Linux - POSIX On A PC For FREE ============================================================================== Patch File For dialog(1) ============================================================================== == Introduction ============================================================== This is a patch for the dialog(1) utility, which allows it to work with ncurses 1.8.5, provided you also patch ncurses 1.8.5! There's also some bug fixes, and a new radiolist option. == What You Need ============================================================= You need the following source code : * dialog v0.3 dialog-slack-8-bit.tar.gz, from ftp.cdrom.com, in the /pub/linux/slackware_source/a hierarchy. * ncurses 1.8.5 1.8.5.tar.gz, from ftp.netcom.com, in /pub/zmbenhal/ncurses. If you have Slackware 1.2.x, you should upgrade to ncurses 1.8.5. You also need the following patches : * dialog-0.4-patch This file. Patches dialog v0.3 to produce v0.4 * ncurses-1.8.5-patch Should be found with this file; if you can't find it, mail me, or look in the Linux Software Map. == What They Do ============================================================== * werase() The werase() function in ncurses 1.8.5 is broken; the patch for ncurses fixes it. * support for ncurses 1.8.5 dialog 0.3 doesn't work with ncurses 1.8.5 as-is (textbox scrolling screws up the screen). I don't know whether ncurses is to blame, but dialog 0.4 gets round the problem. * word wrap fixed the word wrap for text output did anything but; this has been fixed. * new colour defaults dialog 0.4 provides a pseudo 3D look, to go with the drop shadow effect. * new option -- radiolist allow for radio buttons, which some users might prefer * key change on textbox pressing 'enter' in a textbox will quit the textbox; although not normal unix behaviour, it's more consistent with the other dialog options == How To Patch ============================================================== Unpack the dialog and ncurses source code. For ncurses, cd /ncurses-1.8.5, and then patch -p1 < /ncurses-1.8.5-patch. For dialog, cd /dialog-slack-8-bit, and then patch -p1 < /dialog-0.4-patch Compile and install ncurses 1.8.5, before compiling dialog v0.4. If you install ncurses to somewhere different from /usr/local/... then you'll need to change dialog's makefile accordingly. ============================================================================== Stuart Herbert - S.Herbert@sheffield.ac.uk ---- patch starts here ---- diff -u --recursive --new-file dialog-slack-8-bit/src/Makefile dialog-0.4/src/Makefile --- dialog-slack-8-bit/src/Makefile Mon Mar 21 02:09:57 1994 +++ dialog-0.4/src/Makefile Wed Jun 8 01:24:20 1994 @@ -1,6 +1,6 @@ INSTALL = install -BINDIR = /usr/local/bin +BINDIR = /bin MANDIR = /usr/local/man MANEXT = 1 @@ -10,12 +10,12 @@ DEFS = -DHAVE_NCURSES -DLOCALE LIBS = -lncurses -CFLAGS = -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer -I/usr/include/ncurses +CFLAGS = -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer -I/usr/local/ncurses LDFLAGS = -s HDRS = dialog.h colors.h rc.h -SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c textbox.c yesno.c -OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o textbox.o yesno.o +SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c radiolist.c textbox.c yesno.c +OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o radiolist.o textbox.o yesno.o all: dialog diff -u --recursive --new-file dialog-slack-8-bit/src/Makefile.linux dialog-0.4/src/Makefile.linux --- dialog-slack-8-bit/src/Makefile.linux Fri Feb 11 20:16:57 1994 +++ dialog-0.4/src/Makefile.linux Wed Jun 8 01:24:31 1994 @@ -1,21 +1,21 @@ INSTALL = install -BINDIR = /usr/local/bin +BINDIR = /bin MANDIR = /usr/local/man MANEXT = 1 CC = gcc CPP = $(CC) -E -DEFS = -DHAVE_NCURSES -DBROKEN_WSCRL +DEFS = -DHAVE_NCURSES -DLOCALE LIBS = -lncurses -CFLAGS = -s -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer +CFLAGS = -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer -I/usr/local/ncurses LDFLAGS = -s HDRS = dialog.h colors.h rc.h -SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c textbox.c yesno.c -OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o textbox.o yesno.o +SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c radiolist.c textbox.c yesno.c +OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o radiolist.o textbox.o yesno.o all: dialog diff -u --recursive --new-file dialog-slack-8-bit/src/checklist.c dialog-0.4/src/checklist.c --- dialog-slack-8-bit/src/checklist.c Fri Feb 11 20:34:19 1994 +++ dialog-0.4/src/checklist.c Tue Jun 7 23:52:26 1994 @@ -66,6 +66,7 @@ waddch(dialog, ACS_LTEE); for (i = 0; i < width-2; i++) waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); waddch(dialog, ACS_RTEE); wmove(dialog, height-2, 1); for (i = 0; i < width-2; i++) @@ -91,7 +92,7 @@ keypad(list, TRUE); /* draw a box around the list items */ - draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_attr, menubox_border_attr); + draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr); check_x = 0; item_x = 0; @@ -165,7 +166,7 @@ /* print the up/down arrows */ wmove(dialog, box_y, box_x + check_x + 5); - wattrset(dialog, scroll ? uarrow_attr : menubox_border_attr); + wattrset(dialog, scroll ? uarrow_attr : menubox_attr); waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE); wmove(dialog, box_y, box_x + check_x + 6); waddch(dialog, scroll ? '(' : ACS_HLINE); diff -u --recursive --new-file dialog-slack-8-bit/src/colors.h dialog-0.4/src/colors.h --- dialog-slack-8-bit/src/colors.h Fri Feb 11 20:16:57 1994 +++ dialog-0.4/src/colors.h Wed Jun 8 02:00:40 1994 @@ -26,24 +26,24 @@ * *_BG = background * *_HL = highlight? */ -#define SCREEN_FG COLOR_WHITE +#define SCREEN_FG COLOR_CYAN #define SCREEN_BG COLOR_BLUE -#define SCREEN_HL FALSE +#define SCREEN_HL TRUE -#define SHADOW_FG COLOR_WHITE +#define SHADOW_FG COLOR_BLACK #define SHADOW_BG COLOR_BLACK -#define SHADOW_HL FALSE +#define SHADOW_HL TRUE #define DIALOG_FG COLOR_BLACK -#define DIALOG_BG COLOR_CYAN +#define DIALOG_BG COLOR_WHITE #define DIALOG_HL FALSE #define TITLE_FG COLOR_YELLOW -#define TITLE_BG COLOR_CYAN +#define TITLE_BG COLOR_WHITE #define TITLE_HL TRUE -#define BORDER_FG COLOR_CYAN -#define BORDER_BG COLOR_CYAN +#define BORDER_FG COLOR_WHITE +#define BORDER_BG COLOR_WHITE #define BORDER_HL TRUE #define BUTTON_ACTIVE_FG COLOR_WHITE @@ -51,95 +51,95 @@ #define BUTTON_ACTIVE_HL TRUE #define BUTTON_INACTIVE_FG COLOR_BLACK -#define BUTTON_INACTIVE_BG COLOR_CYAN +#define BUTTON_INACTIVE_BG COLOR_WHITE #define BUTTON_INACTIVE_HL FALSE #define BUTTON_KEY_ACTIVE_FG COLOR_WHITE #define BUTTON_KEY_ACTIVE_BG COLOR_BLUE #define BUTTON_KEY_ACTIVE_HL TRUE -#define BUTTON_KEY_INACTIVE_FG COLOR_BLACK -#define BUTTON_KEY_INACTIVE_BG COLOR_CYAN +#define BUTTON_KEY_INACTIVE_FG COLOR_RED +#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE #define BUTTON_KEY_INACTIVE_HL FALSE -#define BUTTON_LABEL_ACTIVE_FG COLOR_WHITE +#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW #define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE #define BUTTON_LABEL_ACTIVE_HL TRUE #define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK -#define BUTTON_LABEL_INACTIVE_BG COLOR_CYAN +#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE #define BUTTON_LABEL_INACTIVE_HL TRUE -#define INPUTBOX_FG COLOR_BLUE +#define INPUTBOX_FG COLOR_BLACK #define INPUTBOX_BG COLOR_WHITE #define INPUTBOX_HL FALSE -#define INPUTBOX_BORDER_FG COLOR_CYAN -#define INPUTBOX_BORDER_BG COLOR_CYAN -#define INPUTBOX_BORDER_HL TRUE +#define INPUTBOX_BORDER_FG COLOR_BLACK +#define INPUTBOX_BORDER_BG COLOR_WHITE +#define INPUTBOX_BORDER_HL FALSE -#define SEARCHBOX_FG COLOR_YELLOW +#define SEARCHBOX_FG COLOR_BLACK #define SEARCHBOX_BG COLOR_WHITE -#define SEARCHBOX_HL TRUE +#define SEARCHBOX_HL FALSE -#define SEARCHBOX_TITLE_FG COLOR_WHITE +#define SEARCHBOX_TITLE_FG COLOR_YELLOW #define SEARCHBOX_TITLE_BG COLOR_WHITE #define SEARCHBOX_TITLE_HL TRUE -#define SEARCHBOX_BORDER_FG COLOR_RED +#define SEARCHBOX_BORDER_FG COLOR_WHITE #define SEARCHBOX_BORDER_BG COLOR_WHITE -#define SEARCHBOX_BORDER_HL FALSE +#define SEARCHBOX_BORDER_HL TRUE -#define POSITION_INDICATOR_FG COLOR_RED -#define POSITION_INDICATOR_BG COLOR_CYAN -#define POSITION_INDICATOR_HL FALSE +#define POSITION_INDICATOR_FG COLOR_YELLOW +#define POSITION_INDICATOR_BG COLOR_WHITE +#define POSITION_INDICATOR_HL TRUE #define MENUBOX_FG COLOR_BLACK -#define MENUBOX_BG COLOR_CYAN +#define MENUBOX_BG COLOR_WHITE #define MENUBOX_HL FALSE -#define MENUBOX_BORDER_FG COLOR_CYAN -#define MENUBOX_BORDER_BG COLOR_CYAN +#define MENUBOX_BORDER_FG COLOR_WHITE +#define MENUBOX_BORDER_BG COLOR_WHITE #define MENUBOX_BORDER_HL TRUE #define ITEM_FG COLOR_BLACK -#define ITEM_BG COLOR_CYAN +#define ITEM_BG COLOR_WHITE #define ITEM_HL FALSE #define ITEM_SELECTED_FG COLOR_WHITE #define ITEM_SELECTED_BG COLOR_BLUE -#define ITEM_SELECTED_HL FALSE +#define ITEM_SELECTED_HL TRUE #define TAG_FG COLOR_YELLOW -#define TAG_BG COLOR_CYAN +#define TAG_BG COLOR_WHITE #define TAG_HL TRUE -#define TAG_SELECTED_FG COLOR_WHITE +#define TAG_SELECTED_FG COLOR_YELLOW #define TAG_SELECTED_BG COLOR_BLUE -#define TAG_SELECTED_HL FALSE +#define TAG_SELECTED_HL TRUE #define TAG_KEY_FG COLOR_RED -#define TAG_KEY_BG COLOR_CYAN -#define TAG_KEY_HL FALSE +#define TAG_KEY_BG COLOR_WHITE +#define TAG_KEY_HL TRUE #define TAG_KEY_SELECTED_FG COLOR_RED #define TAG_KEY_SELECTED_BG COLOR_BLUE #define TAG_KEY_SELECTED_HL TRUE #define CHECK_FG COLOR_BLACK -#define CHECK_BG COLOR_CYAN +#define CHECK_BG COLOR_WHITE #define CHECK_HL FALSE #define CHECK_SELECTED_FG COLOR_WHITE -#define CHECK_SELECTED_BG COLOR_CYAN +#define CHECK_SELECTED_BG COLOR_BLUE #define CHECK_SELECTED_HL TRUE #define UARROW_FG COLOR_GREEN -#define UARROW_BG COLOR_CYAN +#define UARROW_BG COLOR_WHITE #define UARROW_HL TRUE #define DARROW_FG COLOR_GREEN -#define DARROW_BG COLOR_CYAN +#define DARROW_BG COLOR_WHITE #define DARROW_HL TRUE /* End of default color definitions */ diff -u --recursive --new-file dialog-slack-8-bit/src/dialog.c dialog-0.4/src/dialog.c --- dialog-slack-8-bit/src/dialog.c Mon Mar 21 02:08:10 1994 +++ dialog-0.4/src/dialog.c Wed Jun 8 01:22:29 1994 @@ -67,6 +67,14 @@ * 13/01/94 - some changes for easier porting to other Unix systems (tested * on Ultrix, SunOS and HPUX) * - Version 0.3 released. + * + * 08/06/94 - Patches by Stuart Herbert - S.Herbert@shef.ac.uk + * Fixed attr_clear and the textbox stuff to work with ncurses 1.8.5 + * Fixed the wordwrap routine - it'll actually wrap properly now + * Added a more 3D look to everything - having your own rc file could + * prove 'interesting' to say the least :-) + * Added radiolist option + * - Version 0.4 released. */ @@ -242,6 +250,23 @@ endwin(); return retval; } + else if (!strcmp(argv[offset+1], "--radiolist")) { + if (argc-offset < 9 || ((argc-offset-6) % 3)) { + Usage(argv[0]); + exit(-1); + } + init_dialog(); + retval = dialog_radiolist(title, argv[offset+2], atoi(argv[offset+3]), + atoi(argv[offset+4]), atoi(argv[offset+5]), + (argc-offset-6)/3, argv+offset + 6); + + if (clear_screen) { /* clear screen before exit */ + attr_clear(stdscr, LINES, COLS, screen_attr); + refresh(); + } + endwin(); + return retval; + } else if (!strcmp(argv[offset+1], "--inputbox")) { if (argc-offset != 5) { Usage(argv[0]); @@ -271,7 +296,8 @@ void Usage(char *name) { fprintf(stderr, "\ -\ndialog version %s, by Savio Lam (lam836@cs.cuhk.hk).\ +\ndialog version 0.3, by Savio Lam (lam836@cs.cuhk.hk).\ +\n patched to version %s by Stuart Herbert (S.Herbert@shef.ac.uk)\ \n\ \n* Display dialog boxes from shell scripts *\ \n\ @@ -287,7 +313,8 @@ \n --inputbox \ \n --textbox \ \n --menu ...\ -\n --checklist ...\n", VERSION, name, name, name); +\n --checklist ...\ +\n --radiolist ...\n", VERSION, name, name, name); } /* End of Usage() */ @@ -350,7 +377,7 @@ { #ifdef HAVE_NCURSES wattrset(win, attr); /* Set window to attribute 'attr' */ - wclear(win); + werase(win); #else int i, j; @@ -381,7 +408,7 @@ if ((strstr(tempstr, "\\n") != NULL) || (strchr(tempstr, '\n') != NULL)) { /* Prompt contains "\n" or '\n' */ word = tempstr; - cur_y = 1; + cur_y = y; wmove(win, cur_y, x); while (1) { tempptr = strstr(word, "\\n"); @@ -414,7 +441,7 @@ waddstr(win, word); } else if (strlen(tempstr) <= width-x*2) { /* If prompt is short */ - wmove(win, 1, (width - strlen(tempstr)) / 2); + wmove(win, y, (width - strlen(tempstr)) / 2); waddstr(win, tempstr); } else { @@ -424,7 +451,7 @@ while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) { if (first) /* First iteration */ first = 0; - if (cur_x+strlen(word) > width-x) { /* wrap around to next line */ + if (cur_x+strlen(word) > width) { /* wrap around to next line */ cur_y++; cur_x = x; } @@ -480,13 +507,17 @@ else if (i == height-1 && !j) waddch(win, border | ACS_LLCORNER); else if (!i && j == width-1) - waddch(win, border | ACS_URCORNER); + waddch(win, box | ACS_URCORNER); else if (i == height-1 && j == width-1) - waddch(win, border | ACS_LRCORNER); - else if (!i || i == height-1) + waddch(win, box | ACS_LRCORNER); + else if (!i) waddch(win, border | ACS_HLINE); - else if (!j || j == width-1) + else if (i == height-1) + waddch(win, box | ACS_HLINE); + else if (!j) waddch(win, border | ACS_VLINE); + else if (j == width-1) + waddch(win, box | ACS_VLINE); else waddch(win, box | ' '); } diff -u --recursive --new-file dialog-slack-8-bit/src/dialog.h dialog-0.4/src/dialog.h --- dialog-slack-8-bit/src/dialog.h Mon Mar 21 02:08:10 1994 +++ dialog-0.4/src/dialog.h Wed Jun 8 01:00:46 1994 @@ -51,7 +51,7 @@ -#define VERSION "0.3" +#define VERSION "0.4" #define ESC 27 #define TAB 9 #define MAX_LEN 2048 @@ -228,5 +228,6 @@ int dialog_textbox(char *title, char *file, int height, int width); int dialog_menu(char *title, char *prompt, int height, int width, int menu_height, int item_no, char **items); int dialog_checklist(char *title, char *prompt, int height, int width, int list_height, int item_no, char **items); +int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, char **items); int dialog_inputbox(char *title, char *prompt, int height, int width); diff -u --recursive --new-file dialog-slack-8-bit/src/inputbox.c dialog-0.4/src/inputbox.c --- dialog-slack-8-bit/src/inputbox.c Mon Mar 21 02:08:10 1994 +++ dialog-0.4/src/inputbox.c Wed Jun 8 00:21:14 1994 @@ -49,6 +49,7 @@ waddch(dialog, ACS_LTEE); for (i = 0; i < width-2; i++) waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); waddch(dialog, ACS_RTEE); wmove(dialog, height-2, 1); for (i = 0; i < width-2; i++) @@ -69,7 +70,7 @@ getyx(dialog, y, x); box_y = y + 2; box_x = (width - box_width)/2; - draw_box(dialog, y+1, box_x-1, 3, box_width+2, inputbox_attr, inputbox_border_attr); + draw_box(dialog, y+1, box_x-1, 3, box_width+2, border_attr, dialog_attr); x = width/2-11; y = height-2; diff -u --recursive --new-file dialog-slack-8-bit/src/menubox.c dialog-0.4/src/menubox.c --- dialog-slack-8-bit/src/menubox.c Sat Feb 12 02:53:53 1994 +++ dialog-0.4/src/menubox.c Tue Jun 7 23:52:47 1994 @@ -56,6 +56,7 @@ waddch(dialog, ACS_LTEE); for (i = 0; i < width-2; i++) waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); waddch(dialog, ACS_RTEE); wmove(dialog, height-2, 1); for (i = 0; i < width-2; i++) @@ -81,7 +82,7 @@ keypad(menu, TRUE); /* draw a box around the menu items */ - draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_attr, menubox_border_attr); + draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_border_attr, menubox_attr); tag_x = 0; item_x = 0; @@ -154,7 +155,7 @@ /* print the up/down arrows */ wmove(dialog, box_y, box_x + tag_x + 1); - wattrset(dialog, scroll ? uarrow_attr : menubox_border_attr); + wattrset(dialog, scroll ? uarrow_attr : menubox_attr); waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE); wmove(dialog, box_y, box_x + tag_x + 2); waddch(dialog, scroll ? '(' : ACS_HLINE); diff -u --recursive --new-file dialog-slack-8-bit/src/msgbox.c dialog-0.4/src/msgbox.c --- dialog-slack-8-bit/src/msgbox.c Fri Feb 11 20:16:57 1994 +++ dialog-0.4/src/msgbox.c Tue Jun 7 23:54:49 1994 @@ -52,7 +52,7 @@ waddch(dialog, ' '); } wattrset(dialog, dialog_attr); - print_autowrap(dialog, prompt, width, 1, 3); + print_autowrap(dialog, prompt, width-2, 1, 2); if (pause) { wattrset(dialog, border_attr); @@ -60,6 +60,7 @@ waddch(dialog, ACS_LTEE); for (i = 0; i < width-2; i++) waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); waddch(dialog, ACS_RTEE); wmove(dialog, height-2, 1); for (i = 0; i < width-2; i++) diff -u --recursive --new-file dialog-slack-8-bit/src/radiolist.c dialog-0.4/src/radiolist.c --- dialog-slack-8-bit/src/radiolist.c Wed Jun 8 01:07:36 1994 +++ dialog-0.4/src/radiolist.c Wed Jun 8 02:00:06 1994 @@ -0,0 +1,352 @@ +/* + * radiolist.c -- implements the radiolist box + * + * AUTHOR: Stuart Herbert - S.Herbert@sheffield.ac.uk + * (from checklist.c by Savio Lam (lam836@cs.cuhk.hk)) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "dialog.h" + + +static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected); + + +static int list_width, check_x, item_x; + + +/* + * Display a dialog box with a list of options that can be turned on or off + */ +int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, char **items) +{ + int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0, + scroll = 0, max_choice, *status; + WINDOW *dialog, *list; + + /* Allocate space for storing item on/off status */ + if ((status = malloc(sizeof(int)*item_no)) == NULL) { + endwin(); + fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n"); + exit(-1); + } + /* Initializes status */ + for (i = 0; i < item_no; i++) + status[i] = !strcasecmp(items[i*3 + 2], "on"); + + max_choice = MIN(list_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width)/2; + y = (LINES - height)/2; + +#ifdef HAVE_NCURSES + if (use_shadow) + draw_shadow(stdscr, y, x, height, width); +#endif + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset(dialog, border_attr); + wmove(dialog, height-3, 0); + waddch(dialog, ACS_LTEE); + for (i = 0; i < width-2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); + waddch(dialog, ACS_RTEE); + wmove(dialog, height-2, 1); + for (i = 0; i < width-2; i++) + waddch(dialog, ' '); + + if (title != NULL) { + wattrset(dialog, title_attr); + wmove(dialog, 0, (width - strlen(title))/2 - 1); + waddch(dialog, ' '); + waddstr(dialog, title); + waddch(dialog, ' '); + } + wattrset(dialog, dialog_attr); + print_autowrap(dialog, prompt, width, 1, 3); + + list_width = width-6; + getyx(dialog, cur_y, cur_x); + box_y = cur_y + 1; + box_x = (width - list_width)/2 - 1; + + /* create new window for the list */ + list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1); + keypad(list, TRUE); + + /* draw a box around the list items */ + draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr); + + check_x = 0; + item_x = 0; + /* Find length of longest item in order to center radiolist */ + for (i = 0; i < item_no; i++) { + check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6); + item_x = MAX(item_x, strlen(items[i*3])); + } + check_x = (list_width - check_x) / 2; + item_x = check_x + item_x + 6; + + /* Print the list */ + for (i = 0; i < max_choice; i++) + print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice); + wnoutrefresh(list); + + if (list_height < item_no) { + wattrset(dialog, darrow_attr); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 5); + waddch(dialog, ACS_DARROW); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 6); + waddstr(dialog, "(+)"); + } + + x = width/2-11; + y = height-2; + print_button(dialog, "Cancel", y, x+14, FALSE); + print_button(dialog, " OK ", y, x, TRUE); + wrefresh(dialog); + + while (key != ESC) { + key = wgetch(dialog); + /* Check if key pressed matches first character of any item tag in list */ + for (i = 0; i < max_choice; i++) + if (toupper(key) == toupper(items[(scroll+i)*3][0])) + break; + + if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || + key == KEY_UP || key == KEY_DOWN || key == ' ' || + key == '+' || key == '-' ) { + if (key >= '1' && key <= MIN('9', '0'+max_choice)) + i = key - '1'; + else if (key == KEY_UP || key == '-') { + if (!choice) { + if (scroll) { +#ifdef BROKEN_WSCRL + /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation + violation when scrolling windows of height = 4, so scrolling is not + used for now */ + scroll--; + getyx(dialog, cur_y, cur_x); /* Save cursor position */ + /* Reprint list to scroll down */ + for (i = 0; i < max_choice; i++) + print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice); + +#else + + /* Scroll list down */ + getyx(dialog, cur_y, cur_x); /* Save cursor position */ + if (list_height > 1) { + /* De-highlight current first item before scrolling down */ + print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE); + scrollok(list, TRUE); + wscrl(list, -1); + scrollok(list, FALSE); + } + scroll--; + print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE); +#endif + wnoutrefresh(list); + + /* print the up/down arrows */ + wmove(dialog, box_y, box_x + check_x + 5); + wattrset(dialog, scroll ? uarrow_attr : menubox_attr); + waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE); + wmove(dialog, box_y, box_x + check_x + 6); + waddch(dialog, scroll ? '(' : ACS_HLINE); + wmove(dialog, box_y, box_x + check_x + 7); + waddch(dialog, scroll ? '-' : ACS_HLINE); + wmove(dialog, box_y, box_x + check_x + 8); + waddch(dialog, scroll ? ')' : ACS_HLINE); + wattrset(dialog, darrow_attr); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 5); + waddch(dialog, ACS_DARROW); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 6); + waddch(dialog, '('); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 7); + waddch(dialog, '+'); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 8); + waddch(dialog, ')'); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + } + continue; /* wait for another key press */ + } + else + i = choice - 1; + } + else if (key == KEY_DOWN || key == '+') { + if (choice == max_choice - 1) { + if (scroll+choice < item_no-1) { +#ifdef BROKEN_WSCRL + /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation + violation when scrolling windows of height = 4, so scrolling is not + used for now */ + scroll++; + getyx(dialog, cur_y, cur_x); /* Save cursor position */ + /* Reprint list to scroll up */ + for (i = 0; i < max_choice; i++) + print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice); + +#else + + /* Scroll list up */ + getyx(dialog, cur_y, cur_x); /* Save cursor position */ + if (list_height > 1) { + /* De-highlight current last item before scrolling up */ + print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, FALSE); + scrollok(list, TRUE); + scroll(list); + scrollok(list, FALSE); + } + scroll++; + print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, TRUE); +#endif + wnoutrefresh(list); + + /* print the up/down arrows */ + wattrset(dialog, uarrow_attr); + wmove(dialog, box_y, box_x + check_x + 5); + waddch(dialog, ACS_UARROW); + wmove(dialog, box_y, box_x + check_x + 6); + waddstr(dialog, "(-)"); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 5); + wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr); + waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 6); + waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 7); + waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE); + wmove(dialog, box_y + list_height + 1, box_x + check_x + 8); + waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + } + continue; /* wait for another key press */ + } + else + i = choice + 1; + } + else if (key == ' ') { /* Toggle item status */ + if (!status[scroll+choice]) + { + for (i=0; i