]> git.ipfire.org Git - thirdparty/newt.git/blame - newt.c
define env NEWT_NOFLOWCTRL to disable flow control
[thirdparty/newt.git] / newt.c
CommitLineData
d5a8d3e8 1#include "config.h"
2
139f06bc 3#include <slang.h>
6fb96a3f 4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
ae1235d0 7#include <sys/signal.h>
6fb96a3f 8#include <sys/time.h>
9#include <sys/types.h>
91be88a7 10#include <termios.h>
6fb96a3f 11#include <unistd.h>
349586bb 12#include <wchar.h>
6fb96a3f 13
d5a8d3e8 14#ifdef HAVE_ALLOCA_H
15#include <alloca.h>
16#endif
17
6fb96a3f 18#include "newt.h"
19#include "newt_pr.h"
20
6fb96a3f 21struct Window {
22 int height, width, top, left;
6a1d8e87 23 SLsmg_Char_Type * buffer;
aa47774f 24 char * title;
6fb96a3f 25};
26
27struct keymap {
28 char * str;
29 int code;
30 char * tc;
31};
32
a1f11019 33static struct Window windowStack[20];
34static struct Window * currentWindow = NULL;
6fb96a3f 35
a1f11019 36static char * helplineStack[20];
37static char ** currentHelpline = NULL;
38
39static int cursorRow, cursorCol;
5e171db1 40static int cursorOn = 1;
9b146a9f 41static int noFlowCtrl = 0;
7ff5fd71 42static int trashScreen = 0;
0593cb33 43extern int needResize;
81361f3e 44
6605d1bf 45static const char * const defaultHelpLine =
7d4604a9 46" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen"
47;
48
57c466b0 49const struct newtColors newtDefaultColorPalette = {
6f481af2 50 "white", "blue", /* root fg, bg */
51 "black", "lightgray", /* border fg, bg */
52 "black", "lightgray", /* window fg, bg */
53 "white", "black", /* shadow fg, bg */
54 "red", "lightgray", /* title fg, bg */
55 "lightgray", "red", /* button fg, bg */
56 "red", "lightgray", /* active button fg, bg */
f838d158 57 "lightgray", "blue", /* checkbox fg, bg */
58 "lightgray", "red", /* active checkbox fg, bg */
59 "lightgray", "blue", /* entry box fg, bg */
6f481af2 60 "blue", "lightgray", /* label fg, bg */
61 "black", "lightgray", /* listbox fg, bg */
f838d158 62 "lightgray", "blue", /* active listbox fg, bg */
6f481af2 63 "black", "lightgray", /* textbox fg, bg */
f838d158 64 "lightgray", "red", /* active textbox fg, bg */
6f481af2 65 "white", "blue", /* help line */
f838d158 66 "lightgray", "blue", /* root text */
6f481af2 67 "blue", /* scale full */
68 "red", /* scale empty */
69 "blue", "lightgray", /* disabled entry fg, bg */
feef2cb5 70 "black", "lightgray", /* compact button fg, bg */
f838d158 71 "lightgray", "red", /* active & sel listbox */
6f481af2 72 "black", "brown" /* selected listbox */
6fb96a3f 73};
74
57c466b0 75static const struct keymap keymap[] = {
feef2cb5 76 { "\033OA", NEWT_KEY_UP, "ku" },
77 { "\020", NEWT_KEY_UP, NULL }, /* emacs ^P */
6f481af2 78 { "\033OB", NEWT_KEY_DOWN, "kd" },
feef2cb5 79 { "\016", NEWT_KEY_DOWN, NULL }, /* emacs ^N */
6f481af2 80 { "\033OC", NEWT_KEY_RIGHT, "kr" },
feef2cb5 81 { "\006", NEWT_KEY_RIGHT, NULL }, /* emacs ^F */
6f481af2 82 { "\033OD", NEWT_KEY_LEFT, "kl" },
feef2cb5 83 { "\002", NEWT_KEY_LEFT, NULL }, /* emacs ^B */
84 { "\033OH", NEWT_KEY_HOME, "kh" },
85 { "\033[1~", NEWT_KEY_HOME, NULL },
86 { "\001", NEWT_KEY_HOME, NULL }, /* emacs ^A */
6f481af2 87 { "\033Ow", NEWT_KEY_END, "kH" },
feef2cb5 88 { "\033[4~", NEWT_KEY_END, "@7" },
89 { "\005", NEWT_KEY_END, NULL }, /* emacs ^E */
6f481af2 90
feef2cb5 91 { "\033[3~", NEWT_KEY_DELETE, "kD" },
92 { "\004", NEWT_KEY_DELETE, NULL }, /* emacs ^D */
93 { "\033[2~", NEWT_KEY_INSERT, "kI" },
6f481af2 94
feef2cb5 95 { "\033\t", NEWT_KEY_UNTAB, "kB" },
3003455e 96 { "\033[Z", NEWT_KEY_UNTAB, NULL },
6f481af2 97
feef2cb5 98 { "\033[5~", NEWT_KEY_PGUP, "kP" },
99 { "\033[6~", NEWT_KEY_PGDN, "kN" },
100 { "\033V", NEWT_KEY_PGUP, NULL },
101 { "\033v", NEWT_KEY_PGUP, NULL },
102 { "\026", NEWT_KEY_PGDN, NULL },
6f481af2 103
104 { "\033[[A", NEWT_KEY_F1, NULL },
105 { "\033[[B", NEWT_KEY_F2, NULL },
106 { "\033[[C", NEWT_KEY_F3, NULL },
107 { "\033[[D", NEWT_KEY_F4, NULL },
108 { "\033[[E", NEWT_KEY_F5, NULL },
109
110 { "\033OP", NEWT_KEY_F1, NULL },
111 { "\033OQ", NEWT_KEY_F2, NULL },
112 { "\033OR", NEWT_KEY_F3, NULL },
113 { "\033OS", NEWT_KEY_F4, NULL },
114
feef2cb5 115 { "\033[11~", NEWT_KEY_F1, "k1" },
116 { "\033[12~", NEWT_KEY_F2, "k2" },
117 { "\033[13~", NEWT_KEY_F3, "k3" },
118 { "\033[14~", NEWT_KEY_F4, "k4" },
119 { "\033[15~", NEWT_KEY_F5, "k5" },
120 { "\033[17~", NEWT_KEY_F6, "k6" },
121 { "\033[18~", NEWT_KEY_F7, "k7" },
122 { "\033[19~", NEWT_KEY_F8, "k8" },
123 { "\033[20~", NEWT_KEY_F9, "k9" },
124 { "\033[21~", NEWT_KEY_F10, "k;" },
125 { "\033[23~", NEWT_KEY_F11, "F1" },
126 { "\033[24~", NEWT_KEY_F12, "F2" },
127 { "\033", NEWT_KEY_ESCAPE, "@2" },
128 { "\033", NEWT_KEY_ESCAPE, "@9" },
129
130 { "\177", NEWT_KEY_BKSPC, NULL },
131 { "\010", NEWT_KEY_BKSPC, NULL },
132
6f481af2 133 { 0 }, /* LEAVE this one */
6fb96a3f 134};
feef2cb5 135static void initKeymap();
136c3059 136static void freeKeymap();
88d3e0a3 137
16e8af2f 138static const char ident[] = // ident friendly
139 "$Version: Newt windowing library v" VERSION " $"
140 "$Copyright: (C) 1996-2003 Red Hat, Inc. Written by Erik Troan $"
141 "$License: Lesser GNU Public License. $";
6fb96a3f 142
b7c1b763 143static newtSuspendCallback suspendCallback = NULL;
06cf519e 144static void * suspendCallbackData = NULL;
b7c1b763 145
06cf519e 146void newtSetSuspendCallback(newtSuspendCallback cb, void * data) {
b7c1b763 147 suspendCallback = cb;
06cf519e 148 suspendCallbackData = data;
b7c1b763 149}
150
ae1235d0 151static void handleSigwinch(int signum) {
152 needResize = 1;
153}
154
155static int getkeyInterruptHook(void) {
156 return -1;
157}
158
feef2cb5 159int _newt_wstrlen(const char *str, int len) {
6f481af2 160 mbstate_t ps;
161 wchar_t tmp;
162 int nchars = 0;
163
164 if (!str) return 0;
165 if (!len) return 0;
166 if (len < 0) len = strlen(str);
167 memset(&ps,0,sizeof(mbstate_t));
168 while (len > 0) {
169 int x,y;
170
171 x = mbrtowc(&tmp,str,len,&ps);
172 if (x >0) {
173 str += x;
174 len -= x;
175 y = wcwidth(tmp);
176 if (y>0)
177 nchars+=y;
178 } else break;
179 }
180 return nchars;
349586bb 181}
182
feef2cb5 183/** Trim a string to fit
184 * @param title - string. NULL will be inserted if necessary
185 * @param chrs - available space. (character cells)
186 */
187void trim_string(char *title, int chrs)
188{
189 char *p = title;
b9b1302c 190 int ln;
feef2cb5 191 int x = 0,y = 0;
192 wchar_t tmp;
193 mbstate_t ps;
194
195 memset(&ps, 0, sizeof(ps));
b9b1302c 196 ln = strlen(title);
feef2cb5 197
198 while (*p) {
199 x = mbrtowc(&tmp, p, ln, &ps);
200 if (x < 0) { // error
201 *p = '\0';
202 return;
203 }
204 y = wcwidth(tmp);
b9b1302c 205 if (y > chrs) {
feef2cb5 206 *p = '\0';
207 return;
208 } else {
209 p += x;
b9b1302c 210 ln -= x;
211 chrs -= y;
feef2cb5 212 }
213 }
214}
215
16e8af2f 216static int getkey() {
217 int c;
218
219 while ((c = SLang_getkey()) == '\xC') { /* if Ctrl-L redraw whole screen */
5baf7e4b 220 SLsmg_touch_lines(0, SLtt_Screen_Rows);
16e8af2f 221 SLsmg_refresh();
222 }
223 return c;
224
225}
226
34e56d12
ML
227static void updateColorset(char *fg, char *bg, char **fg_p, char **bg_p)
228{
229 if (*fg && fg_p)
230 *fg_p = fg;
231 if (*bg && bg_p)
232 *bg_p = bg;
233}
234
235/* parse color specifications (e.g. root=,black:border=red,blue)
236 * and update the palette
237 */
238static void parseColors(char *s, struct newtColors *palette)
239{
240 char *name, *str, *fg, *bg;
34e56d12
ML
241
242 for (str = s; (s = strtok(str, ";:\n\r\t ")); str = NULL) {
243 name = s;
244 if (!(s = strchr(s, '=')) || !*s)
245 continue;
246 *s = '\0';
247 fg = ++s;
248 if (!(s = strchr(s, ',')) || !*s)
249 continue;
250 *s = '\0';
251 bg = ++s;
252
253 if (!strcmp(name, "root"))
254 updateColorset(fg, bg, &palette->rootFg, &palette->rootBg);
255 else if (!strcmp(name, "border"))
256 updateColorset(fg, bg, &palette->borderFg, &palette->borderBg);
257 else if (!strcmp(name, "window"))
258 updateColorset(fg, bg, &palette->windowFg, &palette->windowBg);
259 else if (!strcmp(name, "shadow"))
260 updateColorset(fg, bg, &palette->shadowFg, &palette->shadowBg);
261 else if (!strcmp(name, "title"))
262 updateColorset(fg, bg, &palette->titleFg, &palette->titleBg);
263 else if (!strcmp(name, "button"))
264 updateColorset(fg, bg, &palette->buttonFg, &palette->buttonBg);
265 else if (!strcmp(name, "actbutton"))
266 updateColorset(fg, bg, &palette->actButtonFg, &palette->actButtonBg);
267 else if (!strcmp(name, "checkbox"))
268 updateColorset(fg, bg, &palette->checkboxFg, &palette->checkboxBg);
269 else if (!strcmp(name, "actcheckbox"))
270 updateColorset(fg, bg, &palette->actCheckboxFg, &palette->actCheckboxBg);
271 else if (!strcmp(name, "entry"))
272 updateColorset(fg, bg, &palette->entryFg, &palette->entryBg);
273 else if (!strcmp(name, "label"))
274 updateColorset(fg, bg, &palette->labelFg, &palette->labelBg);
275 else if (!strcmp(name, "listbox"))
276 updateColorset(fg, bg, &palette->listboxFg, &palette->listboxBg);
277 else if (!strcmp(name, "actlistbox"))
278 updateColorset(fg, bg, &palette->actListboxFg, &palette->actListboxBg);
279 else if (!strcmp(name, "textbox"))
280 updateColorset(fg, bg, &palette->textboxFg, &palette->textboxBg);
281 else if (!strcmp(name, "acttextbox"))
282 updateColorset(fg, bg, &palette->actTextboxFg, &palette->actTextboxBg);
283 else if (!strcmp(name, "helpline"))
284 updateColorset(fg, bg, &palette->helpLineFg, &palette->helpLineBg);
285 else if (!strcmp(name, "roottext"))
286 updateColorset(fg, bg, &palette->rootTextFg, &palette->rootTextBg);
287 else if (!strcmp(name, "emptyscale"))
288 updateColorset(fg, bg, NULL, &palette->emptyScale);
289 else if (!strcmp(name, "fullscale"))
290 updateColorset(fg, bg, NULL, &palette->fullScale);
291 else if (!strcmp(name, "disentry"))
292 updateColorset(fg, bg, &palette->disabledEntryFg, &palette->disabledEntryBg);
293 else if (!strcmp(name, "compactbutton"))
294 updateColorset(fg, bg, &palette->compactButtonFg, &palette->compactButtonBg);
295 else if (!strcmp(name, "actsellistbox"))
296 updateColorset(fg, bg, &palette->actSelListboxFg, &palette->actSelListboxBg);
297 else if (!strcmp(name, "sellistbox"))
298 updateColorset(fg, bg, &palette->selListboxFg, &palette->selListboxBg);
299 }
300}
301
302static void initColors(void)
303{
304 char *colors, *colors_file, buf[16384];
305 FILE *f;
306 struct newtColors palette;
307
308 palette = newtDefaultColorPalette;
309
310 colors_file = getenv("NEWT_COLORS_FILE");
311#ifdef NEWT_COLORS_FILE
312 if (colors_file == NULL)
313 colors_file = NEWT_COLORS_FILE;
314#endif
315
316 if ((colors = getenv("NEWT_COLORS"))) {
317 strncpy(buf, colors, sizeof (buf));
318 buf[sizeof (buf) - 1] = '\0';
319 parseColors(buf, &palette);
320 } else if (colors_file && *colors_file && (f = fopen(colors_file, "r"))) {
321 size_t r;
322 if ((r = fread(buf, 1, sizeof (buf) - 1, f)) > 0) {
323 buf[r] = '\0';
324 parseColors(buf, &palette);
325 }
326 fclose(f);
327 }
328
329 newtSetColors(palette);
330}
331
327436b3 332void newtFlushInput(void) {
333 while (SLang_input_pending(0)) {
6f481af2 334 getkey();
327436b3 335 }
336}
337
3eec7ce4 338/**
339 * @brief Refresh the screen
340 */
6fb96a3f 341void newtRefresh(void) {
342 SLsmg_refresh();
343}
344
3cf3e1b9 345void newtSuspend(void) {
5e171db1 346 SLtt_set_cursor_visibility (1);
3cf3e1b9 347 SLsmg_suspend_smg();
348 SLang_reset_tty();
5e171db1 349 SLtt_set_cursor_visibility (cursorOn);
3cf3e1b9 350}
351
3eec7ce4 352/**
353 * @brief Return after suspension.
354 * @return 0 on success.
355 */
b3ddfdd7 356int newtResume(void) {
3cf3e1b9 357 SLsmg_resume_smg ();
358 SLsmg_refresh();
9b146a9f 359 return SLang_init_tty(0, noFlowCtrl, 0);
3cf3e1b9 360}
361
6fb96a3f 362void newtCls(void) {
81361f3e 363 SLsmg_set_color(NEWT_COLORSET_ROOT);
6fb96a3f 364 SLsmg_gotorc(0, 0);
365 SLsmg_erase_eos();
366
367 newtRefresh();
368}
369
3eec7ce4 370/**
371 * @brief Resize the screen
372 * @param redraw - boolean - should we redraw the screen?
373 */
ae1235d0 374void newtResizeScreen(int redraw) {
0593cb33 375 /* we can't redraw from scratch, just redisplay SLang screen */
ae1235d0 376 SLtt_get_screen_size();
0593cb33 377 /* SLsmg_reinit_smg(); */
16e8af2f 378 if (redraw) {
5baf7e4b 379 SLsmg_touch_lines(0, SLtt_Screen_Rows);
16e8af2f 380 newtRefresh();
381 }
ae1235d0 382}
383
3eec7ce4 384/**
385 * @brief Initialize the newt library
386 * @return int - 0 for success, else < 0
387 */
6fb96a3f 388int newtInit(void) {
16e8af2f 389 char * MonoValue, * MonoEnv = "NEWT_MONO";
9b146a9f 390 char * NoFlowCtrlValue, * NoFlowCtrlEnv = "NEWT_NOFLOWCTRL";
16e8af2f 391 const char *lang;
b3ddfdd7 392 int ret;
16e8af2f 393
394 if ((lang = getenv("LC_ALL")) == NULL)
395 if ((lang = getenv("LC_CTYPE")) == NULL)
396 if ((lang = getenv("LANG")) == NULL)
397 lang = "";
3aab8830 398 /* slang doesn't support multibyte encodings except UTF-8,
399 avoid character corruption by redrawing the screen */
16e8af2f 400 if (strstr (lang, ".euc") != NULL)
6f481af2 401 trashScreen = 1;
91be88a7 402
16e8af2f 403 (void) strlen(ident);
88d3e0a3 404
33b96ba3 405 SLutf8_enable(-1);
6fb96a3f 406 SLtt_get_terminfo();
ae1235d0 407 SLtt_get_screen_size();
91be88a7 408
7d4604a9 409 MonoValue = getenv(MonoEnv);
85ee6604 410 if ( MonoValue != NULL )
6f481af2 411 SLtt_Use_Ansi_Colors = 0;
6fb96a3f 412
9b146a9f
RG
413 NoFlowCtrlValue = getenv(NoFlowCtrlEnv);
414 if ( NoFlowCtrlValue != NULL )
415 noFlowCtrl = 1;
416
b3ddfdd7 417 if ((ret = SLsmg_init_smg()) < 0)
6f481af2 418 return ret;
9b146a9f 419 if ((ret = SLang_init_tty(0, noFlowCtrl, 0)) < 0)
6f481af2 420 return ret;
45f6c4fd 421
34e56d12 422 initColors();
23efd09b 423 newtCursorOff();
feef2cb5 424 initKeymap();
6fb96a3f 425
ae1235d0 426 SLsignal_intr(SIGWINCH, handleSigwinch);
427 SLang_getkey_intr_hook = getkeyInterruptHook;
428
6fb96a3f 429 return 0;
430}
431
3eec7ce4 432/**
433 * @brief Closedown the newt library, tidying screen.
434 * @returns int , 0. (no errors reported)
435 */
6fb96a3f 436int newtFinished(void) {
a753da93 437 if (currentWindow) {
438 for (; currentWindow >= windowStack; currentWindow--) {
439 free(currentWindow->buffer);
440 free(currentWindow->title);
441 }
442 currentWindow = NULL;
443 }
444
445 if (currentHelpline) {
446 for (; currentHelpline >= helplineStack; currentHelpline--)
447 free(*currentHelpline);
448 currentHelpline = NULL;
449 }
450
136c3059
ML
451 freeKeymap();
452
6fb96a3f 453 SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
23efd09b 454 newtCursorOn();
6fb96a3f 455 SLsmg_refresh();
456 SLsmg_reset_smg();
457 SLang_reset_tty();
458
459 return 0;
460}
461
3eec7ce4 462/**
463 * @brief Set the colors used.
464 * @param colors - newtColor struct used.
465 */
6fb96a3f 466void newtSetColors(struct newtColors colors) {
16e8af2f 467 if (!SLtt_Use_Ansi_Colors) {
468 int i;
469
470 for (i = 2; i < 25; i++)
471 SLtt_set_mono(i, NULL, 0);
472
473 SLtt_set_mono(NEWT_COLORSET_SELLISTBOX, NULL, SLTT_BOLD_MASK);
474
475 SLtt_set_mono(NEWT_COLORSET_ACTBUTTON, NULL, SLTT_REV_MASK);
476 SLtt_set_mono(NEWT_COLORSET_ACTCHECKBOX, NULL, SLTT_REV_MASK);
477 SLtt_set_mono(NEWT_COLORSET_ACTLISTBOX, NULL, SLTT_REV_MASK);
478 SLtt_set_mono(NEWT_COLORSET_ACTTEXTBOX, NULL, SLTT_REV_MASK);
479
480 SLtt_set_mono(NEWT_COLORSET_ACTSELLISTBOX, NULL, SLTT_REV_MASK | SLTT_BOLD_MASK);
481
482 SLtt_set_mono(NEWT_COLORSET_DISENTRY, NULL, 0); // FIXME
483 SLtt_set_mono(NEWT_COLORSET_FULLSCALE, NULL, SLTT_ULINE_MASK | SLTT_REV_MASK);
484 SLtt_set_mono(NEWT_COLORSET_EMPTYSCALE, NULL, SLTT_ULINE_MASK);
485 return;
486 }
81361f3e 487 SLtt_set_color(NEWT_COLORSET_ROOT, "", colors.rootFg, colors.rootBg);
488 SLtt_set_color(NEWT_COLORSET_BORDER, "", colors.borderFg, colors.borderBg);
489 SLtt_set_color(NEWT_COLORSET_WINDOW, "", colors.windowFg, colors.windowBg);
490 SLtt_set_color(NEWT_COLORSET_SHADOW, "", colors.shadowFg, colors.shadowBg);
491 SLtt_set_color(NEWT_COLORSET_TITLE, "", colors.titleFg, colors.titleBg);
492 SLtt_set_color(NEWT_COLORSET_BUTTON, "", colors.buttonFg, colors.buttonBg);
45f6c4fd 493 SLtt_set_color(NEWT_COLORSET_ACTBUTTON, "", colors.actButtonFg,
6f481af2 494 colors.actButtonBg);
45f6c4fd 495 SLtt_set_color(NEWT_COLORSET_CHECKBOX, "", colors.checkboxFg,
6f481af2 496 colors.checkboxBg);
45f6c4fd 497 SLtt_set_color(NEWT_COLORSET_ACTCHECKBOX, "", colors.actCheckboxFg,
6f481af2 498 colors.actCheckboxBg);
81361f3e 499 SLtt_set_color(NEWT_COLORSET_ENTRY, "", colors.entryFg, colors.entryBg);
500 SLtt_set_color(NEWT_COLORSET_LABEL, "", colors.labelFg, colors.labelBg);
45f6c4fd 501 SLtt_set_color(NEWT_COLORSET_LISTBOX, "", colors.listboxFg,
6f481af2 502 colors.listboxBg);
45f6c4fd 503 SLtt_set_color(NEWT_COLORSET_ACTLISTBOX, "", colors.actListboxFg,
6f481af2 504 colors.actListboxBg);
45f6c4fd 505 SLtt_set_color(NEWT_COLORSET_TEXTBOX, "", colors.textboxFg,
6f481af2 506 colors.textboxBg);
45f6c4fd 507 SLtt_set_color(NEWT_COLORSET_ACTTEXTBOX, "", colors.actTextboxFg,
6f481af2 508 colors.actTextboxBg);
45f6c4fd 509 SLtt_set_color(NEWT_COLORSET_HELPLINE, "", colors.helpLineFg,
6f481af2 510 colors.helpLineBg);
45f6c4fd 511 SLtt_set_color(NEWT_COLORSET_ROOTTEXT, "", colors.rootTextFg,
6f481af2 512 colors.rootTextBg);
3cf3e1b9 513
5505c898 514 SLtt_set_color(NEWT_COLORSET_EMPTYSCALE, "", "white",
6f481af2 515 colors.emptyScale);
5505c898 516 SLtt_set_color(NEWT_COLORSET_FULLSCALE, "", "white",
6f481af2 517 colors.fullScale);
a1f11019 518 SLtt_set_color(NEWT_COLORSET_DISENTRY, "", colors.disabledEntryFg,
6f481af2 519 colors.disabledEntryBg);
39dd7d98 520
521 SLtt_set_color(NEWT_COLORSET_COMPACTBUTTON, "", colors.compactButtonFg,
6f481af2 522 colors.compactButtonBg);
45f6c4fd 523
46263d9e 524 SLtt_set_color(NEWT_COLORSET_ACTSELLISTBOX, "", colors.actSelListboxFg,
6f481af2 525 colors.actSelListboxBg);
46263d9e 526 SLtt_set_color(NEWT_COLORSET_SELLISTBOX, "", colors.selListboxFg,
6f481af2 527 colors.selListboxBg);
6fb96a3f 528}
529
70728aab 530void newtSetColor(int colorset, char *fg, char *bg) {
7b6003b0
ML
531 if (colorset < NEWT_COLORSET_ROOT ||
532 (colorset > NEWT_COLORSET_SELLISTBOX && colorset < NEWT_COLORSET_CUSTOM(0)) ||
70728aab 533 !SLtt_Use_Ansi_Colors)
534 return;
535
536 SLtt_set_color(colorset, "", fg, bg);
537}
538
feef2cb5 539/* Keymap handling - rewritten by Henning Makholm <henning@makholm.net>,
540 * November 2003.
541 */
542
543struct kmap_trie_entry {
136c3059 544 char alloced; /* alloced/not first element in array */
feef2cb5 545 char c ; /* character got from terminal */
546 int code; /* newt key, or 0 if c does not make a complete sequence */
547 struct kmap_trie_entry *contseq; /* sub-trie for character following c */
548 struct kmap_trie_entry *next; /* try this if char received != c */
549};
136c3059
ML
550
551static struct kmap_trie_entry *kmap_trie_root = NULL;
feef2cb5 552static int keyreader_buf_len = 10 ;
553static unsigned char default_keyreader_buf[10];
554static unsigned char *keyreader_buf = default_keyreader_buf;
555
556#if 0 /* for testing of the keymap manipulation code */
557static void dumpkeys_recursive(struct kmap_trie_entry *curr, int i, FILE *f) {
558 int j, ps ;
559 char seen[256]={0};
560 if( curr && i >= keyreader_buf_len ) {
561 fprintf(f,"ARGH! Too long sequence!\n") ;
562 return ;
563 }
564 for(;curr;curr=curr->next) {
565 keyreader_buf[i] = curr->c ;
566 ps = seen[(unsigned char)curr->c]++ ;
567 if( ps || curr->code || (!curr->code && !curr->contseq) ) {
568 for(j=0;j<=i;j++) {
569 if( keyreader_buf[j] > 32 && keyreader_buf[j]<127 &&
570 keyreader_buf[j] != '^' && keyreader_buf[j] != '\\' )
571 fprintf(f,"%c",keyreader_buf[j]);
572 else if( keyreader_buf[j] > 0 && keyreader_buf[j]<=32 )
573 fprintf(f,"^%c",keyreader_buf[j] + 0x40);
574 else
575 fprintf(f,"\\%03o",
576 (unsigned)(unsigned char)keyreader_buf[j]);
577 }
578 if( curr->code )
579 fprintf(f,": 0x%X\n",curr->code);
580 else
581 fprintf(f,": (just keymap)\n");
582 }
583 dumpkeys_recursive(curr->contseq,i+1,f);
584 }
585}
586static void dump_keymap(void) {
587 FILE *f = fopen("newt.keydump","wt");
588 if (f) {
136c3059 589 dumpkeys_recursive(kmap_trie_root, 0, f);
feef2cb5 590 fclose(f);
591 }
592}
593#endif
594
595/* newtBindKey may overwrite a binding that is there already */
596static void newtBindKey(char *keyseq, int meaning) {
136c3059 597 struct kmap_trie_entry *root = kmap_trie_root ;
feef2cb5 598 struct kmap_trie_entry **curptr = &root ;
599
600 /* Try to make sure the common matching buffer is long enough. */
601 if( strlen(keyseq) > keyreader_buf_len ) {
602 int i = strlen(keyseq)+10;
603 unsigned char *newbuf = malloc(i);
604 if (newbuf) {
605 if (keyreader_buf != default_keyreader_buf)
606 free(keyreader_buf);
607 keyreader_buf = newbuf;
608 keyreader_buf_len = i;
609 }
610 }
611
612 if (*keyseq == 0) return; /* binding the empty sequence is meaningless */
613
614 while(1) {
615 while ((*curptr) && (*curptr)->c != *keyseq)
616 curptr = &(*curptr)->next;
617 if ((*curptr)==0) {
618 struct kmap_trie_entry* fresh
619 = calloc(strlen(keyseq),sizeof(struct kmap_trie_entry));
620 if (fresh == 0) return; /* despair! */
136c3059 621 fresh->alloced = 1;
feef2cb5 622 *curptr = fresh;
623 while (keyseq[1]) {
624 fresh->contseq = fresh+1;
625 (fresh++)->c = *(keyseq++);
626 }
627 fresh->c = *keyseq;
628 fresh->code = meaning;
629 return;
630 }
631 if (keyseq[1]==0) {
632 (*curptr)->code = meaning;
633 return;
634 } else {
635 curptr = &(*curptr)->contseq;
636 keyseq++;
637 }
638 }
639}
640
641/* This function recursively inserts all entries in the "to" trie into
642 corresponding positions in the "from" trie, except positions that
643 are already defined in the "from" trie. */
644static void kmap_trie_fallback(struct kmap_trie_entry *to,
645 struct kmap_trie_entry **from) {
646 if (*from == NULL)
647 *from = to ;
648 if (*from == to)
649 return ;
650 for (;to!=NULL;to=to->next) {
651 struct kmap_trie_entry **fromcopy = from ;
652 while ((*fromcopy) && (*fromcopy)->c != to->c)
653 fromcopy = &(*fromcopy)->next ;
654 if (*fromcopy) {
655 if ((*fromcopy)->code == 0)
656 (*fromcopy)->code = to->code;
657 kmap_trie_fallback(to->contseq, &(*fromcopy)->contseq);
658 } else {
659 *fromcopy = malloc(sizeof(struct kmap_trie_entry));
660 if (*fromcopy) {
661 **fromcopy = *to ;
136c3059 662 (*fromcopy)->alloced = 1;
feef2cb5 663 (*fromcopy)->next = 0 ;
664 }
665 }
666 }
667}
668
6fb96a3f 669int newtGetKey(void) {
b8b8a86f 670 int key, lastcode, errors = 0;
feef2cb5 671 unsigned char *chptr = keyreader_buf, *lastmatch;
136c3059 672 struct kmap_trie_entry *curr = kmap_trie_root;
6fb96a3f 673
b7c1b763 674 do {
6f481af2 675 key = getkey();
676 if (key == SLANG_GETKEY_ERROR) {
6f481af2 677 if (needResize) {
16e8af2f 678 needResize = 0;
6f481af2 679 return NEWT_KEY_RESIZE;
16e8af2f 680 }
ae1235d0 681
b8b8a86f
ML
682 /* Ignore other signals, but assume that stdin disappeared (the
683 * parent terminal was proably closed) if the error persists.
684 */
685 if (errors++ > 10)
686 return NEWT_KEY_ERROR;
687
6f481af2 688 continue;
689 }
ae1235d0 690
6f481af2 691 if (key == NEWT_KEY_SUSPEND && suspendCallback)
692 suspendCallback(suspendCallbackData);
b8b8a86f 693 } while (key == NEWT_KEY_SUSPEND || key == SLANG_GETKEY_ERROR);
6fb96a3f 694
feef2cb5 695 /* Read more characters, matching against the trie as we go */
696 lastcode = *chptr = key;
697 lastmatch = chptr ;
698 while(1) {
699 while (curr->c != key) {
700 curr = curr->next ;
701 if (curr==NULL) goto break2levels;
702 }
703 if (curr->code) {
704 lastcode = curr->code;
705 lastmatch = chptr;
706 }
707 curr = curr->contseq;
708 if (curr==NULL) break;
709
710 if (SLang_input_pending(5) <= 0)
711 break;
712
713 if (chptr==keyreader_buf+keyreader_buf_len-1) break;
714 *++chptr = key = getkey();
6fb96a3f 715 }
feef2cb5 716 break2levels:
717
718 /* The last time the trie matched was at position lastmatch. Back
719 * up if we have read too many characters. */
720 while (chptr > lastmatch)
721 SLang_ungetkey(*chptr--);
722
723 return lastcode;
6fb96a3f 724}
725
3eec7ce4 726/**
727 * @brief Wait for a keystroke
728 */
6fb96a3f 729void newtWaitForKey(void) {
730 newtRefresh();
731
16e8af2f 732 getkey();
6fb96a3f 733 newtClearKeyBuffer();
734}
735
3eec7ce4 736/**
737 * @brief Clear the keybuffer
738 */
6fb96a3f 739void newtClearKeyBuffer(void) {
740 while (SLang_input_pending(1)) {
6f481af2 741 getkey();
6fb96a3f 742 }
743}
744
3eec7ce4 745/**
746 * Open a new window.
edad3d82 747 * @param left. int Size; _not_ including border
748 * @param top: int size, _not_ including border
3eec7ce4 749 * @param width unsigned int
750 * @param height unsigned int
751 * @param title - title string
a753da93 752 * @return zero on success
3eec7ce4 753 */
edad3d82 754int newtOpenWindow(int left, int top,
feef2cb5 755 unsigned int width, unsigned int height,
6f481af2 756 const char * title) {
46263d9e 757 int j, row, col;
d4663248 758 int n;
44de2c93 759 int i;
6fb96a3f 760
327436b3 761 newtFlushInput();
762
a753da93 763 if (currentWindow && currentWindow - windowStack + 1
764 >= sizeof (windowStack) / sizeof (struct Window))
765 return 1;
766
6fb96a3f 767 if (!currentWindow) {
6f481af2 768 currentWindow = windowStack;
6fb96a3f 769 } else {
6f481af2 770 currentWindow++;
6fb96a3f 771 }
772
773 currentWindow->left = left;
774 currentWindow->top = top;
775 currentWindow->width = width;
776 currentWindow->height = height;
649a0152 777 currentWindow->title = title ? strdup(title) : NULL;
6fb96a3f 778
b9b1302c 779 currentWindow->buffer = malloc(sizeof(SLsmg_Char_Type) * (width + 5) * (height + 3));
6fb96a3f 780
781 row = top - 1;
b9b1302c 782 col = left - 2;
22cc0d5e 783 /* clip to the current screen bounds - msw */
784 if (row < 0)
6f481af2 785 row = 0;
22cc0d5e 786 if (col < 0)
6f481af2 787 col = 0;
22cc0d5e 788 if (left + width > SLtt_Screen_Cols)
6f481af2 789 width = SLtt_Screen_Cols - left;
22cc0d5e 790 if (top + height > SLtt_Screen_Rows)
6f481af2 791 height = SLtt_Screen_Rows - top;
d4663248 792 n = 0;
6fb96a3f 793 for (j = 0; j < height + 3; j++, row++) {
6f481af2 794 SLsmg_gotorc(row, col);
795 SLsmg_read_raw(currentWindow->buffer + n,
b9b1302c 796 currentWindow->width + 5);
797 n += currentWindow->width + 5;
6fb96a3f 798 }
799
7ff5fd71 800 newtTrashScreen();
801
81361f3e 802 SLsmg_set_color(NEWT_COLORSET_BORDER);
feef2cb5 803 SLsmg_set_char_set(1);
6fb96a3f 804 SLsmg_draw_box(top - 1, left - 1, height + 2, width + 2);
feef2cb5 805 SLsmg_set_char_set(0);
6fb96a3f 806
aa47774f 807 if (currentWindow->title) {
feef2cb5 808 trim_string (currentWindow->title, width-4);
6f481af2 809 i = wstrlen(currentWindow->title,-1) + 4;
810 i = ((width - i) / 2) + left;
811 SLsmg_gotorc(top - 1, i);
812 SLsmg_set_char_set(1);
813 SLsmg_write_char(SLSMG_RTEE_CHAR);
814 SLsmg_set_char_set(0);
815 SLsmg_write_char(' ');
816 SLsmg_set_color(NEWT_COLORSET_TITLE);
10de8f4a 817 SLsmg_write_string((char *)currentWindow->title);
6f481af2 818 SLsmg_set_color(NEWT_COLORSET_BORDER);
819 SLsmg_write_char(' ');
820 SLsmg_set_char_set(1);
821 SLsmg_write_char(SLSMG_LTEE_CHAR);
822 SLsmg_set_char_set(0);
6fb96a3f 823 }
824
81361f3e 825 SLsmg_set_color(NEWT_COLORSET_WINDOW);
6fb96a3f 826 SLsmg_fill_region(top, left, height, width, ' ');
827
81361f3e 828 SLsmg_set_color(NEWT_COLORSET_SHADOW);
6fb96a3f 829 SLsmg_fill_region(top + height + 1, left, 1, width + 2, ' ');
830 SLsmg_fill_region(top, left + width + 1, height + 1, 1, ' ');
831
832 for (i = top; i < (top + height + 1); i++) {
6f481af2 833 SLsmg_gotorc(i, left + width + 1);
834 SLsmg_write_string(" ");
6fb96a3f 835 }
44de2c93 836
837 return 0;
6fb96a3f 838}
839
3eec7ce4 840/**
841 * @brief Draw a centered window.
842 * @param width - width in char cells
843 * @param height - no. of char cells.
844 * @param title - fixed title
a753da93 845 * @returns zero on success
3eec7ce4 846 */
feef2cb5 847int newtCenteredWindow(unsigned int width,unsigned int height,
848 const char * title) {
edad3d82 849 int top, left;
f16e164f 850
edad3d82 851 top = (int)(SLtt_Screen_Rows - height) / 2;
f16e164f 852
45f6c4fd 853 /* I don't know why, but this seems to look better */
f16e164f 854 if ((SLtt_Screen_Rows % 2) && (top % 2)) top--;
855
edad3d82 856 left = (int)(SLtt_Screen_Cols - width) / 2;
f16e164f 857
a753da93 858 return newtOpenWindow(left, top, width, height, title);
f16e164f 859}
860
3eec7ce4 861/**
862 * @brief Remove the top window
863 */
6fb96a3f 864void newtPopWindow(void) {
e5df813b 865 newtPopWindowNoRefresh();
866 newtRefresh();
867}
868
869void newtPopWindowNoRefresh(void) {
6fb96a3f 870 int j, row, col;
45f6c4fd 871 int n = 0;
6fb96a3f 872
a753da93 873 if (currentWindow == NULL)
874 return;
875
6fb96a3f 876 row = col = 0;
877
878 row = currentWindow->top - 1;
b9b1302c 879 col = currentWindow->left - 2;
22cc0d5e 880 if (row < 0)
6f481af2 881 row = 0;
22cc0d5e 882 if (col < 0)
6f481af2 883 col = 0;
6fb96a3f 884 for (j = 0; j < currentWindow->height + 3; j++, row++) {
6f481af2 885 SLsmg_gotorc(row, col);
886 SLsmg_write_raw(currentWindow->buffer + n,
b9b1302c 887 currentWindow->width + 5);
888 n += currentWindow->width + 5;
6fb96a3f 889 }
890
891 free(currentWindow->buffer);
aa47774f 892 free(currentWindow->title);
6fb96a3f 893
45f6c4fd 894 if (currentWindow == windowStack)
6f481af2 895 currentWindow = NULL;
6fb96a3f 896 else
6f481af2 897 currentWindow--;
6fb96a3f 898
899 SLsmg_set_char_set(0);
900
7ff5fd71 901 newtTrashScreen();
6fb96a3f 902}
903
45f6c4fd 904void newtGetWindowPos(int * x, int * y) {
905 if (currentWindow) {
6f481af2 906 *x = currentWindow->left;
907 *y = currentWindow->top;
45f6c4fd 908 } else
6f481af2 909 *x = *y = 0;
45f6c4fd 910}
911
a1f11019 912void newtGetrc(int * row, int * col) {
28de1915 913 *row = cursorRow;
914 *col = cursorCol;
915
916 if (currentWindow) {
917 *row -= currentWindow->top;
918 *col -= currentWindow->left;
919 }
a1f11019 920}
921
922void newtGotorc(int newRow, int newCol) {
923 if (currentWindow) {
6f481af2 924 newRow += currentWindow->top;
925 newCol += currentWindow->left;
a1f11019 926 }
927
928 cursorRow = newRow;
929 cursorCol = newCol;
930 SLsmg_gotorc(cursorRow, cursorCol);
6fb96a3f 931}
932
933void newtDrawBox(int left, int top, int width, int height, int shadow) {
934 if (currentWindow) {
6f481af2 935 top += currentWindow->top;
936 left += currentWindow->left;
6fb96a3f 937 }
938
939 SLsmg_draw_box(top, left, height, width);
940
941 if (shadow) {
6f481af2 942 SLsmg_set_color(NEWT_COLORSET_SHADOW);
943 SLsmg_fill_region(top + height, left + 1, 1, width - 1, ' ');
944 SLsmg_fill_region(top + 1, left + width, height, 1, ' ');
6fb96a3f 945 }
946}
947
948void newtClearBox(int left, int top, int width, int height) {
949 if (currentWindow) {
6f481af2 950 top += currentWindow->top;
951 left += currentWindow->left;
6fb96a3f 952 }
953
954 SLsmg_fill_region(top, left, height, width, ' ');
955}
956
6fb96a3f 957static void initKeymap(void) {
feef2cb5 958 const struct keymap * curr;
136c3059
ML
959 struct kmap_trie_entry *kmap_trie_escBrack, *kmap_trie_escO;
960
961 /* Here are some entries that will help in handling esc O foo and
962 esc [ foo as variants of each other. */
963 kmap_trie_root = calloc(3, sizeof (struct kmap_trie_entry));
964 kmap_trie_escBrack = kmap_trie_root + 1;
965 kmap_trie_escO = kmap_trie_root + 2;
966
967 kmap_trie_root->alloced = 1;
968 kmap_trie_root->c = '\033';
969 kmap_trie_root->contseq = kmap_trie_escBrack;
970
971 kmap_trie_escBrack->c = '[';
972 kmap_trie_escBrack->next = kmap_trie_escO;
973
974 kmap_trie_escO->c = 'O';
6fb96a3f 975
feef2cb5 976 /* First bind built-in default bindings. They may be shadowed by
977 the termcap entries that get bound later. */
6fb96a3f 978 for (curr = keymap; curr->code; curr++) {
feef2cb5 979 if (curr->str)
980 newtBindKey(curr->str,curr->code);
6fb96a3f 981 }
982
feef2cb5 983 /* Then bind strings from termcap entries */
984 for (curr = keymap; curr->code; curr++) {
985 if (curr->tc) {
986 char *pc = SLtt_tgetstr(curr->tc);
987 if (pc) {
988 newtBindKey(pc,curr->code);
989 }
990 }
991 }
6fb96a3f 992
feef2cb5 993 /* Finally, invent lowest-priority keybindings that correspond to
994 searching for esc-O-foo if esc-[-foo was not found and vice
995 versa. That is needed because of strong confusion among
996 different emulators of VTxxx terminals; some terminfo/termcap
997 descriptions are apparently written by people who were not
998 aware of the differences between "applicataion" and "terminal"
999 keypad modes. Or perhaps they were, but tried to make their
1000 description work with a program that puts the keyboard in the
1001 wrong emulation mode. In short, one needs this: */
136c3059
ML
1002 kmap_trie_fallback(kmap_trie_escO->contseq, &kmap_trie_escBrack->contseq);
1003 kmap_trie_fallback(kmap_trie_escBrack->contseq, &kmap_trie_escO->contseq);
1004}
1005
1006static void free_keys(struct kmap_trie_entry *kmap, struct kmap_trie_entry *parent, int prepare) {
1007 if (kmap == NULL)
1008 return;
1009
1010 free_keys(kmap->contseq, kmap, prepare);
1011 free_keys(kmap->next, kmap, prepare);
1012
1013 if (!kmap->alloced && kmap - parent == 1)
1014 return;
1015
1016 /* find first element in array */
1017 while (!kmap->alloced)
1018 kmap--;
1019
1020 kmap->alloced += prepare ? 1 : -1;
1021 if (!prepare && kmap->alloced == 1)
1022 free(kmap);
1023}
1024
1025static void freeKeymap() {
1026 free_keys(kmap_trie_root, NULL, 1);
1027 free_keys(kmap_trie_root, NULL, 0);
1028 kmap_trie_root = NULL;
6fb96a3f 1029}
6fb96a3f 1030
3eec7ce4 1031/**
1032 * @brief Delay for a specified number of usecs
1033 * @param int - number of usecs to wait for.
1034 */
feef2cb5 1035void newtDelay(unsigned int usecs) {
236ed30e 1036 usleep(usecs);
6fb96a3f 1037}
8735cc88 1038
45c366b1 1039struct eventResult newtDefaultEventHandler(newtComponent c,
6f481af2 1040 struct event ev) {
8735cc88 1041 struct eventResult er;
1042
1043 er.result = ER_IGNORED;
1044 return er;
1045}
81361f3e 1046
7d4604a9 1047void newtRedrawHelpLine(void) {
81361f3e 1048 char * buf;
1049
1050 SLsmg_set_color(NEWT_COLORSET_HELPLINE);
45f6c4fd 1051
22cc0d5e 1052 if (currentHelpline) {
6f481af2 1053 /* buffer size needs to be wide enough to hold all the multibyte
1054 currentHelpline + all the single byte ' ' to fill the line */
1055 int wlen = wstrlen(*currentHelpline, -1);
1056 int len;
1057
1058 if (wlen > SLtt_Screen_Cols)
1059 wlen = SLtt_Screen_Cols;
1060 len = strlen(*currentHelpline) + (SLtt_Screen_Cols - wlen);
1061 buf = alloca(len + 1);
1062 memset(buf, ' ', len);
1063 memcpy(buf, *currentHelpline, strlen(*currentHelpline));
1064 buf[len] = '\0';
ce11acc8 1065 } else {
6f481af2 1066 buf = alloca(SLtt_Screen_Cols + 1);
1067 memset(buf, ' ', SLtt_Screen_Cols);
1068 buf[SLtt_Screen_Cols] = '\0';
22cc0d5e 1069 }
81361f3e 1070 SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
10de8f4a 1071 SLsmg_write_string(buf);
b6c968d2 1072 SLsmg_gotorc(cursorRow, cursorCol);
81361f3e 1073}
1074
d4109c37 1075void newtPushHelpLine(const char * text) {
a753da93 1076 if (currentHelpline && currentHelpline - helplineStack + 1
1077 >= sizeof (helplineStack) / sizeof (char *))
1078 return;
1079
7d4604a9 1080 if (!text)
6f481af2 1081 text = defaultHelpLine;
45f6c4fd 1082
81361f3e 1083 if (currentHelpline)
6f481af2 1084 (*(++currentHelpline)) = strdup(text);
81361f3e 1085 else {
6f481af2 1086 currentHelpline = helplineStack;
1087 *currentHelpline = strdup(text);
81361f3e 1088 }
1089
7d4604a9 1090 newtRedrawHelpLine();
81361f3e 1091}
1092
1093void newtPopHelpLine(void) {
1094 if (!currentHelpline) return;
1095
1096 free(*currentHelpline);
1097 if (currentHelpline == helplineStack)
6f481af2 1098 currentHelpline = NULL;
81361f3e 1099 else
6f481af2 1100 currentHelpline--;
81361f3e 1101
7d4604a9 1102 newtRedrawHelpLine();
81361f3e 1103}
1104
39280c3a 1105void newtDrawRootText(int col, int row, const char * text) {
81361f3e 1106 SLsmg_set_color(NEWT_COLORSET_ROOTTEXT);
7d4604a9 1107
1108 if (col < 0) {
6f481af2 1109 col = SLtt_Screen_Cols + col;
7d4604a9 1110 }
1111
1112 if (row < 0) {
6f481af2 1113 row = SLtt_Screen_Rows + row;
7d4604a9 1114 }
45f6c4fd 1115
81361f3e 1116 SLsmg_gotorc(row, col);
10de8f4a 1117 SLsmg_write_string((char *)text);
81361f3e 1118}
a1f11019 1119
1120int newtSetFlags(int oldFlags, int newFlags, enum newtFlagsSense sense) {
1121 switch (sense) {
1122 case NEWT_FLAGS_SET:
6f481af2 1123 return oldFlags | newFlags;
a1f11019 1124
1125 case NEWT_FLAGS_RESET:
6f481af2 1126 return oldFlags & (~newFlags);
a1f11019 1127
69bf2308 1128 case NEWT_FLAGS_TOGGLE:
6f481af2 1129 return oldFlags ^ newFlags;
69bf2308 1130
a1f11019 1131 default:
6f481af2 1132 return oldFlags;
a1f11019 1133 }
1134}
69bf2308 1135
1136void newtBell(void)
1137{
721584c3 1138 SLtt_beep();
1139}
1140
1141void newtGetScreenSize(int * cols, int * rows) {
1142 if (rows) *rows = SLtt_Screen_Rows;
1143 if (cols) *cols = SLtt_Screen_Cols;
69bf2308 1144}
8f52cd47 1145
1146void newtDefaultPlaceHandler(newtComponent c, int newLeft, int newTop) {
1147 c->left = newLeft;
1148 c->top = newTop;
1149}
1150
1151void newtDefaultMappedHandler(newtComponent c, int isMapped) {
1152 c->isMapped = isMapped;
1153}
23efd09b 1154
1155void newtCursorOff(void) {
5e171db1 1156 cursorOn = 0;
1157 SLtt_set_cursor_visibility (cursorOn);
23efd09b 1158}
1159
1160void newtCursorOn(void) {
5e171db1 1161 cursorOn = 1;
1162 SLtt_set_cursor_visibility (cursorOn);
23efd09b 1163}
7ff5fd71 1164
1165void newtTrashScreen(void) {
1166 if (trashScreen)
5baf7e4b 1167 SLsmg_touch_lines(0, SLtt_Screen_Rows);
7ff5fd71 1168}
1169
c397bfc8
DW
1170void newtComponentGetPosition(newtComponent co, int * left, int * top) {
1171 if (left) *left = co->left;
1172 if (top) *top = co->top;
1173}
1174
1175void newtComponentGetSize(newtComponent co, int * width, int * height) {
1176 if (width) *width = co->width;
1177 if (height) *height = co->height;
1178}