xref: /freebsd/contrib/dialog/checklist.c (revision 197186496661d8f63639b5b27b33851f727d4da7)
14c8945a0SNathan Whitehorn /*
2*19718649SNathan Whitehorn  *  $Id: checklist.c,v 1.127 2011/06/29 23:04:09 tom Exp $
34c8945a0SNathan Whitehorn  *
44c8945a0SNathan Whitehorn  *  checklist.c -- implements the checklist box
54c8945a0SNathan Whitehorn  *
6*19718649SNathan Whitehorn  *  Copyright 2000-2010,2011	Thomas E. Dickey
74c8945a0SNathan Whitehorn  *
84c8945a0SNathan Whitehorn  *  This program is free software; you can redistribute it and/or modify
94c8945a0SNathan Whitehorn  *  it under the terms of the GNU Lesser General Public License, version 2.1
104c8945a0SNathan Whitehorn  *  as published by the Free Software Foundation.
114c8945a0SNathan Whitehorn  *
124c8945a0SNathan Whitehorn  *  This program is distributed in the hope that it will be useful, but
134c8945a0SNathan Whitehorn  *  WITHOUT ANY WARRANTY; without even the implied warranty of
144c8945a0SNathan Whitehorn  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
154c8945a0SNathan Whitehorn  *  Lesser General Public License for more details.
164c8945a0SNathan Whitehorn  *
174c8945a0SNathan Whitehorn  *  You should have received a copy of the GNU Lesser General Public
184c8945a0SNathan Whitehorn  *  License along with this program; if not, write to
194c8945a0SNathan Whitehorn  *	Free Software Foundation, Inc.
204c8945a0SNathan Whitehorn  *	51 Franklin St., Fifth Floor
214c8945a0SNathan Whitehorn  *	Boston, MA 02110, USA.
224c8945a0SNathan Whitehorn  *
234c8945a0SNathan Whitehorn  *  An earlier version of this program lists as authors:
244c8945a0SNathan Whitehorn  *	Savio Lam (lam836@cs.cuhk.hk)
254c8945a0SNathan Whitehorn  *	Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
264c8945a0SNathan Whitehorn  *	Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
274c8945a0SNathan Whitehorn  */
284c8945a0SNathan Whitehorn 
294c8945a0SNathan Whitehorn #include <dialog.h>
304c8945a0SNathan Whitehorn #include <dlg_keys.h>
314c8945a0SNathan Whitehorn 
324c8945a0SNathan Whitehorn static int list_width, check_x, item_x, checkflag;
334c8945a0SNathan Whitehorn 
344c8945a0SNathan Whitehorn #define MIN_HIGH  (1 + (5 * MARGIN))
354c8945a0SNathan Whitehorn 
364c8945a0SNathan Whitehorn #define LLEN(n) ((n) * CHECKBOX_TAGS)
374c8945a0SNathan Whitehorn #define ItemData(i)    &items[LLEN(i)]
384c8945a0SNathan Whitehorn #define ItemName(i)    items[LLEN(i)]
394c8945a0SNathan Whitehorn #define ItemText(i)    items[LLEN(i) + 1]
404c8945a0SNathan Whitehorn #define ItemStatus(i)  items[LLEN(i) + 2]
414c8945a0SNathan Whitehorn #define ItemHelp(i)    items[LLEN(i) + 3]
424c8945a0SNathan Whitehorn 
434c8945a0SNathan Whitehorn static void
444c8945a0SNathan Whitehorn print_arrows(WINDOW *win,
454c8945a0SNathan Whitehorn 	     int box_x,
464c8945a0SNathan Whitehorn 	     int box_y,
474c8945a0SNathan Whitehorn 	     int scrollamt,
484c8945a0SNathan Whitehorn 	     int choice,
494c8945a0SNathan Whitehorn 	     int item_no,
504c8945a0SNathan Whitehorn 	     int list_height)
514c8945a0SNathan Whitehorn {
524c8945a0SNathan Whitehorn     dlg_draw_scrollbar(win,
537a1c0d96SNathan Whitehorn 		       (long) (scrollamt),
547a1c0d96SNathan Whitehorn 		       (long) (scrollamt),
557a1c0d96SNathan Whitehorn 		       (long) (scrollamt + choice),
567a1c0d96SNathan Whitehorn 		       (long) (item_no),
574c8945a0SNathan Whitehorn 		       box_x + check_x,
584c8945a0SNathan Whitehorn 		       box_x + list_width,
594c8945a0SNathan Whitehorn 		       box_y,
604c8945a0SNathan Whitehorn 		       box_y + list_height + 1,
61*19718649SNathan Whitehorn 		       menubox_attr,
624c8945a0SNathan Whitehorn 		       menubox_border_attr);
634c8945a0SNathan Whitehorn }
644c8945a0SNathan Whitehorn 
654c8945a0SNathan Whitehorn /*
664c8945a0SNathan Whitehorn  * Print list item.  The 'selected' parameter is true if 'choice' is the
674c8945a0SNathan Whitehorn  * current item.  That one is colored differently from the other items.
684c8945a0SNathan Whitehorn  */
694c8945a0SNathan Whitehorn static void
704c8945a0SNathan Whitehorn print_item(WINDOW *win,
714c8945a0SNathan Whitehorn 	   DIALOG_LISTITEM * item,
724c8945a0SNathan Whitehorn 	   const char *states,
734c8945a0SNathan Whitehorn 	   int choice,
744c8945a0SNathan Whitehorn 	   int selected)
754c8945a0SNathan Whitehorn {
767a1c0d96SNathan Whitehorn     chtype save = dlg_get_attrs(win);
774c8945a0SNathan Whitehorn     int i;
784c8945a0SNathan Whitehorn     chtype attr = A_NORMAL;
794c8945a0SNathan Whitehorn     const int *cols;
804c8945a0SNathan Whitehorn     const int *indx;
814c8945a0SNathan Whitehorn     int limit;
824c8945a0SNathan Whitehorn 
834c8945a0SNathan Whitehorn     /* Clear 'residue' of last item */
84*19718649SNathan Whitehorn     wattrset(win, menubox_attr);
854c8945a0SNathan Whitehorn     (void) wmove(win, choice, 0);
864c8945a0SNathan Whitehorn     for (i = 0; i < list_width; i++)
874c8945a0SNathan Whitehorn 	(void) waddch(win, ' ');
884c8945a0SNathan Whitehorn 
894c8945a0SNathan Whitehorn     (void) wmove(win, choice, check_x);
90*19718649SNathan Whitehorn     wattrset(win, selected ? check_selected_attr : check_attr);
914c8945a0SNathan Whitehorn     (void) wprintw(win,
924c8945a0SNathan Whitehorn 		   (checkflag == FLAG_CHECK) ? "[%c]" : "(%c)",
934c8945a0SNathan Whitehorn 		   states[item->state]);
94*19718649SNathan Whitehorn     wattrset(win, menubox_attr);
954c8945a0SNathan Whitehorn     (void) waddch(win, ' ');
964c8945a0SNathan Whitehorn 
974c8945a0SNathan Whitehorn     if (strlen(item->name) != 0) {
984c8945a0SNathan Whitehorn 
994c8945a0SNathan Whitehorn 	indx = dlg_index_wchars(item->name);
1004c8945a0SNathan Whitehorn 
101*19718649SNathan Whitehorn 	wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
1024c8945a0SNathan Whitehorn 	(void) waddnstr(win, item->name, indx[1]);
1034c8945a0SNathan Whitehorn 
1044c8945a0SNathan Whitehorn 	if ((int) strlen(item->name) > indx[1]) {
1054c8945a0SNathan Whitehorn 	    limit = dlg_limit_columns(item->name, (item_x - check_x - 6), 1);
1064c8945a0SNathan Whitehorn 	    if (limit > 1) {
107*19718649SNathan Whitehorn 		wattrset(win, selected ? tag_selected_attr : tag_attr);
1084c8945a0SNathan Whitehorn 		(void) waddnstr(win,
1094c8945a0SNathan Whitehorn 				item->name + indx[1],
1104c8945a0SNathan Whitehorn 				indx[limit] - indx[1]);
1114c8945a0SNathan Whitehorn 	    }
1124c8945a0SNathan Whitehorn 	}
1134c8945a0SNathan Whitehorn     }
1144c8945a0SNathan Whitehorn 
1154c8945a0SNathan Whitehorn     if (strlen(item->text) != 0) {
1164c8945a0SNathan Whitehorn 	cols = dlg_index_columns(item->text);
1174c8945a0SNathan Whitehorn 	limit = dlg_limit_columns(item->text, (getmaxx(win) - item_x + 1), 0);
1184c8945a0SNathan Whitehorn 
1194c8945a0SNathan Whitehorn 	if (limit > 0) {
1204c8945a0SNathan Whitehorn 	    (void) wmove(win, choice, item_x);
121*19718649SNathan Whitehorn 	    wattrset(win, selected ? item_selected_attr : item_attr);
1224c8945a0SNathan Whitehorn 	    dlg_print_text(win, item->text, cols[limit], &attr);
1234c8945a0SNathan Whitehorn 	}
1244c8945a0SNathan Whitehorn     }
1254c8945a0SNathan Whitehorn 
1264c8945a0SNathan Whitehorn     if (selected) {
1274c8945a0SNathan Whitehorn 	dlg_item_help(item->help);
1284c8945a0SNathan Whitehorn     }
129*19718649SNathan Whitehorn     wattrset(win, save);
1304c8945a0SNathan Whitehorn }
1314c8945a0SNathan Whitehorn 
1324c8945a0SNathan Whitehorn /*
1334c8945a0SNathan Whitehorn  * This is an alternate interface to 'checklist' which allows the application
1344c8945a0SNathan Whitehorn  * to read the list item states back directly without putting them in the
1354c8945a0SNathan Whitehorn  * output buffer.  It also provides for more than two states over which the
1364c8945a0SNathan Whitehorn  * check/radio box can display.
1374c8945a0SNathan Whitehorn  */
1384c8945a0SNathan Whitehorn int
1394c8945a0SNathan Whitehorn dlg_checklist(const char *title,
1404c8945a0SNathan Whitehorn 	      const char *cprompt,
1414c8945a0SNathan Whitehorn 	      int height,
1424c8945a0SNathan Whitehorn 	      int width,
1434c8945a0SNathan Whitehorn 	      int list_height,
1444c8945a0SNathan Whitehorn 	      int item_no,
1454c8945a0SNathan Whitehorn 	      DIALOG_LISTITEM * items,
1464c8945a0SNathan Whitehorn 	      const char *states,
1474c8945a0SNathan Whitehorn 	      int flag,
1484c8945a0SNathan Whitehorn 	      int *current_item)
1494c8945a0SNathan Whitehorn {
1504c8945a0SNathan Whitehorn     /* *INDENT-OFF* */
1514c8945a0SNathan Whitehorn     static DLG_KEYS_BINDING binding[] = {
152682c9e0fSNathan Whitehorn 	HELPKEY_BINDINGS,
1534c8945a0SNathan Whitehorn 	ENTERKEY_BINDINGS,
1544c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
1554c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
1564c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
1574c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
1584c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
1594c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_LAST,	KEY_END ),
1604c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_LAST,	KEY_LL ),
1614c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_NEXT,	'+' ),
1624c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_NEXT,	KEY_DOWN ),
1634c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  CHR_NEXT ),
1644c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_PREV,	'-' ),
1654c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_PREV,	KEY_UP ),
1664c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_ITEM_PREV,  CHR_PREVIOUS ),
1674c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_PAGE_NEXT,	KEY_NPAGE ),
1684c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_PAGE_NEXT,	DLGK_MOUSE(KEY_NPAGE) ),
1694c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_PAGE_PREV,	KEY_PPAGE ),
1704c8945a0SNathan Whitehorn 	DLG_KEYS_DATA( DLGK_PAGE_PREV,	DLGK_MOUSE(KEY_PPAGE) ),
1714c8945a0SNathan Whitehorn 	END_KEYS_BINDING
1724c8945a0SNathan Whitehorn     };
1734c8945a0SNathan Whitehorn     /* *INDENT-ON* */
1744c8945a0SNathan Whitehorn 
1754c8945a0SNathan Whitehorn #ifdef KEY_RESIZE
1764c8945a0SNathan Whitehorn     int old_height = height;
1774c8945a0SNathan Whitehorn     int old_width = width;
1784c8945a0SNathan Whitehorn #endif
1794c8945a0SNathan Whitehorn     int i, j, key2, found, x, y, cur_x, cur_y, box_x, box_y;
1804c8945a0SNathan Whitehorn     int key = 0, fkey;
181*19718649SNathan Whitehorn     int button = dialog_state.visit_items ? -1 : dlg_defaultno_button();
1824c8945a0SNathan Whitehorn     int choice = dlg_default_listitem(items);
1834c8945a0SNathan Whitehorn     int scrollamt = 0;
1844c8945a0SNathan Whitehorn     int max_choice;
1854c8945a0SNathan Whitehorn     int was_mouse;
1864c8945a0SNathan Whitehorn     int use_height;
1874c8945a0SNathan Whitehorn     int use_width, name_width, text_width;
1884c8945a0SNathan Whitehorn     int result = DLG_EXIT_UNKNOWN;
1894c8945a0SNathan Whitehorn     int num_states;
1904c8945a0SNathan Whitehorn     WINDOW *dialog, *list;
1914c8945a0SNathan Whitehorn     char *prompt = dlg_strclone(cprompt);
1924c8945a0SNathan Whitehorn     const char **buttons = dlg_ok_labels();
1934c8945a0SNathan Whitehorn 
1944c8945a0SNathan Whitehorn     dlg_does_output();
1954c8945a0SNathan Whitehorn     dlg_tab_correct_str(prompt);
1964c8945a0SNathan Whitehorn 
197682c9e0fSNathan Whitehorn     /*
198682c9e0fSNathan Whitehorn      * If this is a radiobutton list, ensure that no more than one item is
199682c9e0fSNathan Whitehorn      * selected initially.  Allow none to be selected, since some users may
200682c9e0fSNathan Whitehorn      * wish to provide this flavor.
201682c9e0fSNathan Whitehorn      */
202682c9e0fSNathan Whitehorn     if (flag == FLAG_RADIO) {
203682c9e0fSNathan Whitehorn 	bool first = TRUE;
204682c9e0fSNathan Whitehorn 
205682c9e0fSNathan Whitehorn 	for (i = 0; i < item_no; i++) {
206682c9e0fSNathan Whitehorn 	    if (items[i].state) {
207682c9e0fSNathan Whitehorn 		if (first) {
208682c9e0fSNathan Whitehorn 		    first = FALSE;
209682c9e0fSNathan Whitehorn 		} else {
210682c9e0fSNathan Whitehorn 		    items[i].state = 0;
211682c9e0fSNathan Whitehorn 		}
212682c9e0fSNathan Whitehorn 	    }
213682c9e0fSNathan Whitehorn 	}
214682c9e0fSNathan Whitehorn     }
2154c8945a0SNathan Whitehorn #ifdef KEY_RESIZE
2164c8945a0SNathan Whitehorn   retry:
2174c8945a0SNathan Whitehorn #endif
2184c8945a0SNathan Whitehorn 
2194c8945a0SNathan Whitehorn     use_height = list_height;
2202a664c03SNathan Whitehorn     if (use_height == 0) {
221*19718649SNathan Whitehorn 	use_width = dlg_calc_list_width(item_no, items) + 10;
2224c8945a0SNathan Whitehorn 	/* calculate height without items (4) */
223*19718649SNathan Whitehorn 	dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, MAX(26, use_width));
2244c8945a0SNathan Whitehorn 	dlg_calc_listh(&height, &use_height, item_no);
2254c8945a0SNathan Whitehorn     } else {
226*19718649SNathan Whitehorn 	dlg_auto_size(title, prompt, &height, &width, MIN_HIGH + use_height, 26);
2274c8945a0SNathan Whitehorn     }
2284c8945a0SNathan Whitehorn     dlg_button_layout(buttons, &width);
2294c8945a0SNathan Whitehorn     dlg_print_size(height, width);
2304c8945a0SNathan Whitehorn     dlg_ctl_size(height, width);
2314c8945a0SNathan Whitehorn 
2324c8945a0SNathan Whitehorn     /* we need at least two states */
2334c8945a0SNathan Whitehorn     if (states == 0 || strlen(states) < 2)
2344c8945a0SNathan Whitehorn 	states = " *";
2354c8945a0SNathan Whitehorn     num_states = (int) strlen(states);
2364c8945a0SNathan Whitehorn 
2374c8945a0SNathan Whitehorn     checkflag = flag;
2384c8945a0SNathan Whitehorn 
2394c8945a0SNathan Whitehorn     x = dlg_box_x_ordinate(width);
2404c8945a0SNathan Whitehorn     y = dlg_box_y_ordinate(height);
2414c8945a0SNathan Whitehorn 
2424c8945a0SNathan Whitehorn     dialog = dlg_new_window(height, width, y, x);
243*19718649SNathan Whitehorn     dlg_register_window(dialog, "checklist", binding);
244*19718649SNathan Whitehorn     dlg_register_buttons(dialog, "checklist", buttons);
2454c8945a0SNathan Whitehorn 
2464c8945a0SNathan Whitehorn     dlg_mouse_setbase(x, y);
2474c8945a0SNathan Whitehorn 
248*19718649SNathan Whitehorn     dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
249*19718649SNathan Whitehorn     dlg_draw_bottom_box(dialog);
2504c8945a0SNathan Whitehorn     dlg_draw_title(dialog, title);
2514c8945a0SNathan Whitehorn 
252*19718649SNathan Whitehorn     wattrset(dialog, dialog_attr);
2534c8945a0SNathan Whitehorn     dlg_print_autowrap(dialog, prompt, height, width);
2544c8945a0SNathan Whitehorn 
2554c8945a0SNathan Whitehorn     list_width = width - 6;
2564c8945a0SNathan Whitehorn     getyx(dialog, cur_y, cur_x);
2574c8945a0SNathan Whitehorn     box_y = cur_y + 1;
2584c8945a0SNathan Whitehorn     box_x = (width - list_width) / 2 - 1;
2594c8945a0SNathan Whitehorn 
2604c8945a0SNathan Whitehorn     /*
2614c8945a0SNathan Whitehorn      * After displaying the prompt, we know how much space we really have.
2624c8945a0SNathan Whitehorn      * Limit the list to avoid overwriting the ok-button.
2634c8945a0SNathan Whitehorn      */
2644c8945a0SNathan Whitehorn     if (use_height + MIN_HIGH > height - cur_y)
2654c8945a0SNathan Whitehorn 	use_height = height - MIN_HIGH - cur_y;
2664c8945a0SNathan Whitehorn     if (use_height <= 0)
2674c8945a0SNathan Whitehorn 	use_height = 1;
2684c8945a0SNathan Whitehorn 
2694c8945a0SNathan Whitehorn     max_choice = MIN(use_height, item_no);
2704c8945a0SNathan Whitehorn 
2714c8945a0SNathan Whitehorn     /* create new window for the list */
2724c8945a0SNathan Whitehorn     list = dlg_sub_window(dialog, use_height, list_width,
2734c8945a0SNathan Whitehorn 			  y + box_y + 1, x + box_x + 1);
2744c8945a0SNathan Whitehorn 
2754c8945a0SNathan Whitehorn     /* draw a box around the list items */
2764c8945a0SNathan Whitehorn     dlg_draw_box(dialog, box_y, box_x,
2774c8945a0SNathan Whitehorn 		 use_height + 2 * MARGIN,
2784c8945a0SNathan Whitehorn 		 list_width + 2 * MARGIN,
279*19718649SNathan Whitehorn 		 menubox_border_attr, menubox_attr);
2804c8945a0SNathan Whitehorn 
2814c8945a0SNathan Whitehorn     text_width = 0;
2824c8945a0SNathan Whitehorn     name_width = 0;
2834c8945a0SNathan Whitehorn     /* Find length of longest item to center checklist */
2844c8945a0SNathan Whitehorn     for (i = 0; i < item_no; i++) {
2854c8945a0SNathan Whitehorn 	text_width = MAX(text_width, dlg_count_columns(items[i].text));
2864c8945a0SNathan Whitehorn 	name_width = MAX(name_width, dlg_count_columns(items[i].name));
2874c8945a0SNathan Whitehorn     }
2884c8945a0SNathan Whitehorn 
2894c8945a0SNathan Whitehorn     /* If the name+text is wider than the list is allowed, then truncate
2904c8945a0SNathan Whitehorn      * one or both of them.  If the name is no wider than 1/4 of the list,
2914c8945a0SNathan Whitehorn      * leave it intact.
2924c8945a0SNathan Whitehorn      */
2934c8945a0SNathan Whitehorn     use_width = (list_width - 6);
2944c8945a0SNathan Whitehorn     if (text_width + name_width > use_width) {
2954c8945a0SNathan Whitehorn 	int need = (int) (0.25 * use_width);
2964c8945a0SNathan Whitehorn 	if (name_width > need) {
2974c8945a0SNathan Whitehorn 	    int want = (int) (use_width * ((double) name_width) /
2984c8945a0SNathan Whitehorn 			      (text_width + name_width));
2994c8945a0SNathan Whitehorn 	    name_width = (want > need) ? want : need;
3004c8945a0SNathan Whitehorn 	}
3014c8945a0SNathan Whitehorn 	text_width = use_width - name_width;
3024c8945a0SNathan Whitehorn     }
3034c8945a0SNathan Whitehorn 
3044c8945a0SNathan Whitehorn     check_x = (use_width - (text_width + name_width)) / 2;
3054c8945a0SNathan Whitehorn     item_x = name_width + check_x + 6;
3064c8945a0SNathan Whitehorn 
3074c8945a0SNathan Whitehorn     /* ensure we are scrolled to show the current choice */
3084c8945a0SNathan Whitehorn     if (choice >= (max_choice + scrollamt)) {
3094c8945a0SNathan Whitehorn 	scrollamt = choice - max_choice + 1;
3104c8945a0SNathan Whitehorn 	choice = max_choice - 1;
3114c8945a0SNathan Whitehorn     }
3124c8945a0SNathan Whitehorn     /* Print the list */
313682c9e0fSNathan Whitehorn     for (i = 0; i < max_choice; i++) {
3144c8945a0SNathan Whitehorn 	print_item(list,
3154c8945a0SNathan Whitehorn 		   &items[i + scrollamt],
3164c8945a0SNathan Whitehorn 		   states,
3174c8945a0SNathan Whitehorn 		   i, i == choice);
318682c9e0fSNathan Whitehorn     }
3194c8945a0SNathan Whitehorn     (void) wnoutrefresh(list);
3204c8945a0SNathan Whitehorn 
3214c8945a0SNathan Whitehorn     /* register the new window, along with its borders */
3224c8945a0SNathan Whitehorn     dlg_mouse_mkbigregion(box_y + 1, box_x, use_height, list_width + 2,
3234c8945a0SNathan Whitehorn 			  KEY_MAX, 1, 1, 1 /* by lines */ );
3244c8945a0SNathan Whitehorn 
3254c8945a0SNathan Whitehorn     print_arrows(dialog,
3264c8945a0SNathan Whitehorn 		 box_x, box_y,
3274c8945a0SNathan Whitehorn 		 scrollamt, max_choice, item_no, use_height);
3284c8945a0SNathan Whitehorn 
3294c8945a0SNathan Whitehorn     dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
3304c8945a0SNathan Whitehorn 
3314c8945a0SNathan Whitehorn     while (result == DLG_EXIT_UNKNOWN) {
3324c8945a0SNathan Whitehorn 	if (button < 0)		/* --visit-items */
3334c8945a0SNathan Whitehorn 	    wmove(dialog, box_y + choice + 1, box_x + check_x + 2);
3344c8945a0SNathan Whitehorn 
3354c8945a0SNathan Whitehorn 	key = dlg_mouse_wgetch(dialog, &fkey);
3364c8945a0SNathan Whitehorn 	if (dlg_result_key(key, fkey, &result))
3374c8945a0SNathan Whitehorn 	    break;
3384c8945a0SNathan Whitehorn 
3394c8945a0SNathan Whitehorn 	was_mouse = (fkey && is_DLGK_MOUSE(key));
3404c8945a0SNathan Whitehorn 	if (was_mouse)
3414c8945a0SNathan Whitehorn 	    key -= M_EVENT;
3424c8945a0SNathan Whitehorn 
3434c8945a0SNathan Whitehorn 	if (was_mouse && (key >= KEY_MAX)) {
3444c8945a0SNathan Whitehorn 	    getyx(dialog, cur_y, cur_x);
3454c8945a0SNathan Whitehorn 	    i = (key - KEY_MAX);
3464c8945a0SNathan Whitehorn 	    if (i < max_choice) {
3474c8945a0SNathan Whitehorn 		/* De-highlight current item */
3484c8945a0SNathan Whitehorn 		print_item(list,
3494c8945a0SNathan Whitehorn 			   &items[scrollamt + choice],
3504c8945a0SNathan Whitehorn 			   states,
3514c8945a0SNathan Whitehorn 			   choice, FALSE);
3524c8945a0SNathan Whitehorn 		/* Highlight new item */
3534c8945a0SNathan Whitehorn 		choice = (key - KEY_MAX);
3544c8945a0SNathan Whitehorn 		print_item(list,
3554c8945a0SNathan Whitehorn 			   &items[scrollamt + choice],
3564c8945a0SNathan Whitehorn 			   states,
3574c8945a0SNathan Whitehorn 			   choice, TRUE);
3584c8945a0SNathan Whitehorn 		(void) wnoutrefresh(list);
3594c8945a0SNathan Whitehorn 		(void) wmove(dialog, cur_y, cur_x);
3604c8945a0SNathan Whitehorn 
3614c8945a0SNathan Whitehorn 		key = ' ';	/* force the selected item to toggle */
3624c8945a0SNathan Whitehorn 	    } else {
3634c8945a0SNathan Whitehorn 		beep();
3644c8945a0SNathan Whitehorn 		continue;
3654c8945a0SNathan Whitehorn 	    }
3664c8945a0SNathan Whitehorn 	    fkey = FALSE;
3674c8945a0SNathan Whitehorn 	} else if (was_mouse && key >= KEY_MIN) {
3684c8945a0SNathan Whitehorn 	    key = dlg_lookup_key(dialog, key, &fkey);
3694c8945a0SNathan Whitehorn 	}
3704c8945a0SNathan Whitehorn 
3714c8945a0SNathan Whitehorn 	/*
3724c8945a0SNathan Whitehorn 	 * A space toggles the item status.  We handle either a checklist
3734c8945a0SNathan Whitehorn 	 * (any number of items can be selected) or radio list (zero or one
3744c8945a0SNathan Whitehorn 	 * items can be selected).
3754c8945a0SNathan Whitehorn 	 */
3764c8945a0SNathan Whitehorn 	if (key == ' ') {
3774c8945a0SNathan Whitehorn 	    int current = scrollamt + choice;
3784c8945a0SNathan Whitehorn 	    int next = items[current].state + 1;
3794c8945a0SNathan Whitehorn 
3804c8945a0SNathan Whitehorn 	    if (next >= num_states)
3814c8945a0SNathan Whitehorn 		next = 0;
3824c8945a0SNathan Whitehorn 
3834c8945a0SNathan Whitehorn 	    getyx(dialog, cur_y, cur_x);
3844c8945a0SNathan Whitehorn 	    if (flag == FLAG_CHECK) {	/* checklist? */
3854c8945a0SNathan Whitehorn 		items[current].state = next;
3864c8945a0SNathan Whitehorn 		print_item(list,
3874c8945a0SNathan Whitehorn 			   &items[scrollamt + choice],
3884c8945a0SNathan Whitehorn 			   states,
3894c8945a0SNathan Whitehorn 			   choice, TRUE);
3904c8945a0SNathan Whitehorn 	    } else {		/* radiolist */
3914c8945a0SNathan Whitehorn 		for (i = 0; i < item_no; i++) {
3924c8945a0SNathan Whitehorn 		    if (i != current) {
3934c8945a0SNathan Whitehorn 			items[i].state = 0;
3944c8945a0SNathan Whitehorn 		    }
3954c8945a0SNathan Whitehorn 		}
3964c8945a0SNathan Whitehorn 		if (items[current].state) {
3974c8945a0SNathan Whitehorn 		    items[current].state = next ? next : 1;
3984c8945a0SNathan Whitehorn 		    print_item(list,
3994c8945a0SNathan Whitehorn 			       &items[current],
4004c8945a0SNathan Whitehorn 			       states,
4014c8945a0SNathan Whitehorn 			       choice, TRUE);
4024c8945a0SNathan Whitehorn 		} else {
4034c8945a0SNathan Whitehorn 		    items[current].state = 1;
4044c8945a0SNathan Whitehorn 		    for (i = 0; i < max_choice; i++)
4054c8945a0SNathan Whitehorn 			print_item(list,
4064c8945a0SNathan Whitehorn 				   &items[scrollamt + i],
4074c8945a0SNathan Whitehorn 				   states,
4084c8945a0SNathan Whitehorn 				   i, i == choice);
4094c8945a0SNathan Whitehorn 		}
4104c8945a0SNathan Whitehorn 	    }
4114c8945a0SNathan Whitehorn 	    (void) wnoutrefresh(list);
4124c8945a0SNathan Whitehorn 	    (void) wmove(dialog, cur_y, cur_x);
4134c8945a0SNathan Whitehorn 	    wrefresh(dialog);
4144c8945a0SNathan Whitehorn 	    continue;		/* wait for another key press */
4154c8945a0SNathan Whitehorn 	}
4164c8945a0SNathan Whitehorn 
4174c8945a0SNathan Whitehorn 	/*
4184c8945a0SNathan Whitehorn 	 * Check if key pressed matches first character of any item tag in
4194c8945a0SNathan Whitehorn 	 * list.  If there is more than one match, we will cycle through
4204c8945a0SNathan Whitehorn 	 * each one as the same key is pressed repeatedly.
4214c8945a0SNathan Whitehorn 	 */
4224c8945a0SNathan Whitehorn 	found = FALSE;
4234c8945a0SNathan Whitehorn 	if (!fkey) {
4244c8945a0SNathan Whitehorn 	    if (button < 0 || !dialog_state.visit_items) {
4254c8945a0SNathan Whitehorn 		for (j = scrollamt + choice + 1; j < item_no; j++) {
4264c8945a0SNathan Whitehorn 		    if (dlg_match_char(dlg_last_getc(), items[j].name)) {
4274c8945a0SNathan Whitehorn 			found = TRUE;
4284c8945a0SNathan Whitehorn 			i = j - scrollamt;
4294c8945a0SNathan Whitehorn 			break;
4304c8945a0SNathan Whitehorn 		    }
4314c8945a0SNathan Whitehorn 		}
4324c8945a0SNathan Whitehorn 		if (!found) {
4334c8945a0SNathan Whitehorn 		    for (j = 0; j <= scrollamt + choice; j++) {
4344c8945a0SNathan Whitehorn 			if (dlg_match_char(dlg_last_getc(), items[j].name)) {
4354c8945a0SNathan Whitehorn 			    found = TRUE;
4364c8945a0SNathan Whitehorn 			    i = j - scrollamt;
4374c8945a0SNathan Whitehorn 			    break;
4384c8945a0SNathan Whitehorn 			}
4394c8945a0SNathan Whitehorn 		    }
4404c8945a0SNathan Whitehorn 		}
4414c8945a0SNathan Whitehorn 		if (found)
4424c8945a0SNathan Whitehorn 		    dlg_flush_getc();
4434c8945a0SNathan Whitehorn 	    } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
4444c8945a0SNathan Whitehorn 		button = j;
4454c8945a0SNathan Whitehorn 		ungetch('\n');
4464c8945a0SNathan Whitehorn 		continue;
4474c8945a0SNathan Whitehorn 	    }
4484c8945a0SNathan Whitehorn 	}
4494c8945a0SNathan Whitehorn 
4504c8945a0SNathan Whitehorn 	/*
4514c8945a0SNathan Whitehorn 	 * A single digit (1-9) positions the selection to that line in the
4524c8945a0SNathan Whitehorn 	 * current screen.
4534c8945a0SNathan Whitehorn 	 */
4544c8945a0SNathan Whitehorn 	if (!found
4554c8945a0SNathan Whitehorn 	    && (key <= '9')
4564c8945a0SNathan Whitehorn 	    && (key > '0')
4574c8945a0SNathan Whitehorn 	    && (key - '1' < max_choice)) {
4584c8945a0SNathan Whitehorn 	    found = TRUE;
4594c8945a0SNathan Whitehorn 	    i = key - '1';
4604c8945a0SNathan Whitehorn 	}
4614c8945a0SNathan Whitehorn 
4624c8945a0SNathan Whitehorn 	if (!found) {
4634c8945a0SNathan Whitehorn 	    if (fkey) {
4644c8945a0SNathan Whitehorn 		found = TRUE;
4654c8945a0SNathan Whitehorn 		switch (key) {
4664c8945a0SNathan Whitehorn 		case DLGK_ITEM_FIRST:
4674c8945a0SNathan Whitehorn 		    i = -scrollamt;
4684c8945a0SNathan Whitehorn 		    break;
4694c8945a0SNathan Whitehorn 		case DLGK_ITEM_LAST:
4704c8945a0SNathan Whitehorn 		    i = item_no - 1 - scrollamt;
4714c8945a0SNathan Whitehorn 		    break;
4724c8945a0SNathan Whitehorn 		case DLGK_PAGE_PREV:
4734c8945a0SNathan Whitehorn 		    if (choice)
4744c8945a0SNathan Whitehorn 			i = 0;
4754c8945a0SNathan Whitehorn 		    else if (scrollamt != 0)
4764c8945a0SNathan Whitehorn 			i = -MIN(scrollamt, max_choice);
4774c8945a0SNathan Whitehorn 		    else
4784c8945a0SNathan Whitehorn 			continue;
4794c8945a0SNathan Whitehorn 		    break;
4804c8945a0SNathan Whitehorn 		case DLGK_PAGE_NEXT:
4814c8945a0SNathan Whitehorn 		    i = MIN(choice + max_choice, item_no - scrollamt - 1);
4824c8945a0SNathan Whitehorn 		    break;
4834c8945a0SNathan Whitehorn 		case DLGK_ITEM_PREV:
4844c8945a0SNathan Whitehorn 		    i = choice - 1;
4854c8945a0SNathan Whitehorn 		    if (choice == 0 && scrollamt == 0)
4864c8945a0SNathan Whitehorn 			continue;
4874c8945a0SNathan Whitehorn 		    break;
4884c8945a0SNathan Whitehorn 		case DLGK_ITEM_NEXT:
4894c8945a0SNathan Whitehorn 		    i = choice + 1;
4904c8945a0SNathan Whitehorn 		    if (scrollamt + choice >= item_no - 1)
4914c8945a0SNathan Whitehorn 			continue;
4924c8945a0SNathan Whitehorn 		    break;
4934c8945a0SNathan Whitehorn 		default:
4944c8945a0SNathan Whitehorn 		    found = FALSE;
4954c8945a0SNathan Whitehorn 		    break;
4964c8945a0SNathan Whitehorn 		}
4974c8945a0SNathan Whitehorn 	    }
4984c8945a0SNathan Whitehorn 	}
4994c8945a0SNathan Whitehorn 
5004c8945a0SNathan Whitehorn 	if (found) {
5014c8945a0SNathan Whitehorn 	    if (i != choice) {
5024c8945a0SNathan Whitehorn 		getyx(dialog, cur_y, cur_x);
5034c8945a0SNathan Whitehorn 		if (i < 0 || i >= max_choice) {
5044c8945a0SNathan Whitehorn #if defined(NCURSES_VERSION_MAJOR) && NCURSES_VERSION_MAJOR < 5
5054c8945a0SNathan Whitehorn 		    /*
5064c8945a0SNathan Whitehorn 		     * Using wscrl to assist ncurses scrolling is not needed
5074c8945a0SNathan Whitehorn 		     * in version 5.x
5084c8945a0SNathan Whitehorn 		     */
5094c8945a0SNathan Whitehorn 		    if (i == -1) {
5104c8945a0SNathan Whitehorn 			if (use_height > 1) {
5114c8945a0SNathan Whitehorn 			    /* De-highlight current first item */
5124c8945a0SNathan Whitehorn 			    print_item(list,
5134c8945a0SNathan Whitehorn 				       &items[scrollamt],
5144c8945a0SNathan Whitehorn 				       states,
5154c8945a0SNathan Whitehorn 				       0, FALSE);
5164c8945a0SNathan Whitehorn 			    scrollok(list, TRUE);
5174c8945a0SNathan Whitehorn 			    wscrl(list, -1);
5184c8945a0SNathan Whitehorn 			    scrollok(list, FALSE);
5194c8945a0SNathan Whitehorn 			}
5204c8945a0SNathan Whitehorn 			scrollamt--;
5214c8945a0SNathan Whitehorn 			print_item(list,
5224c8945a0SNathan Whitehorn 				   &items[scrollamt],
5234c8945a0SNathan Whitehorn 				   states,
5244c8945a0SNathan Whitehorn 				   0, TRUE);
5254c8945a0SNathan Whitehorn 		    } else if (i == max_choice) {
5264c8945a0SNathan Whitehorn 			if (use_height > 1) {
5274c8945a0SNathan Whitehorn 			    /* De-highlight current last item before scrolling up */
5284c8945a0SNathan Whitehorn 			    print_item(list,
5294c8945a0SNathan Whitehorn 				       &items[scrollamt + max_choice - 1],
5304c8945a0SNathan Whitehorn 				       states,
5314c8945a0SNathan Whitehorn 				       max_choice - 1, FALSE);
5324c8945a0SNathan Whitehorn 			    scrollok(list, TRUE);
5334c8945a0SNathan Whitehorn 			    wscrl(list, 1);
5344c8945a0SNathan Whitehorn 			    scrollok(list, FALSE);
5354c8945a0SNathan Whitehorn 			}
5364c8945a0SNathan Whitehorn 			scrollamt++;
5374c8945a0SNathan Whitehorn 			print_item(list,
5384c8945a0SNathan Whitehorn 				   &items[scrollamt + max_choice - 1],
5394c8945a0SNathan Whitehorn 				   states,
5404c8945a0SNathan Whitehorn 				   max_choice - 1, TRUE);
5414c8945a0SNathan Whitehorn 		    } else
5424c8945a0SNathan Whitehorn #endif
5434c8945a0SNathan Whitehorn 		    {
5444c8945a0SNathan Whitehorn 			if (i < 0) {
5454c8945a0SNathan Whitehorn 			    scrollamt += i;
5464c8945a0SNathan Whitehorn 			    choice = 0;
5474c8945a0SNathan Whitehorn 			} else {
5484c8945a0SNathan Whitehorn 			    choice = max_choice - 1;
5494c8945a0SNathan Whitehorn 			    scrollamt += (i - max_choice + 1);
5504c8945a0SNathan Whitehorn 			}
5514c8945a0SNathan Whitehorn 			for (i = 0; i < max_choice; i++) {
5524c8945a0SNathan Whitehorn 			    print_item(list,
5534c8945a0SNathan Whitehorn 				       &items[scrollamt + i],
5544c8945a0SNathan Whitehorn 				       states,
5554c8945a0SNathan Whitehorn 				       i, i == choice);
5564c8945a0SNathan Whitehorn 			}
5574c8945a0SNathan Whitehorn 		    }
5584c8945a0SNathan Whitehorn 		    (void) wnoutrefresh(list);
5594c8945a0SNathan Whitehorn 		    print_arrows(dialog,
5604c8945a0SNathan Whitehorn 				 box_x, box_y,
5614c8945a0SNathan Whitehorn 				 scrollamt, max_choice, item_no, use_height);
5624c8945a0SNathan Whitehorn 		} else {
5634c8945a0SNathan Whitehorn 		    /* De-highlight current item */
5644c8945a0SNathan Whitehorn 		    print_item(list,
5654c8945a0SNathan Whitehorn 			       &items[scrollamt + choice],
5664c8945a0SNathan Whitehorn 			       states,
5674c8945a0SNathan Whitehorn 			       choice, FALSE);
5684c8945a0SNathan Whitehorn 		    /* Highlight new item */
5694c8945a0SNathan Whitehorn 		    choice = i;
5704c8945a0SNathan Whitehorn 		    print_item(list,
5714c8945a0SNathan Whitehorn 			       &items[scrollamt + choice],
5724c8945a0SNathan Whitehorn 			       states,
5734c8945a0SNathan Whitehorn 			       choice, TRUE);
5744c8945a0SNathan Whitehorn 		    (void) wnoutrefresh(list);
5754c8945a0SNathan Whitehorn 		    print_arrows(dialog,
5764c8945a0SNathan Whitehorn 				 box_x, box_y,
5774c8945a0SNathan Whitehorn 				 scrollamt, max_choice, item_no, use_height);
5784c8945a0SNathan Whitehorn 		    (void) wmove(dialog, cur_y, cur_x);
5794c8945a0SNathan Whitehorn 		    wrefresh(dialog);
5804c8945a0SNathan Whitehorn 		}
5814c8945a0SNathan Whitehorn 	    }
5824c8945a0SNathan Whitehorn 	    continue;		/* wait for another key press */
5834c8945a0SNathan Whitehorn 	}
5844c8945a0SNathan Whitehorn 
5854c8945a0SNathan Whitehorn 	if (fkey) {
5864c8945a0SNathan Whitehorn 	    switch (key) {
5874c8945a0SNathan Whitehorn 	    case DLGK_ENTER:
588682c9e0fSNathan Whitehorn 		result = dlg_enter_buttoncode(button);
5894c8945a0SNathan Whitehorn 		break;
5904c8945a0SNathan Whitehorn 	    case DLGK_FIELD_PREV:
5914c8945a0SNathan Whitehorn 		button = dlg_prev_button(buttons, button);
5924c8945a0SNathan Whitehorn 		dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
5934c8945a0SNathan Whitehorn 				 FALSE, width);
5944c8945a0SNathan Whitehorn 		break;
5954c8945a0SNathan Whitehorn 	    case DLGK_FIELD_NEXT:
5964c8945a0SNathan Whitehorn 		button = dlg_next_button(buttons, button);
5974c8945a0SNathan Whitehorn 		dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
5984c8945a0SNathan Whitehorn 				 FALSE, width);
5994c8945a0SNathan Whitehorn 		break;
6004c8945a0SNathan Whitehorn #ifdef KEY_RESIZE
6014c8945a0SNathan Whitehorn 	    case KEY_RESIZE:
6024c8945a0SNathan Whitehorn 		/* reset data */
6034c8945a0SNathan Whitehorn 		height = old_height;
6044c8945a0SNathan Whitehorn 		width = old_width;
6054c8945a0SNathan Whitehorn 		/* repaint */
6064c8945a0SNathan Whitehorn 		dlg_clear();
6074c8945a0SNathan Whitehorn 		dlg_del_window(dialog);
6084c8945a0SNathan Whitehorn 		refresh();
6094c8945a0SNathan Whitehorn 		dlg_mouse_free_regions();
6104c8945a0SNathan Whitehorn 		goto retry;
6114c8945a0SNathan Whitehorn #endif
6124c8945a0SNathan Whitehorn 	    default:
6134c8945a0SNathan Whitehorn 		if (was_mouse) {
6144c8945a0SNathan Whitehorn 		    if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
6154c8945a0SNathan Whitehorn 			result = key2;
6164c8945a0SNathan Whitehorn 			break;
6174c8945a0SNathan Whitehorn 		    }
6184c8945a0SNathan Whitehorn 		    beep();
6194c8945a0SNathan Whitehorn 		}
6204c8945a0SNathan Whitehorn 	    }
6214c8945a0SNathan Whitehorn 	} else {
6224c8945a0SNathan Whitehorn 	    beep();
6234c8945a0SNathan Whitehorn 	}
6244c8945a0SNathan Whitehorn     }
6254c8945a0SNathan Whitehorn 
6264c8945a0SNathan Whitehorn     dlg_del_window(dialog);
6274c8945a0SNathan Whitehorn     dlg_mouse_free_regions();
6284c8945a0SNathan Whitehorn     free(prompt);
6294c8945a0SNathan Whitehorn     *current_item = (scrollamt + choice);
6304c8945a0SNathan Whitehorn     return result;
6314c8945a0SNathan Whitehorn }
6324c8945a0SNathan Whitehorn 
6334c8945a0SNathan Whitehorn /*
6344c8945a0SNathan Whitehorn  * Display a dialog box with a list of options that can be turned on or off
6354c8945a0SNathan Whitehorn  * The `flag' parameter is used to select between radiolist and checklist.
6364c8945a0SNathan Whitehorn  */
6374c8945a0SNathan Whitehorn int
6384c8945a0SNathan Whitehorn dialog_checklist(const char *title,
6394c8945a0SNathan Whitehorn 		 const char *cprompt,
6404c8945a0SNathan Whitehorn 		 int height,
6414c8945a0SNathan Whitehorn 		 int width,
6424c8945a0SNathan Whitehorn 		 int list_height,
6434c8945a0SNathan Whitehorn 		 int item_no,
6444c8945a0SNathan Whitehorn 		 char **items,
6454c8945a0SNathan Whitehorn 		 int flag)
6464c8945a0SNathan Whitehorn {
6474c8945a0SNathan Whitehorn     int result;
6484c8945a0SNathan Whitehorn     int i;
6494c8945a0SNathan Whitehorn     DIALOG_LISTITEM *listitems;
6504c8945a0SNathan Whitehorn     bool separate_output = ((flag == FLAG_CHECK)
6514c8945a0SNathan Whitehorn 			    && (dialog_vars.separate_output));
6524c8945a0SNathan Whitehorn     bool show_status = FALSE;
6534c8945a0SNathan Whitehorn     int current = 0;
6544c8945a0SNathan Whitehorn 
6554c8945a0SNathan Whitehorn     listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
6564c8945a0SNathan Whitehorn     assert_ptr(listitems, "dialog_checklist");
6574c8945a0SNathan Whitehorn 
6584c8945a0SNathan Whitehorn     for (i = 0; i < item_no; ++i) {
6594c8945a0SNathan Whitehorn 	listitems[i].name = ItemName(i);
6604c8945a0SNathan Whitehorn 	listitems[i].text = ItemText(i);
6614c8945a0SNathan Whitehorn 	listitems[i].help = ((dialog_vars.item_help)
6624c8945a0SNathan Whitehorn 			     ? ItemHelp(i)
6634c8945a0SNathan Whitehorn 			     : dlg_strempty());
6644c8945a0SNathan Whitehorn 	listitems[i].state = !dlg_strcmp(ItemStatus(i), "on");
6654c8945a0SNathan Whitehorn     }
6667a1c0d96SNathan Whitehorn     dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
6674c8945a0SNathan Whitehorn 
6684c8945a0SNathan Whitehorn     result = dlg_checklist(title,
6694c8945a0SNathan Whitehorn 			   cprompt,
6704c8945a0SNathan Whitehorn 			   height,
6714c8945a0SNathan Whitehorn 			   width,
6724c8945a0SNathan Whitehorn 			   list_height,
6734c8945a0SNathan Whitehorn 			   item_no,
6744c8945a0SNathan Whitehorn 			   listitems,
6754c8945a0SNathan Whitehorn 			   NULL,
6764c8945a0SNathan Whitehorn 			   flag,
6774c8945a0SNathan Whitehorn 			   &current);
6784c8945a0SNathan Whitehorn 
6794c8945a0SNathan Whitehorn     switch (result) {
6804c8945a0SNathan Whitehorn     case DLG_EXIT_OK:		/* FALLTHRU */
6814c8945a0SNathan Whitehorn     case DLG_EXIT_EXTRA:
6824c8945a0SNathan Whitehorn 	show_status = TRUE;
6834c8945a0SNathan Whitehorn 	break;
6844c8945a0SNathan Whitehorn     case DLG_EXIT_HELP:
6854c8945a0SNathan Whitehorn 	dlg_add_result("HELP ");
6864c8945a0SNathan Whitehorn 	show_status = dialog_vars.help_status;
6874c8945a0SNathan Whitehorn 	if (USE_ITEM_HELP(listitems[current].help)) {
6884c8945a0SNathan Whitehorn 	    if (show_status) {
6894c8945a0SNathan Whitehorn 		if (separate_output) {
6904c8945a0SNathan Whitehorn 		    dlg_add_string(listitems[current].help);
6914c8945a0SNathan Whitehorn 		    dlg_add_separator();
6924c8945a0SNathan Whitehorn 		} else {
6934c8945a0SNathan Whitehorn 		    dlg_add_quoted(listitems[current].help);
6944c8945a0SNathan Whitehorn 		}
6954c8945a0SNathan Whitehorn 	    } else {
6964c8945a0SNathan Whitehorn 		dlg_add_string(listitems[current].help);
6974c8945a0SNathan Whitehorn 	    }
6984c8945a0SNathan Whitehorn 	    result = DLG_EXIT_ITEM_HELP;
6994c8945a0SNathan Whitehorn 	} else {
7004c8945a0SNathan Whitehorn 	    if (show_status) {
7014c8945a0SNathan Whitehorn 		if (separate_output) {
7024c8945a0SNathan Whitehorn 		    dlg_add_string(listitems[current].name);
7034c8945a0SNathan Whitehorn 		    dlg_add_separator();
7044c8945a0SNathan Whitehorn 		} else {
7054c8945a0SNathan Whitehorn 		    dlg_add_quoted(listitems[current].name);
7064c8945a0SNathan Whitehorn 		}
7074c8945a0SNathan Whitehorn 	    } else {
7084c8945a0SNathan Whitehorn 		dlg_add_string(listitems[current].name);
7094c8945a0SNathan Whitehorn 	    }
7104c8945a0SNathan Whitehorn 	}
7114c8945a0SNathan Whitehorn 	break;
7124c8945a0SNathan Whitehorn     }
7134c8945a0SNathan Whitehorn 
7144c8945a0SNathan Whitehorn     if (show_status) {
7154c8945a0SNathan Whitehorn 	for (i = 0; i < item_no; i++) {
7164c8945a0SNathan Whitehorn 	    if (listitems[i].state) {
7174c8945a0SNathan Whitehorn 		if (separate_output) {
7184c8945a0SNathan Whitehorn 		    dlg_add_string(listitems[i].name);
7194c8945a0SNathan Whitehorn 		    dlg_add_separator();
7204c8945a0SNathan Whitehorn 		} else {
7214c8945a0SNathan Whitehorn 		    if (dlg_need_separator())
7224c8945a0SNathan Whitehorn 			dlg_add_separator();
7234c8945a0SNathan Whitehorn 		    dlg_add_string(listitems[i].name);
7244c8945a0SNathan Whitehorn 		}
7254c8945a0SNathan Whitehorn 	    }
7264c8945a0SNathan Whitehorn 	}
7274c8945a0SNathan Whitehorn     }
7284c8945a0SNathan Whitehorn 
7297a1c0d96SNathan Whitehorn     dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
7304c8945a0SNathan Whitehorn     free(listitems);
7314c8945a0SNathan Whitehorn     return result;
7324c8945a0SNathan Whitehorn }
733