7 #include <sys/signal.h>
22 int height
, width
, top
, left
;
23 SLsmg_Char_Type
* buffer
;
33 static struct Window windowStack
[20];
34 static struct Window
* currentWindow
= NULL
;
36 static char * helplineStack
[20];
37 static char ** currentHelpline
= NULL
;
39 static int cursorRow
, cursorCol
;
40 static int needResize
= 0;
41 static int cursorOn
= 1;
42 static int trashScreen
= 0;
44 static const char * defaultHelpLine
=
45 " <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen"
48 const struct newtColors newtDefaultColorPalette
= {
49 "white", "blue", /* root fg, bg */
50 "black", "lightgray", /* border fg, bg */
51 "black", "lightgray", /* window fg, bg */
52 "white", "black", /* shadow fg, bg */
53 "red", "lightgray", /* title fg, bg */
54 "lightgray", "red", /* button fg, bg */
55 "red", "lightgray", /* active button fg, bg */
56 "yellow", "blue", /* checkbox fg, bg */
57 "blue", "brown", /* active checkbox fg, bg */
58 "yellow", "blue", /* entry box fg, bg */
59 "blue", "lightgray", /* label fg, bg */
60 "black", "lightgray", /* listbox fg, bg */
61 "yellow", "blue", /* active listbox fg, bg */
62 "black", "lightgray", /* textbox fg, bg */
63 "lightgray", "black", /* active textbox fg, bg */
64 "white", "blue", /* help line */
65 "yellow", "blue", /* root text */
66 "blue", /* scale full */
67 "red", /* scale empty */
68 "blue", "lightgray", /* disabled entry fg, bg */
69 "black", "lightgray", /* compact button fg, bg */
70 "yellow", "red", /* active & sel listbox */
71 "black", "brown" /* selected listbox */
74 static const struct keymap keymap
[] = {
75 { "\033OA", NEWT_KEY_UP
, "ku" },
76 { "\020", NEWT_KEY_UP
, NULL
}, /* emacs ^P */
77 { "\033OB", NEWT_KEY_DOWN
, "kd" },
78 { "\016", NEWT_KEY_DOWN
, NULL
}, /* emacs ^N */
79 { "\033OC", NEWT_KEY_RIGHT
, "kr" },
80 { "\006", NEWT_KEY_RIGHT
, NULL
}, /* emacs ^F */
81 { "\033OD", NEWT_KEY_LEFT
, "kl" },
82 { "\002", NEWT_KEY_LEFT
, NULL
}, /* emacs ^B */
83 { "\033OH", NEWT_KEY_HOME
, "kh" },
84 { "\033[1~", NEWT_KEY_HOME
, NULL
},
85 { "\001", NEWT_KEY_HOME
, NULL
}, /* emacs ^A */
86 { "\033Ow", NEWT_KEY_END
, "kH" },
87 { "\033[4~", NEWT_KEY_END
, "@7" },
88 { "\005", NEWT_KEY_END
, NULL
}, /* emacs ^E */
90 { "\033[3~", NEWT_KEY_DELETE
, "kD" },
91 { "\004", NEWT_KEY_DELETE
, NULL
}, /* emacs ^D */
92 { "\033[2~", NEWT_KEY_INSERT
, "kI" },
94 { "\033\t", NEWT_KEY_UNTAB
, "kB" },
96 { "\033[5~", NEWT_KEY_PGUP
, "kP" },
97 { "\033[6~", NEWT_KEY_PGDN
, "kN" },
98 { "\033V", NEWT_KEY_PGUP
, NULL
},
99 { "\033v", NEWT_KEY_PGUP
, NULL
},
100 { "\026", NEWT_KEY_PGDN
, NULL
},
102 { "\033[[A", NEWT_KEY_F1
, NULL
},
103 { "\033[[B", NEWT_KEY_F2
, NULL
},
104 { "\033[[C", NEWT_KEY_F3
, NULL
},
105 { "\033[[D", NEWT_KEY_F4
, NULL
},
106 { "\033[[E", NEWT_KEY_F5
, NULL
},
108 { "\033OP", NEWT_KEY_F1
, NULL
},
109 { "\033OQ", NEWT_KEY_F2
, NULL
},
110 { "\033OR", NEWT_KEY_F3
, NULL
},
111 { "\033OS", NEWT_KEY_F4
, NULL
},
113 { "\033[11~", NEWT_KEY_F1
, "k1" },
114 { "\033[12~", NEWT_KEY_F2
, "k2" },
115 { "\033[13~", NEWT_KEY_F3
, "k3" },
116 { "\033[14~", NEWT_KEY_F4
, "k4" },
117 { "\033[15~", NEWT_KEY_F5
, "k5" },
118 { "\033[17~", NEWT_KEY_F6
, "k6" },
119 { "\033[18~", NEWT_KEY_F7
, "k7" },
120 { "\033[19~", NEWT_KEY_F8
, "k8" },
121 { "\033[20~", NEWT_KEY_F9
, "k9" },
122 { "\033[21~", NEWT_KEY_F10
, "k;" },
123 { "\033[23~", NEWT_KEY_F11
, "F1" },
124 { "\033[24~", NEWT_KEY_F12
, "F2" },
125 { "\033", NEWT_KEY_ESCAPE
, "@2" },
126 { "\033", NEWT_KEY_ESCAPE
, "@9" },
128 { "\177", NEWT_KEY_BKSPC
, NULL
},
129 { "\010", NEWT_KEY_BKSPC
, NULL
},
131 { 0 }, /* LEAVE this one */
133 static void initKeymap();
135 static const char ident
[] = // ident friendly
136 "$Version: Newt windowing library v" VERSION
" $"
137 "$Copyright: (C) 1996-2003 Red Hat, Inc. Written by Erik Troan $"
138 "$License: Lesser GNU Public License. $";
140 static newtSuspendCallback suspendCallback
= NULL
;
141 static void * suspendCallbackData
= NULL
;
143 void newtSetSuspendCallback(newtSuspendCallback cb
, void * data
) {
144 suspendCallback
= cb
;
145 suspendCallbackData
= data
;
148 static void handleSigwinch(int signum
) {
152 static int getkeyInterruptHook(void) {
156 int _newt_wstrlen(const char *str
, int len
) {
163 if (len
< 0) len
= strlen(str
);
164 memset(&ps
,0,sizeof(mbstate_t));
168 x
= mbrtowc(&tmp
,str
,len
,&ps
);
180 /** Trim a string to fit
181 * @param title - string. NULL will be inserted if necessary
182 * @param chrs - available space. (character cells)
184 void trim_string(char *title
, int chrs
)
192 memset(&ps
, 0, sizeof(ps
));
195 x
= mbrtowc(&tmp
, p
, ln
, &ps
);
196 if (x
< 0) { // error
211 static int getkey() {
214 while ((c
= SLang_getkey()) == '\xC') { /* if Ctrl-L redraw whole screen */
215 SLsmg_touch_lines (0, SLtt_Screen_Rows
- 1);
222 void newtFlushInput(void) {
223 while (SLang_input_pending(0)) {
229 * @brief Refresh the screen
231 void newtRefresh(void) {
235 void newtSuspend(void) {
236 SLtt_set_cursor_visibility (1);
239 SLtt_set_cursor_visibility (cursorOn
);
243 * @brief Return after suspension.
244 * @return 0 on success.
246 int newtResume(void) {
249 return SLang_init_tty(0, 0, 0);
253 SLsmg_set_color(NEWT_COLORSET_ROOT
);
261 * @brief Resize the screen
262 * @param redraw - boolean - should we redraw the screen?
264 void newtResizeScreen(int redraw
) {
265 SLtt_get_screen_size();
268 SLsmg_touch_lines (0, SLtt_Screen_Rows
- 1);
274 * @brief Initialize the newt library
275 * @return int - 0 for success, else < 0
278 char * MonoValue
, * MonoEnv
= "NEWT_MONO";
282 if ((lang
= getenv("LC_ALL")) == NULL
)
283 if ((lang
= getenv("LC_CTYPE")) == NULL
)
284 if ((lang
= getenv("LANG")) == NULL
)
286 if (strstr (lang
, ".euc") != NULL
)
289 (void) strlen(ident
);
292 SLtt_get_screen_size();
294 MonoValue
= getenv(MonoEnv
);
295 if ( MonoValue
== NULL
) {
296 SLtt_Use_Ansi_Colors
= 1;
298 SLtt_Use_Ansi_Colors
= 0;
301 if ((ret
= SLsmg_init_smg()) < 0)
303 if ((ret
= SLang_init_tty(0, 0, 0)) < 0)
306 newtSetColors(newtDefaultColorPalette
);
310 /*memset(&sa, 0, sizeof(sa));
311 sa.sa_handler = handleSigwinch;
312 sigaction(SIGWINCH, &sa, NULL);*/
314 SLsignal_intr(SIGWINCH
, handleSigwinch
);
315 SLang_getkey_intr_hook
= getkeyInterruptHook
;
321 * @brief Closedown the newt library, tidying screen.
322 * @returns int , 0. (no errors reported)
324 int newtFinished(void) {
325 SLsmg_gotorc(SLtt_Screen_Rows
- 1, 0);
335 * @brief Set the colors used.
336 * @param colors - newtColor struct used.
338 void newtSetColors(struct newtColors colors
) {
339 if (!SLtt_Use_Ansi_Colors
) {
342 for (i
= 2; i
< 25; i
++)
343 SLtt_set_mono(i
, NULL
, 0);
345 SLtt_set_mono(NEWT_COLORSET_SELLISTBOX
, NULL
, SLTT_BOLD_MASK
);
347 SLtt_set_mono(NEWT_COLORSET_ACTBUTTON
, NULL
, SLTT_REV_MASK
);
348 SLtt_set_mono(NEWT_COLORSET_ACTCHECKBOX
, NULL
, SLTT_REV_MASK
);
349 SLtt_set_mono(NEWT_COLORSET_ACTLISTBOX
, NULL
, SLTT_REV_MASK
);
350 SLtt_set_mono(NEWT_COLORSET_ACTTEXTBOX
, NULL
, SLTT_REV_MASK
);
352 SLtt_set_mono(NEWT_COLORSET_ACTSELLISTBOX
, NULL
, SLTT_REV_MASK
| SLTT_BOLD_MASK
);
354 SLtt_set_mono(NEWT_COLORSET_DISENTRY
, NULL
, 0); // FIXME
355 SLtt_set_mono(NEWT_COLORSET_FULLSCALE
, NULL
, SLTT_ULINE_MASK
| SLTT_REV_MASK
);
356 SLtt_set_mono(NEWT_COLORSET_EMPTYSCALE
, NULL
, SLTT_ULINE_MASK
);
359 SLtt_set_color(NEWT_COLORSET_ROOT
, "", colors
.rootFg
, colors
.rootBg
);
360 SLtt_set_color(NEWT_COLORSET_BORDER
, "", colors
.borderFg
, colors
.borderBg
);
361 SLtt_set_color(NEWT_COLORSET_WINDOW
, "", colors
.windowFg
, colors
.windowBg
);
362 SLtt_set_color(NEWT_COLORSET_SHADOW
, "", colors
.shadowFg
, colors
.shadowBg
);
363 SLtt_set_color(NEWT_COLORSET_TITLE
, "", colors
.titleFg
, colors
.titleBg
);
364 SLtt_set_color(NEWT_COLORSET_BUTTON
, "", colors
.buttonFg
, colors
.buttonBg
);
365 SLtt_set_color(NEWT_COLORSET_ACTBUTTON
, "", colors
.actButtonFg
,
367 SLtt_set_color(NEWT_COLORSET_CHECKBOX
, "", colors
.checkboxFg
,
369 SLtt_set_color(NEWT_COLORSET_ACTCHECKBOX
, "", colors
.actCheckboxFg
,
370 colors
.actCheckboxBg
);
371 SLtt_set_color(NEWT_COLORSET_ENTRY
, "", colors
.entryFg
, colors
.entryBg
);
372 SLtt_set_color(NEWT_COLORSET_LABEL
, "", colors
.labelFg
, colors
.labelBg
);
373 SLtt_set_color(NEWT_COLORSET_LISTBOX
, "", colors
.listboxFg
,
375 SLtt_set_color(NEWT_COLORSET_ACTLISTBOX
, "", colors
.actListboxFg
,
376 colors
.actListboxBg
);
377 SLtt_set_color(NEWT_COLORSET_TEXTBOX
, "", colors
.textboxFg
,
379 SLtt_set_color(NEWT_COLORSET_ACTTEXTBOX
, "", colors
.actTextboxFg
,
380 colors
.actTextboxBg
);
381 SLtt_set_color(NEWT_COLORSET_HELPLINE
, "", colors
.helpLineFg
,
383 SLtt_set_color(NEWT_COLORSET_ROOTTEXT
, "", colors
.rootTextFg
,
386 SLtt_set_color(NEWT_COLORSET_EMPTYSCALE
, "", "white",
388 SLtt_set_color(NEWT_COLORSET_FULLSCALE
, "", "white",
390 SLtt_set_color(NEWT_COLORSET_DISENTRY
, "", colors
.disabledEntryFg
,
391 colors
.disabledEntryBg
);
393 SLtt_set_color(NEWT_COLORSET_COMPACTBUTTON
, "", colors
.compactButtonFg
,
394 colors
.compactButtonBg
);
396 SLtt_set_color(NEWT_COLORSET_ACTSELLISTBOX
, "", colors
.actSelListboxFg
,
397 colors
.actSelListboxBg
);
398 SLtt_set_color(NEWT_COLORSET_SELLISTBOX
, "", colors
.selListboxFg
,
399 colors
.selListboxBg
);
402 /* Keymap handling - rewritten by Henning Makholm <henning@makholm.net>,
406 struct kmap_trie_entry
{
407 char c
; /* character got from terminal */
408 int code
; /* newt key, or 0 if c does not make a complete sequence */
409 struct kmap_trie_entry
*contseq
; /* sub-trie for character following c */
410 struct kmap_trie_entry
*next
; /* try this if char received != c */
412 /* Here are some static entries that will help in handling esc O foo and
413 esc [ foo as variants of each other: */
414 static struct kmap_trie_entry
415 kmap_trie_escO
= { 'O', 0, 0, 0 },
416 kmap_trie_escBrack
= { '[', 0, 0, &kmap_trie_escO
},
417 kmap_trie_root
= { '\033', 0, &kmap_trie_escBrack
, 0 };
418 static int keyreader_buf_len
= 10 ;
419 static unsigned char default_keyreader_buf
[10];
420 static unsigned char *keyreader_buf
= default_keyreader_buf
;
422 #if 0 /* for testing of the keymap manipulation code */
423 static void dumpkeys_recursive(struct kmap_trie_entry
*curr
, int i
, FILE *f
) {
426 if( curr
&& i
>= keyreader_buf_len
) {
427 fprintf(f
,"ARGH! Too long sequence!\n") ;
430 for(;curr
;curr
=curr
->next
) {
431 keyreader_buf
[i
] = curr
->c
;
432 ps
= seen
[(unsigned char)curr
->c
]++ ;
433 if( ps
|| curr
->code
|| (!curr
->code
&& !curr
->contseq
) ) {
435 if( keyreader_buf
[j
] > 32 && keyreader_buf
[j
]<127 &&
436 keyreader_buf
[j
] != '^' && keyreader_buf
[j
] != '\\' )
437 fprintf(f
,"%c",keyreader_buf
[j
]);
438 else if( keyreader_buf
[j
] > 0 && keyreader_buf
[j
]<=32 )
439 fprintf(f
,"^%c",keyreader_buf
[j
] + 0x40);
442 (unsigned)(unsigned char)keyreader_buf
[j
]);
445 fprintf(f
,": 0x%X\n",curr
->code
);
447 fprintf(f
,": (just keymap)\n");
449 dumpkeys_recursive(curr
->contseq
,i
+1,f
);
452 static void dump_keymap(void) {
453 FILE *f
= fopen("newt.keydump","wt");
455 dumpkeys_recursive(&kmap_trie_root
,0,f
);
461 /* newtBindKey may overwrite a binding that is there already */
462 static void newtBindKey(char *keyseq
, int meaning
) {
463 struct kmap_trie_entry
*root
= &kmap_trie_root
;
464 struct kmap_trie_entry
**curptr
= &root
;
466 /* Try to make sure the common matching buffer is long enough. */
467 if( strlen(keyseq
) > keyreader_buf_len
) {
468 int i
= strlen(keyseq
)+10;
469 unsigned char *newbuf
= malloc(i
);
471 if (keyreader_buf
!= default_keyreader_buf
)
473 keyreader_buf
= newbuf
;
474 keyreader_buf_len
= i
;
478 if (*keyseq
== 0) return; /* binding the empty sequence is meaningless */
481 while ((*curptr
) && (*curptr
)->c
!= *keyseq
)
482 curptr
= &(*curptr
)->next
;
484 struct kmap_trie_entry
* fresh
485 = calloc(strlen(keyseq
),sizeof(struct kmap_trie_entry
));
486 if (fresh
== 0) return; /* despair! */
489 fresh
->contseq
= fresh
+1;
490 (fresh
++)->c
= *(keyseq
++);
493 fresh
->code
= meaning
;
497 (*curptr
)->code
= meaning
;
500 curptr
= &(*curptr
)->contseq
;
506 /* This function recursively inserts all entries in the "to" trie into
507 corresponding positions in the "from" trie, except positions that
508 are already defined in the "from" trie. */
509 static void kmap_trie_fallback(struct kmap_trie_entry
*to
,
510 struct kmap_trie_entry
**from
) {
515 for (;to
!=NULL
;to
=to
->next
) {
516 struct kmap_trie_entry
**fromcopy
= from
;
517 while ((*fromcopy
) && (*fromcopy
)->c
!= to
->c
)
518 fromcopy
= &(*fromcopy
)->next
;
520 if ((*fromcopy
)->code
== 0)
521 (*fromcopy
)->code
= to
->code
;
522 kmap_trie_fallback(to
->contseq
, &(*fromcopy
)->contseq
);
524 *fromcopy
= malloc(sizeof(struct kmap_trie_entry
));
527 (*fromcopy
)->next
= 0 ;
533 int newtGetKey(void) {
535 unsigned char *chptr
= keyreader_buf
, *lastmatch
;
537 struct kmap_trie_entry
*curr
= &kmap_trie_root
;
541 if (key
== SLANG_GETKEY_ERROR
) {
542 /* Either garbage was read, or stdin disappeared
543 * (the parent terminal was proably closed)
544 * if the latter, die.
550 return NEWT_KEY_RESIZE
;
553 /* ignore other signals */
557 if (key
== NEWT_KEY_SUSPEND
&& suspendCallback
)
558 suspendCallback(suspendCallbackData
);
559 } while (key
== NEWT_KEY_SUSPEND
);
561 /* Read more characters, matching against the trie as we go */
562 lastcode
= *chptr
= key
;
565 while (curr
->c
!= key
) {
567 if (curr
==NULL
) goto break2levels
;
570 lastcode
= curr
->code
;
573 curr
= curr
->contseq
;
574 if (curr
==NULL
) break;
576 if (SLang_input_pending(5) <= 0)
579 if (chptr
==keyreader_buf
+keyreader_buf_len
-1) break;
580 *++chptr
= key
= getkey();
584 /* The last time the trie matched was at position lastmatch. Back
585 * up if we have read too many characters. */
586 while (chptr
> lastmatch
)
587 SLang_ungetkey(*chptr
--);
593 * @brief Wait for a keystroke
595 void newtWaitForKey(void) {
599 newtClearKeyBuffer();
603 * @brief Clear the keybuffer
605 void newtClearKeyBuffer(void) {
606 while (SLang_input_pending(1)) {
613 * @param left. int Size; _not_ including border
614 * @param top: int size, _not_ including border
615 * @param width unsigned int
616 * @param height unsigned int
617 * @param title - title string
618 * @return zero on success (currently no errors reported)
620 int newtOpenWindow(int left
, int top
,
621 unsigned int width
, unsigned int height
,
622 const char * title
) {
629 if (!currentWindow
) {
630 currentWindow
= windowStack
;
635 currentWindow
->left
= left
;
636 currentWindow
->top
= top
;
637 currentWindow
->width
= width
;
638 currentWindow
->height
= height
;
639 currentWindow
->title
= title
? strdup(title
) : NULL
;
641 currentWindow
->buffer
= malloc(sizeof(SLsmg_Char_Type
) * (width
+ 3) * (height
+ 3));
645 /* clip to the current screen bounds - msw */
650 if (left
+ width
> SLtt_Screen_Cols
)
651 width
= SLtt_Screen_Cols
- left
;
652 if (top
+ height
> SLtt_Screen_Rows
)
653 height
= SLtt_Screen_Rows
- top
;
655 for (j
= 0; j
< height
+ 3; j
++, row
++) {
656 SLsmg_gotorc(row
, col
);
657 SLsmg_read_raw(currentWindow
->buffer
+ n
,
658 currentWindow
->width
+ 3);
659 n
+= currentWindow
->width
+ 3;
664 SLsmg_set_color(NEWT_COLORSET_BORDER
);
665 SLsmg_set_char_set(1);
666 SLsmg_draw_box(top
- 1, left
- 1, height
+ 2, width
+ 2);
667 SLsmg_set_char_set(0);
669 if (currentWindow
->title
) {
670 trim_string (currentWindow
->title
, width
-4);
671 i
= wstrlen(currentWindow
->title
,-1) + 4;
672 i
= ((width
- i
) / 2) + left
;
673 SLsmg_gotorc(top
- 1, i
);
674 SLsmg_set_char_set(1);
675 SLsmg_write_char(SLSMG_RTEE_CHAR
);
676 SLsmg_set_char_set(0);
677 SLsmg_write_char(' ');
678 SLsmg_set_color(NEWT_COLORSET_TITLE
);
679 SLsmg_write_string((char *)currentWindow
->title
);
680 SLsmg_set_color(NEWT_COLORSET_BORDER
);
681 SLsmg_write_char(' ');
682 SLsmg_set_char_set(1);
683 SLsmg_write_char(SLSMG_LTEE_CHAR
);
684 SLsmg_set_char_set(0);
687 SLsmg_set_color(NEWT_COLORSET_WINDOW
);
688 SLsmg_fill_region(top
, left
, height
, width
, ' ');
690 SLsmg_set_color(NEWT_COLORSET_SHADOW
);
691 SLsmg_fill_region(top
+ height
+ 1, left
, 1, width
+ 2, ' ');
692 SLsmg_fill_region(top
, left
+ width
+ 1, height
+ 1, 1, ' ');
694 for (i
= top
; i
< (top
+ height
+ 1); i
++) {
695 SLsmg_gotorc(i
, left
+ width
+ 1);
696 SLsmg_write_string(" ");
703 * @brief Draw a centered window.
704 * @param width - width in char cells
705 * @param height - no. of char cells.
706 * @param title - fixed title
707 * @returns 0. No errors reported
709 int newtCenteredWindow(unsigned int width
,unsigned int height
,
710 const char * title
) {
713 top
= (int)(SLtt_Screen_Rows
- height
) / 2;
715 /* I don't know why, but this seems to look better */
716 if ((SLtt_Screen_Rows
% 2) && (top
% 2)) top
--;
718 left
= (int)(SLtt_Screen_Cols
- width
) / 2;
720 newtOpenWindow(left
, top
, width
, height
, title
);
726 * @brief Remove the top window
728 void newtPopWindow(void) {
734 row
= currentWindow
->top
- 1;
735 col
= currentWindow
->left
- 1;
740 for (j
= 0; j
< currentWindow
->height
+ 3; j
++, row
++) {
741 SLsmg_gotorc(row
, col
);
742 SLsmg_write_raw(currentWindow
->buffer
+ n
,
743 currentWindow
->width
+ 3);
744 n
+= currentWindow
->width
+ 3;
747 free(currentWindow
->buffer
);
748 free(currentWindow
->title
);
750 if (currentWindow
== windowStack
)
751 currentWindow
= NULL
;
755 SLsmg_set_char_set(0);
762 void newtGetWindowPos(int * x
, int * y
) {
764 *x
= currentWindow
->left
;
765 *y
= currentWindow
->top
;
770 void newtGetrc(int * row
, int * col
) {
775 void newtGotorc(int newRow
, int newCol
) {
777 newRow
+= currentWindow
->top
;
778 newCol
+= currentWindow
->left
;
783 SLsmg_gotorc(cursorRow
, cursorCol
);
786 void newtDrawBox(int left
, int top
, int width
, int height
, int shadow
) {
788 top
+= currentWindow
->top
;
789 left
+= currentWindow
->left
;
792 SLsmg_draw_box(top
, left
, height
, width
);
795 SLsmg_set_color(NEWT_COLORSET_SHADOW
);
796 SLsmg_fill_region(top
+ height
, left
+ 1, 1, width
- 1, ' ');
797 SLsmg_fill_region(top
+ 1, left
+ width
, height
, 1, ' ');
801 void newtClearBox(int left
, int top
, int width
, int height
) {
803 top
+= currentWindow
->top
;
804 left
+= currentWindow
->left
;
807 SLsmg_fill_region(top
, left
, height
, width
, ' ');
810 static void initKeymap(void) {
811 const struct keymap
* curr
;
813 /* First bind built-in default bindings. They may be shadowed by
814 the termcap entries that get bound later. */
815 for (curr
= keymap
; curr
->code
; curr
++) {
817 newtBindKey(curr
->str
,curr
->code
);
820 /* Then bind strings from termcap entries */
821 for (curr
= keymap
; curr
->code
; curr
++) {
823 char *pc
= SLtt_tgetstr(curr
->tc
);
825 newtBindKey(pc
,curr
->code
);
830 /* Finally, invent lowest-priority keybindings that correspond to
831 searching for esc-O-foo if esc-[-foo was not found and vice
832 versa. That is needed because of strong confusion among
833 different emulators of VTxxx terminals; some terminfo/termcap
834 descriptions are apparently written by people who were not
835 aware of the differences between "applicataion" and "terminal"
836 keypad modes. Or perhaps they were, but tried to make their
837 description work with a program that puts the keyboard in the
838 wrong emulation mode. In short, one needs this: */
839 kmap_trie_fallback(kmap_trie_escO
.contseq
, &kmap_trie_escBrack
.contseq
);
840 kmap_trie_fallback(kmap_trie_escBrack
.contseq
, &kmap_trie_escO
.contseq
);
844 * @brief Delay for a specified number of usecs
845 * @param int - number of usecs to wait for.
847 void newtDelay(unsigned int usecs
) {
853 tv
.tv_sec
= usecs
/ 1000000;
854 tv
.tv_usec
= usecs
% 1000000;
856 select(0, &set
, &set
, &set
, &tv
);
859 struct eventResult
newtDefaultEventHandler(newtComponent c
,
861 struct eventResult er
;
863 er
.result
= ER_IGNORED
;
867 void newtRedrawHelpLine(void) {
870 SLsmg_set_color(NEWT_COLORSET_HELPLINE
);
872 if (currentHelpline
) {
873 /* buffer size needs to be wide enough to hold all the multibyte
874 currentHelpline + all the single byte ' ' to fill the line */
875 int wlen
= wstrlen(*currentHelpline
, -1);
878 if (wlen
> SLtt_Screen_Cols
)
879 wlen
= SLtt_Screen_Cols
;
880 len
= strlen(*currentHelpline
) + (SLtt_Screen_Cols
- wlen
);
881 buf
= alloca(len
+ 1);
882 memset(buf
, ' ', len
);
883 memcpy(buf
, *currentHelpline
, strlen(*currentHelpline
));
886 buf
= alloca(SLtt_Screen_Cols
+ 1);
887 memset(buf
, ' ', SLtt_Screen_Cols
);
888 buf
[SLtt_Screen_Cols
] = '\0';
890 SLsmg_gotorc(SLtt_Screen_Rows
- 1, 0);
891 SLsmg_write_string(buf
);
894 void newtPushHelpLine(const char * text
) {
896 text
= defaultHelpLine
;
899 (*(++currentHelpline
)) = strdup(text
);
901 currentHelpline
= helplineStack
;
902 *currentHelpline
= strdup(text
);
905 newtRedrawHelpLine();
908 void newtPopHelpLine(void) {
909 if (!currentHelpline
) return;
911 free(*currentHelpline
);
912 if (currentHelpline
== helplineStack
)
913 currentHelpline
= NULL
;
917 newtRedrawHelpLine();
920 void newtDrawRootText(int col
, int row
, const char * text
) {
921 SLsmg_set_color(NEWT_COLORSET_ROOTTEXT
);
924 col
= SLtt_Screen_Cols
+ col
;
928 row
= SLtt_Screen_Rows
+ row
;
931 SLsmg_gotorc(row
, col
);
932 SLsmg_write_string((char *)text
);
935 int newtSetFlags(int oldFlags
, int newFlags
, enum newtFlagsSense sense
) {
938 return oldFlags
| newFlags
;
940 case NEWT_FLAGS_RESET
:
941 return oldFlags
& (~newFlags
);
943 case NEWT_FLAGS_TOGGLE
:
944 return oldFlags
^ newFlags
;
956 void newtGetScreenSize(int * cols
, int * rows
) {
957 if (rows
) *rows
= SLtt_Screen_Rows
;
958 if (cols
) *cols
= SLtt_Screen_Cols
;
961 void newtDefaultPlaceHandler(newtComponent c
, int newLeft
, int newTop
) {
966 void newtDefaultMappedHandler(newtComponent c
, int isMapped
) {
967 c
->isMapped
= isMapped
;
970 void newtCursorOff(void) {
972 SLtt_set_cursor_visibility (cursorOn
);
975 void newtCursorOn(void) {
977 SLtt_set_cursor_visibility (cursorOn
);
980 void newtTrashScreen(void) {
982 SLsmg_touch_lines (0, SLtt_Screen_Rows
- 1);