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 "lightgray", "blue", /* checkbox fg, bg */
57 "lightgray", "red", /* active checkbox fg, bg */
58 "lightgray", "blue", /* entry box fg, bg */
59 "blue", "lightgray", /* label fg, bg */
60 "black", "lightgray", /* listbox fg, bg */
61 "lightgray", "blue", /* active listbox fg, bg */
62 "black", "lightgray", /* textbox fg, bg */
63 "lightgray", "red", /* active textbox fg, bg */
64 "white", "blue", /* help line */
65 "lightgray", "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 "lightgray", "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
));
196 x
= mbrtowc(&tmp
, p
, ln
, &ps
);
197 if (x
< 0) { // error
213 static int getkey() {
216 while ((c
= SLang_getkey()) == '\xC') { /* if Ctrl-L redraw whole screen */
217 SLsmg_touch_lines (0, SLtt_Screen_Rows
- 1);
224 void newtFlushInput(void) {
225 while (SLang_input_pending(0)) {
231 * @brief Refresh the screen
233 void newtRefresh(void) {
237 void newtSuspend(void) {
238 SLtt_set_cursor_visibility (1);
241 SLtt_set_cursor_visibility (cursorOn
);
245 * @brief Return after suspension.
246 * @return 0 on success.
248 int newtResume(void) {
251 return SLang_init_tty(0, 0, 0);
255 SLsmg_set_color(NEWT_COLORSET_ROOT
);
263 * @brief Resize the screen
264 * @param redraw - boolean - should we redraw the screen?
266 void newtResizeScreen(int redraw
) {
267 SLtt_get_screen_size();
270 SLsmg_touch_lines (0, SLtt_Screen_Rows
- 1);
276 * @brief Initialize the newt library
277 * @return int - 0 for success, else < 0
280 char * MonoValue
, * MonoEnv
= "NEWT_MONO";
284 if ((lang
= getenv("LC_ALL")) == NULL
)
285 if ((lang
= getenv("LC_CTYPE")) == NULL
)
286 if ((lang
= getenv("LANG")) == NULL
)
288 if (strstr (lang
, ".euc") != NULL
)
291 (void) strlen(ident
);
294 SLtt_get_screen_size();
296 MonoValue
= getenv(MonoEnv
);
297 if ( MonoValue
!= NULL
)
298 SLtt_Use_Ansi_Colors
= 0;
300 if ((ret
= SLsmg_init_smg()) < 0)
302 if ((ret
= SLang_init_tty(0, 0, 0)) < 0)
305 newtSetColors(newtDefaultColorPalette
);
309 /*memset(&sa, 0, sizeof(sa));
310 sa.sa_handler = handleSigwinch;
311 sigaction(SIGWINCH, &sa, NULL);*/
313 SLsignal_intr(SIGWINCH
, handleSigwinch
);
314 SLang_getkey_intr_hook
= getkeyInterruptHook
;
320 * @brief Closedown the newt library, tidying screen.
321 * @returns int , 0. (no errors reported)
323 int newtFinished(void) {
324 SLsmg_gotorc(SLtt_Screen_Rows
- 1, 0);
334 * @brief Set the colors used.
335 * @param colors - newtColor struct used.
337 void newtSetColors(struct newtColors colors
) {
338 if (!SLtt_Use_Ansi_Colors
) {
341 for (i
= 2; i
< 25; i
++)
342 SLtt_set_mono(i
, NULL
, 0);
344 SLtt_set_mono(NEWT_COLORSET_SELLISTBOX
, NULL
, SLTT_BOLD_MASK
);
346 SLtt_set_mono(NEWT_COLORSET_ACTBUTTON
, NULL
, SLTT_REV_MASK
);
347 SLtt_set_mono(NEWT_COLORSET_ACTCHECKBOX
, NULL
, SLTT_REV_MASK
);
348 SLtt_set_mono(NEWT_COLORSET_ACTLISTBOX
, NULL
, SLTT_REV_MASK
);
349 SLtt_set_mono(NEWT_COLORSET_ACTTEXTBOX
, NULL
, SLTT_REV_MASK
);
351 SLtt_set_mono(NEWT_COLORSET_ACTSELLISTBOX
, NULL
, SLTT_REV_MASK
| SLTT_BOLD_MASK
);
353 SLtt_set_mono(NEWT_COLORSET_DISENTRY
, NULL
, 0); // FIXME
354 SLtt_set_mono(NEWT_COLORSET_FULLSCALE
, NULL
, SLTT_ULINE_MASK
| SLTT_REV_MASK
);
355 SLtt_set_mono(NEWT_COLORSET_EMPTYSCALE
, NULL
, SLTT_ULINE_MASK
);
358 SLtt_set_color(NEWT_COLORSET_ROOT
, "", colors
.rootFg
, colors
.rootBg
);
359 SLtt_set_color(NEWT_COLORSET_BORDER
, "", colors
.borderFg
, colors
.borderBg
);
360 SLtt_set_color(NEWT_COLORSET_WINDOW
, "", colors
.windowFg
, colors
.windowBg
);
361 SLtt_set_color(NEWT_COLORSET_SHADOW
, "", colors
.shadowFg
, colors
.shadowBg
);
362 SLtt_set_color(NEWT_COLORSET_TITLE
, "", colors
.titleFg
, colors
.titleBg
);
363 SLtt_set_color(NEWT_COLORSET_BUTTON
, "", colors
.buttonFg
, colors
.buttonBg
);
364 SLtt_set_color(NEWT_COLORSET_ACTBUTTON
, "", colors
.actButtonFg
,
366 SLtt_set_color(NEWT_COLORSET_CHECKBOX
, "", colors
.checkboxFg
,
368 SLtt_set_color(NEWT_COLORSET_ACTCHECKBOX
, "", colors
.actCheckboxFg
,
369 colors
.actCheckboxBg
);
370 SLtt_set_color(NEWT_COLORSET_ENTRY
, "", colors
.entryFg
, colors
.entryBg
);
371 SLtt_set_color(NEWT_COLORSET_LABEL
, "", colors
.labelFg
, colors
.labelBg
);
372 SLtt_set_color(NEWT_COLORSET_LISTBOX
, "", colors
.listboxFg
,
374 SLtt_set_color(NEWT_COLORSET_ACTLISTBOX
, "", colors
.actListboxFg
,
375 colors
.actListboxBg
);
376 SLtt_set_color(NEWT_COLORSET_TEXTBOX
, "", colors
.textboxFg
,
378 SLtt_set_color(NEWT_COLORSET_ACTTEXTBOX
, "", colors
.actTextboxFg
,
379 colors
.actTextboxBg
);
380 SLtt_set_color(NEWT_COLORSET_HELPLINE
, "", colors
.helpLineFg
,
382 SLtt_set_color(NEWT_COLORSET_ROOTTEXT
, "", colors
.rootTextFg
,
385 SLtt_set_color(NEWT_COLORSET_EMPTYSCALE
, "", "white",
387 SLtt_set_color(NEWT_COLORSET_FULLSCALE
, "", "white",
389 SLtt_set_color(NEWT_COLORSET_DISENTRY
, "", colors
.disabledEntryFg
,
390 colors
.disabledEntryBg
);
392 SLtt_set_color(NEWT_COLORSET_COMPACTBUTTON
, "", colors
.compactButtonFg
,
393 colors
.compactButtonBg
);
395 SLtt_set_color(NEWT_COLORSET_ACTSELLISTBOX
, "", colors
.actSelListboxFg
,
396 colors
.actSelListboxBg
);
397 SLtt_set_color(NEWT_COLORSET_SELLISTBOX
, "", colors
.selListboxFg
,
398 colors
.selListboxBg
);
401 /* Keymap handling - rewritten by Henning Makholm <henning@makholm.net>,
405 struct kmap_trie_entry
{
406 char c
; /* character got from terminal */
407 int code
; /* newt key, or 0 if c does not make a complete sequence */
408 struct kmap_trie_entry
*contseq
; /* sub-trie for character following c */
409 struct kmap_trie_entry
*next
; /* try this if char received != c */
411 /* Here are some static entries that will help in handling esc O foo and
412 esc [ foo as variants of each other: */
413 static struct kmap_trie_entry
414 kmap_trie_escO
= { 'O', 0, 0, 0 },
415 kmap_trie_escBrack
= { '[', 0, 0, &kmap_trie_escO
},
416 kmap_trie_root
= { '\033', 0, &kmap_trie_escBrack
, 0 };
417 static int keyreader_buf_len
= 10 ;
418 static unsigned char default_keyreader_buf
[10];
419 static unsigned char *keyreader_buf
= default_keyreader_buf
;
421 #if 0 /* for testing of the keymap manipulation code */
422 static void dumpkeys_recursive(struct kmap_trie_entry
*curr
, int i
, FILE *f
) {
425 if( curr
&& i
>= keyreader_buf_len
) {
426 fprintf(f
,"ARGH! Too long sequence!\n") ;
429 for(;curr
;curr
=curr
->next
) {
430 keyreader_buf
[i
] = curr
->c
;
431 ps
= seen
[(unsigned char)curr
->c
]++ ;
432 if( ps
|| curr
->code
|| (!curr
->code
&& !curr
->contseq
) ) {
434 if( keyreader_buf
[j
] > 32 && keyreader_buf
[j
]<127 &&
435 keyreader_buf
[j
] != '^' && keyreader_buf
[j
] != '\\' )
436 fprintf(f
,"%c",keyreader_buf
[j
]);
437 else if( keyreader_buf
[j
] > 0 && keyreader_buf
[j
]<=32 )
438 fprintf(f
,"^%c",keyreader_buf
[j
] + 0x40);
441 (unsigned)(unsigned char)keyreader_buf
[j
]);
444 fprintf(f
,": 0x%X\n",curr
->code
);
446 fprintf(f
,": (just keymap)\n");
448 dumpkeys_recursive(curr
->contseq
,i
+1,f
);
451 static void dump_keymap(void) {
452 FILE *f
= fopen("newt.keydump","wt");
454 dumpkeys_recursive(&kmap_trie_root
,0,f
);
460 /* newtBindKey may overwrite a binding that is there already */
461 static void newtBindKey(char *keyseq
, int meaning
) {
462 struct kmap_trie_entry
*root
= &kmap_trie_root
;
463 struct kmap_trie_entry
**curptr
= &root
;
465 /* Try to make sure the common matching buffer is long enough. */
466 if( strlen(keyseq
) > keyreader_buf_len
) {
467 int i
= strlen(keyseq
)+10;
468 unsigned char *newbuf
= malloc(i
);
470 if (keyreader_buf
!= default_keyreader_buf
)
472 keyreader_buf
= newbuf
;
473 keyreader_buf_len
= i
;
477 if (*keyseq
== 0) return; /* binding the empty sequence is meaningless */
480 while ((*curptr
) && (*curptr
)->c
!= *keyseq
)
481 curptr
= &(*curptr
)->next
;
483 struct kmap_trie_entry
* fresh
484 = calloc(strlen(keyseq
),sizeof(struct kmap_trie_entry
));
485 if (fresh
== 0) return; /* despair! */
488 fresh
->contseq
= fresh
+1;
489 (fresh
++)->c
= *(keyseq
++);
492 fresh
->code
= meaning
;
496 (*curptr
)->code
= meaning
;
499 curptr
= &(*curptr
)->contseq
;
505 /* This function recursively inserts all entries in the "to" trie into
506 corresponding positions in the "from" trie, except positions that
507 are already defined in the "from" trie. */
508 static void kmap_trie_fallback(struct kmap_trie_entry
*to
,
509 struct kmap_trie_entry
**from
) {
514 for (;to
!=NULL
;to
=to
->next
) {
515 struct kmap_trie_entry
**fromcopy
= from
;
516 while ((*fromcopy
) && (*fromcopy
)->c
!= to
->c
)
517 fromcopy
= &(*fromcopy
)->next
;
519 if ((*fromcopy
)->code
== 0)
520 (*fromcopy
)->code
= to
->code
;
521 kmap_trie_fallback(to
->contseq
, &(*fromcopy
)->contseq
);
523 *fromcopy
= malloc(sizeof(struct kmap_trie_entry
));
526 (*fromcopy
)->next
= 0 ;
532 int newtGetKey(void) {
534 unsigned char *chptr
= keyreader_buf
, *lastmatch
;
536 struct kmap_trie_entry
*curr
= &kmap_trie_root
;
540 if (key
== SLANG_GETKEY_ERROR
) {
541 /* Either garbage was read, or stdin disappeared
542 * (the parent terminal was proably closed)
543 * if the latter, die.
549 return NEWT_KEY_RESIZE
;
552 /* ignore other signals */
556 if (key
== NEWT_KEY_SUSPEND
&& suspendCallback
)
557 suspendCallback(suspendCallbackData
);
558 } while (key
== NEWT_KEY_SUSPEND
);
560 /* Read more characters, matching against the trie as we go */
561 lastcode
= *chptr
= key
;
564 while (curr
->c
!= key
) {
566 if (curr
==NULL
) goto break2levels
;
569 lastcode
= curr
->code
;
572 curr
= curr
->contseq
;
573 if (curr
==NULL
) break;
575 if (SLang_input_pending(5) <= 0)
578 if (chptr
==keyreader_buf
+keyreader_buf_len
-1) break;
579 *++chptr
= key
= getkey();
583 /* The last time the trie matched was at position lastmatch. Back
584 * up if we have read too many characters. */
585 while (chptr
> lastmatch
)
586 SLang_ungetkey(*chptr
--);
592 * @brief Wait for a keystroke
594 void newtWaitForKey(void) {
598 newtClearKeyBuffer();
602 * @brief Clear the keybuffer
604 void newtClearKeyBuffer(void) {
605 while (SLang_input_pending(1)) {
612 * @param left. int Size; _not_ including border
613 * @param top: int size, _not_ including border
614 * @param width unsigned int
615 * @param height unsigned int
616 * @param title - title string
617 * @return zero on success (currently no errors reported)
619 int newtOpenWindow(int left
, int top
,
620 unsigned int width
, unsigned int height
,
621 const char * title
) {
628 if (!currentWindow
) {
629 currentWindow
= windowStack
;
634 currentWindow
->left
= left
;
635 currentWindow
->top
= top
;
636 currentWindow
->width
= width
;
637 currentWindow
->height
= height
;
638 currentWindow
->title
= title
? strdup(title
) : NULL
;
640 currentWindow
->buffer
= malloc(sizeof(SLsmg_Char_Type
) * (width
+ 5) * (height
+ 3));
644 /* clip to the current screen bounds - msw */
649 if (left
+ width
> SLtt_Screen_Cols
)
650 width
= SLtt_Screen_Cols
- left
;
651 if (top
+ height
> SLtt_Screen_Rows
)
652 height
= SLtt_Screen_Rows
- top
;
654 for (j
= 0; j
< height
+ 3; j
++, row
++) {
655 SLsmg_gotorc(row
, col
);
656 SLsmg_read_raw(currentWindow
->buffer
+ n
,
657 currentWindow
->width
+ 5);
658 n
+= currentWindow
->width
+ 5;
663 SLsmg_set_color(NEWT_COLORSET_BORDER
);
664 SLsmg_set_char_set(1);
665 SLsmg_draw_box(top
- 1, left
- 1, height
+ 2, width
+ 2);
666 SLsmg_set_char_set(0);
668 if (currentWindow
->title
) {
669 trim_string (currentWindow
->title
, width
-4);
670 i
= wstrlen(currentWindow
->title
,-1) + 4;
671 i
= ((width
- i
) / 2) + left
;
672 SLsmg_gotorc(top
- 1, i
);
673 SLsmg_set_char_set(1);
674 SLsmg_write_char(SLSMG_RTEE_CHAR
);
675 SLsmg_set_char_set(0);
676 SLsmg_write_char(' ');
677 SLsmg_set_color(NEWT_COLORSET_TITLE
);
678 SLsmg_write_string((char *)currentWindow
->title
);
679 SLsmg_set_color(NEWT_COLORSET_BORDER
);
680 SLsmg_write_char(' ');
681 SLsmg_set_char_set(1);
682 SLsmg_write_char(SLSMG_LTEE_CHAR
);
683 SLsmg_set_char_set(0);
686 SLsmg_set_color(NEWT_COLORSET_WINDOW
);
687 SLsmg_fill_region(top
, left
, height
, width
, ' ');
689 SLsmg_set_color(NEWT_COLORSET_SHADOW
);
690 SLsmg_fill_region(top
+ height
+ 1, left
, 1, width
+ 2, ' ');
691 SLsmg_fill_region(top
, left
+ width
+ 1, height
+ 1, 1, ' ');
693 for (i
= top
; i
< (top
+ height
+ 1); i
++) {
694 SLsmg_gotorc(i
, left
+ width
+ 1);
695 SLsmg_write_string(" ");
702 * @brief Draw a centered window.
703 * @param width - width in char cells
704 * @param height - no. of char cells.
705 * @param title - fixed title
706 * @returns 0. No errors reported
708 int newtCenteredWindow(unsigned int width
,unsigned int height
,
709 const char * title
) {
712 top
= (int)(SLtt_Screen_Rows
- height
) / 2;
714 /* I don't know why, but this seems to look better */
715 if ((SLtt_Screen_Rows
% 2) && (top
% 2)) top
--;
717 left
= (int)(SLtt_Screen_Cols
- width
) / 2;
719 newtOpenWindow(left
, top
, width
, height
, title
);
725 * @brief Remove the top window
727 void newtPopWindow(void) {
728 newtPopWindowNoRefresh();
732 void newtPopWindowNoRefresh(void) {
738 row
= currentWindow
->top
- 1;
739 col
= currentWindow
->left
- 2;
744 for (j
= 0; j
< currentWindow
->height
+ 3; j
++, row
++) {
745 SLsmg_gotorc(row
, col
);
746 SLsmg_write_raw(currentWindow
->buffer
+ n
,
747 currentWindow
->width
+ 5);
748 n
+= currentWindow
->width
+ 5;
751 free(currentWindow
->buffer
);
752 free(currentWindow
->title
);
754 if (currentWindow
== windowStack
)
755 currentWindow
= NULL
;
759 SLsmg_set_char_set(0);
764 void newtGetWindowPos(int * x
, int * y
) {
766 *x
= currentWindow
->left
;
767 *y
= currentWindow
->top
;
772 void newtGetrc(int * row
, int * col
) {
777 void newtGotorc(int newRow
, int newCol
) {
779 newRow
+= currentWindow
->top
;
780 newCol
+= currentWindow
->left
;
785 SLsmg_gotorc(cursorRow
, cursorCol
);
788 void newtDrawBox(int left
, int top
, int width
, int height
, int shadow
) {
790 top
+= currentWindow
->top
;
791 left
+= currentWindow
->left
;
794 SLsmg_draw_box(top
, left
, height
, width
);
797 SLsmg_set_color(NEWT_COLORSET_SHADOW
);
798 SLsmg_fill_region(top
+ height
, left
+ 1, 1, width
- 1, ' ');
799 SLsmg_fill_region(top
+ 1, left
+ width
, height
, 1, ' ');
803 void newtClearBox(int left
, int top
, int width
, int height
) {
805 top
+= currentWindow
->top
;
806 left
+= currentWindow
->left
;
809 SLsmg_fill_region(top
, left
, height
, width
, ' ');
812 static void initKeymap(void) {
813 const struct keymap
* curr
;
815 /* First bind built-in default bindings. They may be shadowed by
816 the termcap entries that get bound later. */
817 for (curr
= keymap
; curr
->code
; curr
++) {
819 newtBindKey(curr
->str
,curr
->code
);
822 /* Then bind strings from termcap entries */
823 for (curr
= keymap
; curr
->code
; curr
++) {
825 char *pc
= SLtt_tgetstr(curr
->tc
);
827 newtBindKey(pc
,curr
->code
);
832 /* Finally, invent lowest-priority keybindings that correspond to
833 searching for esc-O-foo if esc-[-foo was not found and vice
834 versa. That is needed because of strong confusion among
835 different emulators of VTxxx terminals; some terminfo/termcap
836 descriptions are apparently written by people who were not
837 aware of the differences between "applicataion" and "terminal"
838 keypad modes. Or perhaps they were, but tried to make their
839 description work with a program that puts the keyboard in the
840 wrong emulation mode. In short, one needs this: */
841 kmap_trie_fallback(kmap_trie_escO
.contseq
, &kmap_trie_escBrack
.contseq
);
842 kmap_trie_fallback(kmap_trie_escBrack
.contseq
, &kmap_trie_escO
.contseq
);
846 * @brief Delay for a specified number of usecs
847 * @param int - number of usecs to wait for.
849 void newtDelay(unsigned int usecs
) {
855 tv
.tv_sec
= usecs
/ 1000000;
856 tv
.tv_usec
= usecs
% 1000000;
858 select(0, &set
, &set
, &set
, &tv
);
861 struct eventResult
newtDefaultEventHandler(newtComponent c
,
863 struct eventResult er
;
865 er
.result
= ER_IGNORED
;
869 void newtRedrawHelpLine(void) {
872 SLsmg_set_color(NEWT_COLORSET_HELPLINE
);
874 if (currentHelpline
) {
875 /* buffer size needs to be wide enough to hold all the multibyte
876 currentHelpline + all the single byte ' ' to fill the line */
877 int wlen
= wstrlen(*currentHelpline
, -1);
880 if (wlen
> SLtt_Screen_Cols
)
881 wlen
= SLtt_Screen_Cols
;
882 len
= strlen(*currentHelpline
) + (SLtt_Screen_Cols
- wlen
);
883 buf
= alloca(len
+ 1);
884 memset(buf
, ' ', len
);
885 memcpy(buf
, *currentHelpline
, strlen(*currentHelpline
));
888 buf
= alloca(SLtt_Screen_Cols
+ 1);
889 memset(buf
, ' ', SLtt_Screen_Cols
);
890 buf
[SLtt_Screen_Cols
] = '\0';
892 SLsmg_gotorc(SLtt_Screen_Rows
- 1, 0);
893 SLsmg_write_string(buf
);
896 void newtPushHelpLine(const char * text
) {
898 text
= defaultHelpLine
;
901 (*(++currentHelpline
)) = strdup(text
);
903 currentHelpline
= helplineStack
;
904 *currentHelpline
= strdup(text
);
907 newtRedrawHelpLine();
910 void newtPopHelpLine(void) {
911 if (!currentHelpline
) return;
913 free(*currentHelpline
);
914 if (currentHelpline
== helplineStack
)
915 currentHelpline
= NULL
;
919 newtRedrawHelpLine();
922 void newtDrawRootText(int col
, int row
, const char * text
) {
923 SLsmg_set_color(NEWT_COLORSET_ROOTTEXT
);
926 col
= SLtt_Screen_Cols
+ col
;
930 row
= SLtt_Screen_Rows
+ row
;
933 SLsmg_gotorc(row
, col
);
934 SLsmg_write_string((char *)text
);
937 int newtSetFlags(int oldFlags
, int newFlags
, enum newtFlagsSense sense
) {
940 return oldFlags
| newFlags
;
942 case NEWT_FLAGS_RESET
:
943 return oldFlags
& (~newFlags
);
945 case NEWT_FLAGS_TOGGLE
:
946 return oldFlags
^ newFlags
;
958 void newtGetScreenSize(int * cols
, int * rows
) {
959 if (rows
) *rows
= SLtt_Screen_Rows
;
960 if (cols
) *cols
= SLtt_Screen_Cols
;
963 void newtDefaultPlaceHandler(newtComponent c
, int newLeft
, int newTop
) {
968 void newtDefaultMappedHandler(newtComponent c
, int isMapped
) {
969 c
->isMapped
= isMapped
;
972 void newtCursorOff(void) {
974 SLtt_set_cursor_visibility (cursorOn
);
977 void newtCursorOn(void) {
979 SLtt_set_cursor_visibility (cursorOn
);
982 void newtTrashScreen(void) {
984 SLsmg_touch_lines (0, SLtt_Screen_Rows
- 1);