1
/* $XFree86: xc/programs/Xserver/hw/xfree86/XF86Setup/tclcurses.c,v 1.2 1999/04/05 08:28:23 dawes Exp $ */
3
* Copyright 1997 by Joseph V. Moss <joe@XFree86.Org>
5
* Permission to use, copy, modify, distribute, and sell this software and its
6
* documentation for any purpose is hereby granted without fee, provided that
7
* the above copyright notice appear in all copies and that both that
8
* copyright notice and this permission notice appear in supporting
9
* documentation, and that the name of Joseph Moss not be used in
10
* advertising or publicity pertaining to distribution of the software without
11
* specific, written prior permission. Joseph Moss makes no representations
12
* about the suitability of this software for any purpose. It is provided
13
* "as is" without express or implied warranty.
15
* JOSEPH MOSS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17
* EVENT SHALL JOSEPH MOSS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21
* PERFORMANCE OF THIS SOFTWARE.
26
This file contains Tcl bindings to the curses library
37
#include "tclcurses.h"
40
static int curs_debug = 0;
43
Adds the curses command to the Tcl interpreter
50
Tcl_CreateCommand(interp, "curses", TCL_Curses, NULL,
60
TCL_Curses(clientData, interp, argc, argv)
61
ClientData clientData;
66
Tcl_AppendResult(interp,
67
"Curses not compiled in to this version of XF86SETUP", NULL);
77
TCL_Curses(clientData, interp, argc, argv)
78
ClientData clientData;
83
struct windata *winPtr;
87
Tcl_SetResult(interp, "Usage: curses ", TCL_STATIC);
91
if (!strcmp(argv[1], "init")) {
93
Tcl_AppendResult(interp, "Already initialized", NULL);
96
if (initscr() == NULL) {
97
Tcl_AppendResult(interp, "Unable to initialize curses", NULL);
103
intrflush(stdscr, FALSE);
104
keypad(stdscr, TRUE);
108
init_pair(PAIR_SCREEN);
109
init_pair(PAIR_ULBORD);
110
init_pair(PAIR_LRBORD);
111
init_pair(PAIR_TEXT);
112
init_pair(PAIR_TITLE);
113
init_pair(PAIR_SELECT);
114
winPtr = initwinPtr(stdscr);
116
attrset(ATTR_SCREEN);
117
Tcl_CreateCommand(interp,"stdscr",TCL_WinProc,winPtr,NULL);
118
} else if (argc == 3 && !strcmp(argv[1], "debug")) {
119
curs_debug = atoi(argv[2]);
120
} else if (!strcmp(argv[1], "end")) {
121
if (endwin() != OK) {
122
Tcl_AppendResult(interp, "curses end failed", NULL);
125
} else if (!strcmp(argv[1], "menubar")) {
127
Tcl_AppendResult(interp, "Not yet implemented", NULL);
129
} else if (!strcmp(argv[1], "newwin")) {
131
Tcl_AppendResult(interp,
132
"Usage: curses newwin <winname> <nlines>"
133
" <ncols> <begin_y> <begin_x>",
137
if ((tmpwin = newwin(atoi(argv[3]),atoi(argv[4]),
138
atoi(argv[5]),atoi(argv[6]))) == NULL) {
139
Tcl_AppendResult(interp, "Unable to create window", NULL);
143
keypad(tmpwin, TRUE);
144
winPtr = initwinPtr(tmpwin);
145
wbkgd(winPtr->win,ATTR_TEXT);
146
Tcl_CreateCommand(interp,argv[2],TCL_WinProc,winPtr,NULL);
147
} else if (!strcmp(argv[1], "delwin")) {
149
Tcl_AppendResult(interp,
150
"Usage: curses delwin <winname>", NULL);
153
if (Tcl_DeleteCommand(interp, argv[2]) == TCL_ERROR)
156
Tcl_AppendResult(interp, "Invalid option: ",
163
void TCL_WinDelete(clientData)
164
ClientData clientData;
166
struct windata *winPtr;
169
winPtr = (struct windata *) clientData;
171
ckfree(winPtr->title);
172
ckfree(winPtr->menu.chkd);
173
ckfree(winPtr->menu.win);
174
ckfree(winPtr->menu.data);
175
ckfree(winPtr->text.buffer);
176
ckfree(winPtr->text.data);
177
for (i = 0; i < MAXBUTTONS; i++)
178
ckfree(winPtr->button[i]);
186
TCL_WinProc(clientData, interp, argc, argv)
187
ClientData clientData;
192
struct windata *winPtr = (struct windata *) clientData;
195
if (argc == 4 && !strcmp(argv[1], "move")) {
196
wmove(winPtr->win,atoi(argv[2]),atoi(argv[3]));
197
} else if (argc == 3 && !strcmp(argv[1], "addstr")) {
198
waddstr(winPtr->win,argv[2]);
199
} else if (argc == 3 && !strcmp(argv[1], "text")) {
200
return settext(winPtr, interp, argv[2]);
201
} else if (argc == 2 && !strcmp(argv[1], "activate")) {
202
return processinput(winPtr, interp);
203
} else if (argc == 2 && !strcmp(argv[1], "clear")) {
205
} else if (argc == 2 && !strcmp(argv[1], "update")) {
206
wrefresh(winPtr->win);
207
} else if (argc == 2 && !strcmp(argv[1], "info")) {
208
sprintf(tmpbuf, "%d %d %d %d", winPtr->width, winPtr->height,
209
winPtr->border, winPtr->shadow);
210
Tcl_AppendResult(interp, tmpbuf, NULL);
211
Tcl_AppendElement(interp, winPtr->title);
212
} else if (argc > 2 && !strcmp(argv[1], "menu")) {
213
winPtr->menu.type=TYPE_MENU;
214
return setmenu(winPtr, interp, argc, argv);
215
} else if (argc > 2 && !strcmp(argv[1], "checklist")) {
216
winPtr->menu.type=TYPE_CHECK;
217
return setmenu(winPtr, interp, argc, argv);
218
} else if (argc > 2 && !strcmp(argv[1], "radiolist")) {
219
winPtr->menu.type=TYPE_RADIO;
220
return setmenu(winPtr, interp, argc, argv);
221
} else if (argc > 2 && !strcmp(argv[1], "buttons")) {
222
return setbuttons(winPtr, interp, argc, argv);
223
} else if (argc > 2 && !strcmp(argv[1], "configure")) {
224
return winconfig(winPtr, interp, argc, argv);
226
Tcl_AppendResult(interp, "Invalid option: ",
234
settext(winPtr, interp, text)
235
struct windata *winPtr;
240
char savechar, *ptr, *nlptr, *spcptr, *endchar;
242
DEBUG4("settext(%p, %p, %s)\n", winPtr, interp, text);
244
numcols = winPtr->width - (winPtr->border==BORDER_NONE? 0: 2);
245
if (winPtr->text.data) {
246
ckfree(winPtr->text.data);
247
ckfree(winPtr->text.buffer);
249
winPtr->text.items = winPtr->text.topline = 0;
251
winPtr->text.buffer = strdup(text);
252
ptr = nlptr = winPtr->text.buffer;
253
endchar = winPtr->text.buffer + strlen(text);
254
while (nlptr < endchar) {
255
if ((nlptr = strchr(ptr, '\n')) == NULL)
257
if (nlptr - ptr > numcols) {
259
while (strlen(ptr) > numcols) {
260
savechar = ptr[numcols];
262
spcptr = strrchr(ptr, ' ');
263
ptr[numcols] = savechar;
264
if (spcptr == NULL) {
265
ptr[numcols-1] = '\n';
272
if (nlptr != endchar)
278
winPtr->text.data = (char **) 0;
279
winPtr->text.buffer = endchar = NULL;
282
for (ptr= nlptr= winPtr->text.buffer; ptr<endchar && nlptr; ptr= nlptr+1) {
283
nlptr = strchr(ptr, '\n');
284
winPtr->text.items++;
286
winPtr->text.data = (char **) ckalloc(winPtr->text.items * sizeof(char *));
288
for (i=0, ptr= nlptr= winPtr->text.buffer; ptr<endchar && nlptr; ptr= nlptr+1) {
289
if ((nlptr = strchr(ptr, '\n')) != NULL)
291
winPtr->text.data[i++] = ptr;
293
DEBUG3("(text='%s' items=%d)\n", winPtr->text.buffer, winPtr->text.items);
295
updatetext(winPtr, interp);
296
DEBUG1("settext() returning okay\n");
301
updatetext(winPtr, interp)
302
struct windata *winPtr;
305
int i, j, row, col, numrows, numcols;
307
DEBUG3("updatetext(%p, %p)\n", winPtr, interp);
308
wattrset(winPtr->win, ATTR_TEXT);
309
if (winPtr->border == BORDER_NONE) {
311
numcols = winPtr->width;
314
numcols = winPtr->width-2;
316
numrows = textlines(winPtr);
318
for (i = row; i < row+numrows; i++) {
319
wmove(winPtr->win, i, col);
320
for (j = col; j < col+numcols; j++)
321
waddch(winPtr->win, ATTR_TEXT | ' ');
323
if (!winPtr->text.items)
326
for (i= 0, j= winPtr->text.topline; i<numrows && j<winPtr->text.items; i++, j++) {
327
wmove(winPtr->win, i+row, col);
328
waddstr(winPtr->win, winPtr->text.data[j]);
330
DEBUG1("updatetext() returning okay\n");
336
struct windata *winPtr;
340
if (winPtr->border == BORDER_NONE) {
341
rows = winPtr->height;
342
if (winPtr->button[0]) rows--;
344
rows = winPtr->height-2;
345
if (winPtr->button[0]) rows-=2;
347
if (winPtr->menu.items) rows -= winPtr->menu.items+2;
353
processinput(winPtr, interp)
354
struct windata *winPtr;
357
int key=0, i, lastbutton;
359
#define mybeep() beep(); wrefresh(winPtr->win)
361
for (lastbutton=0; lastbutton<MAXBUTTONS; lastbutton++) {
362
if (!winPtr->button[lastbutton])
366
switch (key = wgetch(winPtr->win)) {
368
if (!winPtr->button[0] || winPtr->butsel == lastbutton-1) {
372
updatebuttons(winPtr);
375
if (!winPtr->button[0] || winPtr->butsel == 0) {
379
updatebuttons(winPtr);
383
if (updatepos(winPtr, interp, KEY_UP, SCROLL_LINE) == TCL_ERROR)
387
if (updatepos(winPtr, interp, KEY_DOWN, SCROLL_LINE) == TCL_ERROR)
391
if (updatepos(winPtr, interp, KEY_UP, SCROLL_ALL) == TCL_ERROR)
395
if (updatepos(winPtr, interp, KEY_DOWN, SCROLL_ALL) == TCL_ERROR)
398
if (updatepos(winPtr, interp, KEY_UP, SCROLL_PAGE) == TCL_ERROR)
401
if (updatepos(winPtr, interp, KEY_DOWN, SCROLL_PAGE) == TCL_ERROR)
406
Tcl_AppendElement(interp, winPtr->button[0]?
407
winPtr->button[winPtr->butsel]: "");
408
if (winPtr->menu.items) {
409
if (winPtr->menu.type == TYPE_RADIO) {
410
Tcl_AppendElement(interp,
411
winPtr->menu.data[winPtr->menu.rsel]);
412
} else if (winPtr->menu.type == TYPE_CHECK) {
413
for (i = 0; i < winPtr->menu.items; i++) {
414
if (winPtr->menu.chkd[i])
415
Tcl_AppendElement(interp,
416
winPtr->menu.data[i]);
419
Tcl_AppendElement(interp,
420
winPtr->menu.data[winPtr->menu.current]);
425
if (winPtr->menu.items == 0
426
|| winPtr->menu.type == TYPE_NONE
427
|| winPtr->menu.type == TYPE_MENU) {
430
if (winPtr->menu.type == TYPE_RADIO)
431
winPtr->menu.rsel = winPtr->menu.current;
433
winPtr->menu.chkd[winPtr->menu.current] =
434
(winPtr->menu.chkd[winPtr->menu.current]+1)%2;
435
if (updatemenu(winPtr) == TCL_ERROR)
437
wrefresh(winPtr->menu.win);
443
Tcl_AppendResult(interp, "Escape", NULL);
453
updatepos(winPtr, interp, dir, amt)
454
struct windata *winPtr;
460
if ((winPtr->menu.type == TYPE_NONE && winPtr->text.data == NULL)
461
|| (winPtr->menu.type != TYPE_NONE && winPtr->menu.lines == 0) ) {
469
if (winPtr->menu.type == TYPE_NONE) {
470
scroll = textlines(winPtr);
472
scroll = winPtr->menu.lines;
478
Tcl_AppendResult(interp,
479
"internal error: updatepos() called with invalid scroll amount (%d)",
483
if (winPtr->menu.type == TYPE_NONE) {
484
int rows = textlines(winPtr);
487
if (winPtr->text.topline == 0) {
491
winPtr->text.topline -= scroll;
492
if (!scroll || winPtr->text.topline < 0)
493
winPtr->text.topline = 0;
494
if (updatetext(winPtr, interp) == TCL_ERROR)
496
wrefresh(winPtr->win);
498
if (winPtr->text.topline >= winPtr->text.items-rows) {
502
winPtr->text.topline += scroll;
503
if (!scroll || winPtr->text.topline > winPtr->text.items-rows) {
504
winPtr->text.topline = winPtr->text.items-rows;
505
if (winPtr->text.topline < 0)
506
winPtr->text.topline = 0;
508
if (updatetext(winPtr, interp) == TCL_ERROR)
510
wrefresh(winPtr->win);
513
Tcl_AppendResult(interp,
514
"internal error: updatepos() called with invalid dir (%d)",
521
if (winPtr->menu.current == 0) {
525
winPtr->menu.current -= scroll;
526
if (!scroll || winPtr->menu.current < 0)
527
winPtr->menu.current = 0;
529
winPtr->menu.topline -= scroll;
530
if (!scroll || winPtr->menu.topline < 0)
531
winPtr->menu.topline = 0;
533
if (updatemenu(winPtr, interp) == TCL_ERROR)
535
wrefresh(winPtr->menu.win);
537
if (winPtr->menu.current == winPtr->menu.items-1) {
541
winPtr->menu.current += scroll;
542
if (!scroll || winPtr->menu.current > winPtr->menu.items-1)
543
winPtr->menu.current = winPtr->menu.items-1;
545
winPtr->menu.topline += scroll;
546
if (!scroll || winPtr->menu.topline > winPtr->menu.items-winPtr->menu.lines)
547
winPtr->menu.topline = winPtr->menu.items-winPtr->menu.lines;
549
if (updatemenu(winPtr, interp) == TCL_ERROR)
551
wrefresh(winPtr->menu.win);
554
Tcl_AppendResult(interp,
555
"internal error: updatepos() called with invalid dir (%d)",
563
static struct windata *
567
struct windata *winPtr;
570
if ((winPtr= (struct windata *) ckalloc(sizeof(struct windata))) == NULL)
573
getmaxyx(win, winPtr->height, winPtr->width);
574
winPtr->title = (char *) 0;
575
winPtr->border = BORDER_NONE;
578
winPtr->menu.type = TYPE_NONE;
579
winPtr->menu.lines = 0;
580
winPtr->menu.items = 0;
581
winPtr->menu.topline = 0;
582
winPtr->menu.current = 0;
583
winPtr->menu.rsel = 0;
584
winPtr->menu.chkd = (int *) 0;
585
winPtr->menu.win = (WINDOW *) 0;
586
winPtr->menu.data = (char **) 0;
587
winPtr->text.items = 0;
588
winPtr->text.topline = 0;
589
winPtr->text.buffer = (char *) 0;
590
winPtr->text.data = (char **) 0;
592
for (i = 0; i < MAXBUTTONS; i++)
593
winPtr->button[i] = (char *) 0;
598
winconfig(winPtr, interp, argc, argv)
599
struct windata *winPtr;
606
DEBUG5("winconfig(%p, %p, %d, %p)\n", winPtr, interp, argc, argv);
607
for (i = 2; i < argc-1; i += 2) {
608
if (!strcmp(argv[i],"-shadow")) {
610
Tcl_AppendResult(interp, "Not yet implemented", NULL);
612
} else if (!strcmp(argv[i],"-title")) {
613
if (winPtr->border == BORDER_NONE) {
614
Tcl_AppendResult(interp,
615
"Only bordered windows can have titles",
619
if (strlen(argv[i+1]) > winPtr->width-2) {
620
Tcl_AppendResult(interp,
621
"Title too long", NULL);
625
ckfree(winPtr->title);
626
drawbox(winPtr, 0, 0, winPtr->height,
627
winPtr->width, winPtr->border-1,
628
ATTR_ULBORD, ATTR_LRBORD);
630
wmove(winPtr->win, 0, (winPtr->width-strlen(argv[i+1]))/2);
631
wattrset(winPtr->win, ATTR_TITLE);
632
waddstr(winPtr->win, argv[i+1]);
633
} else if (!strcmp(argv[i],"-border")) {
634
if (!strcmp(argv[i+1], "none")) {
635
winPtr->border=BORDER_NONE;
636
} else if (!strcmp(argv[i+1], "blank")) {
637
winPtr->border=BORDER_BLANK;
638
drawbox(winPtr, 0, 0, winPtr->height,
639
winPtr->width, 0, ATTR_ULBORD, ATTR_LRBORD);
640
} else if (!strcmp(argv[i+1], "line")) {
641
winPtr->border=BORDER_LINE;
642
drawbox(winPtr, 0, 0, winPtr->height,
643
winPtr->width, 1, ATTR_ULBORD, ATTR_LRBORD);
645
Tcl_AppendResult(interp, "Invalid border type: ",
650
Tcl_AppendResult(interp, "Invalid option: ",
655
DEBUG1("winconfig() returning okay\n");
660
setmenu(winPtr, interp, argc, argv)
661
struct windata *winPtr;
666
int i, subx, suby, subwid, subht, winy, winx;
667
static char *defaultbuttons[] = {"menu", "buttons", "Okay", "Cancel"};
669
DEBUG5("setmenu(%p, %p, %d, %p)\n", winPtr, interp, argc, argv);
670
if (winPtr->menu.data)
671
ckfree(winPtr->menu.data);
672
if (winPtr->menu.win)
673
delwin(winPtr->menu.win);
674
if (!(winPtr->menu.items = argc-3)) {
675
winPtr->menu.lines = 0;
676
winPtr->menu.topline = 0;
677
winPtr->menu.current = 0;
680
subht = winPtr->menu.lines = atoi(argv[2]);
681
i = winPtr->height - 3 - (winPtr->border? 3: 0);
683
Tcl_AppendResult(interp, "Not enough room for menu window",
687
winPtr->menu.data = (char **) ckalloc(sizeof(char *) * (argc-2));
688
for (i = 0; i<argc-3; i++) {
689
winPtr->menu.data[i] = strdup(argv[i+3]);
691
if (winPtr->menu.type == TYPE_CHECK) {
692
winPtr->menu.chkd = (int *) ckalloc(sizeof(int) * (argc-3));
693
for (i = 0; i<argc-3; i++) {
694
winPtr->menu.chkd[i] = 0;
697
winPtr->menu.data[i] = NULL;
698
if (!winPtr->button[0]) {
699
if (setbuttons(winPtr, interp, 4, defaultbuttons) == TCL_ERROR)
702
getbegyx(winPtr->win, winy, winx);
703
subx = (winPtr->border? 3: 2);
704
suby = winPtr->height - 2 - (winPtr->border? 2: 0) - subht;
705
subwid = winPtr->width - (winPtr->border? 6: 4);
706
if ((winPtr->menu.win = subwin(winPtr->win, subht, subwid,
707
suby+winy, subx+winx)) == NULL) {
708
Tcl_AppendResult(interp, "Unable to create menu subwindow",
712
drawbox(winPtr, suby-1, subx-1, subht+2, subwid+2, 1,
713
ATTR_LRBORD, ATTR_ULBORD);
715
if (updatemenu(winPtr, interp) == TCL_ERROR)
717
if (updatetext(winPtr, interp) == TCL_ERROR)
719
DEBUG1("setmenu() returning okay\n");
724
updatemenu(winPtr, interp)
725
struct windata *winPtr;
728
int i, j, tmp, bottom, wid, ht;
729
DEBUG3("updatemenu(%p, %p)\n", winPtr, interp);
730
bottom = winPtr->menu.topline + winPtr->menu.lines - 1;
731
DEBUG2("bottom = %d\n", bottom);
732
if (winPtr->menu.current < winPtr->menu.topline) {
733
winPtr->menu.topline = winPtr->menu.current;
735
if (winPtr->menu.current > bottom) {
736
winPtr->menu.topline = winPtr->menu.current - winPtr->menu.lines + 1;
738
DEBUG5("menu.current=%d, menu.topline=%d, menu.lines=%d, bottom=%d\n",
739
winPtr->menu.current, winPtr->menu.topline, (int) winPtr->menu.lines, bottom);
740
getmaxyx(winPtr->menu.win, ht, wid);
741
for (i = 0; i < winPtr->menu.lines; i++) {
742
tmp = i+winPtr->menu.topline;
743
if (tmp == winPtr->menu.current)
744
wattrset(winPtr->menu.win, ATTR_SELECT);
746
wattrset(winPtr->menu.win, ATTR_TEXT);
747
wmove(winPtr->menu.win, i, 0);
748
for (j = 0; j < wid; j++)
749
waddch(winPtr->menu.win, ' ');
750
if (tmp < winPtr->menu.items && winPtr->menu.data[tmp]) {
751
wmove(winPtr->menu.win, i, 0);
752
if (winPtr->menu.type == TYPE_RADIO) {
753
if (winPtr->menu.rsel == tmp)
754
waddstr(winPtr->menu.win, "(X) ");
756
waddstr(winPtr->menu.win, "( ) ");
758
if (winPtr->menu.type == TYPE_CHECK) {
759
if (winPtr->menu.chkd[tmp])
760
waddstr(winPtr->menu.win, "[X] ");
762
waddstr(winPtr->menu.win, "[ ] ");
764
waddstr(winPtr->menu.win, winPtr->menu.data[tmp]);
771
setbuttons(winPtr, interp, argc, argv)
772
struct windata *winPtr;
777
int i, needlines=1, needcols=0;
779
DEBUG5("setbuttons(%p, %p, %d, %p)\n", winPtr, interp, argc, argv);
780
if (winPtr->text.items) needlines++;
781
if (winPtr->border) {
782
needlines+= winPtr->text.items? 3:2;
785
for (i = 2; i < argc; i++) {
786
needcols += strlen(argv[i]) + 3;
788
if (winPtr->height < needlines || winPtr->width < needcols) {
789
Tcl_AppendResult(interp, "Window too small", NULL);
792
if (winPtr->border && winPtr->text.items) {
793
wattrset(winPtr->win, ATTR_ULBORD);
794
wmove(winPtr->win, winPtr->height-3, 0);
795
waddch(winPtr->win, ACS_LTEE);
796
for (i = 0; i < winPtr->width-2; i++)
797
waddch(winPtr->win, ACS_HLINE);
798
wattrset(winPtr->win, ATTR_LRBORD);
799
waddch(winPtr->win, ACS_RTEE);
801
for (i = 0; i < MAXBUTTONS; i++) {
802
if (winPtr->button[i])
803
ckfree(winPtr->button);
805
for (i = 0; argv[i+2]; i++)
806
winPtr->button[i] = strdup(argv[i+2]);
807
updatebuttons(winPtr);
808
DEBUG1("setbuttons() returning okay\n");
813
updatebuttons(winPtr)
814
struct windata *winPtr;
816
int i, j, numbuttons, needcols=0, x, y;
818
DEBUG1("updatebuttons(winPtr)\n");
820
getyx(winPtr->win, y, x);
821
for (i = numbuttons = 0; i < MAXBUTTONS; i++) {
822
if (winPtr->button[i])
829
for (i = 0; i < numbuttons; i++) {
830
needcols += strlen(winPtr->button[i]) + 3;
832
wmove(winPtr->win, winPtr->height-2, 1);
833
for (i = 0; i < winPtr->width-2; i++) {
834
waddch(winPtr->win, ' ');
836
wmove(winPtr->win, winPtr->height-2, 1);
837
wattrset(winPtr->win, ATTR_TEXT);
838
for (i = 0; i < numbuttons; i++) {
839
for (j = 0; j < (winPtr->width-needcols)/(numbuttons+1); j++)
840
waddch(winPtr->win, ' ');
841
if (winPtr->butsel == i) {
842
wattrset(winPtr->win, ATTR_SELECT);
843
getyx(winPtr->win, y, x);
845
waddch(winPtr->win, '<');
846
waddstr(winPtr->win, winPtr->button[i]);
847
waddch(winPtr->win, '>');
848
wattrset(winPtr->win, ATTR_TEXT);
850
wmove(winPtr->win, y, x+1);
854
drawbox(winPtr, begrow, begcol, rows, cols, lchar, ulattr, lrattr)
855
struct windata *winPtr;
856
int begrow, begcol, rows, cols, lchar;
857
chtype ulattr, lrattr;
861
#define bchar(ch) (lchar? (ch): ' ')
863
DEBUG9("drawbox(%p, %d, %d, %d, %d, %d, %lx, %lx)\n",
864
winPtr, begrow, begcol, rows, cols, lchar, ulattr, lrattr);
865
wattrset(winPtr->win, ulattr);
866
wmove(winPtr->win, begrow, begcol);
867
waddch(winPtr->win, bchar(ACS_ULCORNER));
868
for (i=0; i<cols-2; i++)
869
waddch(winPtr->win, bchar(ACS_HLINE));
870
wattrset(winPtr->win, lrattr);
871
waddch(winPtr->win, bchar(ACS_URCORNER));
872
for (i=begrow+1; i<begrow+rows-1; i++) {
873
wattrset(winPtr->win, ulattr);
874
mvwaddch(winPtr->win,i,begcol,bchar(ACS_VLINE));
875
wattrset(winPtr->win, lrattr);
876
mvwaddch(winPtr->win,i,begcol+cols-1,bchar(ACS_VLINE));
878
wmove(winPtr->win, begrow+rows-1, begcol);
879
wattrset(winPtr->win, ulattr);
880
waddch(winPtr->win, bchar(ACS_LLCORNER));
881
wattrset(winPtr->win, lrattr);
882
for (i=0; i<cols-2; i++)
883
waddch(winPtr->win, bchar(ACS_HLINE));
884
waddch(winPtr->win, bchar(ACS_LRCORNER));