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