xref: /openbmc/linux/scripts/kconfig/lxdialog/menubox.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1*0c874100SMasahiro Yamada // SPDX-License-Identifier: GPL-2.0+
26f6046cfSSam Ravnborg /*
36f6046cfSSam Ravnborg  *  menubox.c -- implements the menu box
46f6046cfSSam Ravnborg  *
56f6046cfSSam Ravnborg  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
66f6046cfSSam Ravnborg  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
76f6046cfSSam Ravnborg  */
86f6046cfSSam Ravnborg 
96f6046cfSSam Ravnborg /*
106f6046cfSSam Ravnborg  *  Changes by Clifford Wolf (god@clifford.at)
116f6046cfSSam Ravnborg  *
126f6046cfSSam Ravnborg  *  [ 1998-06-13 ]
136f6046cfSSam Ravnborg  *
146f6046cfSSam Ravnborg  *    *)  A bugfix for the Page-Down problem
156f6046cfSSam Ravnborg  *
166f6046cfSSam Ravnborg  *    *)  Formerly when I used Page Down and Page Up, the cursor would be set
176f6046cfSSam Ravnborg  *        to the first position in the menu box.  Now lxdialog is a bit
186f6046cfSSam Ravnborg  *        smarter and works more like other menu systems (just have a look at
196f6046cfSSam Ravnborg  *        it).
206f6046cfSSam Ravnborg  *
216f6046cfSSam Ravnborg  *    *)  Formerly if I selected something my scrolling would be broken because
226f6046cfSSam Ravnborg  *        lxdialog is re-invoked by the Menuconfig shell script, can't
236f6046cfSSam Ravnborg  *        remember the last scrolling position, and just sets it so that the
246f6046cfSSam Ravnborg  *        cursor is at the bottom of the box.  Now it writes the temporary file
256f6046cfSSam Ravnborg  *        lxdialog.scrltmp which contains this information. The file is
266f6046cfSSam Ravnborg  *        deleted by lxdialog if the user leaves a submenu or enters a new
276f6046cfSSam Ravnborg  *        one, but it would be nice if Menuconfig could make another "rm -f"
286f6046cfSSam Ravnborg  *        just to be sure.  Just try it out - you will recognise a difference!
296f6046cfSSam Ravnborg  *
306f6046cfSSam Ravnborg  *  [ 1998-06-14 ]
316f6046cfSSam Ravnborg  *
326f6046cfSSam Ravnborg  *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
336f6046cfSSam Ravnborg  *        and menus change their size on the fly.
346f6046cfSSam Ravnborg  *
356f6046cfSSam Ravnborg  *    *)  If for some reason the last scrolling position is not saved by
366f6046cfSSam Ravnborg  *        lxdialog, it sets the scrolling so that the selected item is in the
376f6046cfSSam Ravnborg  *        middle of the menu box, not at the bottom.
386f6046cfSSam Ravnborg  *
396f6046cfSSam Ravnborg  * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
406f6046cfSSam Ravnborg  * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
416f6046cfSSam Ravnborg  * This fixes a bug in Menuconfig where using ' ' to descend into menus
426f6046cfSSam Ravnborg  * would leave mis-synchronized lxdialog.scrltmp files lying around,
436f6046cfSSam Ravnborg  * fscanf would read in 'scroll', and eventually that value would get used.
446f6046cfSSam Ravnborg  */
456f6046cfSSam Ravnborg 
466f6046cfSSam Ravnborg #include "dialog.h"
476f6046cfSSam Ravnborg 
4894f2505bSRoman Zippel static int menu_width, item_x;
496f6046cfSSam Ravnborg 
506f6046cfSSam Ravnborg /*
516f6046cfSSam Ravnborg  * Print menu item
526f6046cfSSam Ravnborg  */
do_print_item(WINDOW * win,const char * item,int line_y,int selected,int hotkey)53737ecae2SSam Ravnborg static void do_print_item(WINDOW * win, const char *item, int line_y,
546f6046cfSSam Ravnborg 			  int selected, int hotkey)
556f6046cfSSam Ravnborg {
566f6046cfSSam Ravnborg 	int j;
576f6046cfSSam Ravnborg 	char *menu_item = malloc(menu_width + 1);
586f6046cfSSam Ravnborg 
5994f2505bSRoman Zippel 	strncpy(menu_item, item, menu_width - item_x);
60737ecae2SSam Ravnborg 	menu_item[menu_width - item_x] = '\0';
616f6046cfSSam Ravnborg 	j = first_alpha(menu_item, "YyNnMmHh");
626f6046cfSSam Ravnborg 
636f6046cfSSam Ravnborg 	/* Clear 'residue' of last item */
6498e5a157SSam Ravnborg 	wattrset(win, dlg.menubox.atr);
65737ecae2SSam Ravnborg 	wmove(win, line_y, 0);
666f6046cfSSam Ravnborg 	wclrtoeol(win);
6798e5a157SSam Ravnborg 	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
68737ecae2SSam Ravnborg 	mvwaddstr(win, line_y, item_x, menu_item);
696f6046cfSSam Ravnborg 	if (hotkey) {
7098e5a157SSam Ravnborg 		wattrset(win, selected ? dlg.tag_key_selected.atr
7198e5a157SSam Ravnborg 			 : dlg.tag_key.atr);
72737ecae2SSam Ravnborg 		mvwaddch(win, line_y, item_x + j, menu_item[j]);
736f6046cfSSam Ravnborg 	}
746f6046cfSSam Ravnborg 	if (selected) {
75737ecae2SSam Ravnborg 		wmove(win, line_y, item_x + 1);
766f6046cfSSam Ravnborg 	}
776f6046cfSSam Ravnborg 	free(menu_item);
786f6046cfSSam Ravnborg 	wrefresh(win);
796f6046cfSSam Ravnborg }
806f6046cfSSam Ravnborg 
816f6046cfSSam Ravnborg #define print_item(index, choice, selected)				\
826f6046cfSSam Ravnborg do {									\
832982de69SSam Ravnborg 	item_set(index);						\
842982de69SSam Ravnborg 	do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
856f6046cfSSam Ravnborg } while (0)
866f6046cfSSam Ravnborg 
876f6046cfSSam Ravnborg /*
886f6046cfSSam Ravnborg  * Print the scroll indicators.
896f6046cfSSam Ravnborg  */
print_arrows(WINDOW * win,int item_no,int scroll,int y,int x,int height)906f6046cfSSam Ravnborg static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
916f6046cfSSam Ravnborg 			 int height)
926f6046cfSSam Ravnborg {
936f6046cfSSam Ravnborg 	int cur_y, cur_x;
946f6046cfSSam Ravnborg 
956f6046cfSSam Ravnborg 	getyx(win, cur_y, cur_x);
966f6046cfSSam Ravnborg 
976f6046cfSSam Ravnborg 	wmove(win, y, x);
986f6046cfSSam Ravnborg 
996f6046cfSSam Ravnborg 	if (scroll > 0) {
10098e5a157SSam Ravnborg 		wattrset(win, dlg.uarrow.atr);
1016f6046cfSSam Ravnborg 		waddch(win, ACS_UARROW);
1026f6046cfSSam Ravnborg 		waddstr(win, "(-)");
1036f6046cfSSam Ravnborg 	} else {
10498e5a157SSam Ravnborg 		wattrset(win, dlg.menubox.atr);
1056f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1066f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1076f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1086f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1096f6046cfSSam Ravnborg 	}
1106f6046cfSSam Ravnborg 
1116f6046cfSSam Ravnborg 	y = y + height + 1;
1126f6046cfSSam Ravnborg 	wmove(win, y, x);
1136f6046cfSSam Ravnborg 	wrefresh(win);
1146f6046cfSSam Ravnborg 
1156f6046cfSSam Ravnborg 	if ((height < item_no) && (scroll + height < item_no)) {
11698e5a157SSam Ravnborg 		wattrset(win, dlg.darrow.atr);
1176f6046cfSSam Ravnborg 		waddch(win, ACS_DARROW);
1186f6046cfSSam Ravnborg 		waddstr(win, "(+)");
1196f6046cfSSam Ravnborg 	} else {
12098e5a157SSam Ravnborg 		wattrset(win, dlg.menubox_border.atr);
1216f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1226f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1236f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1246f6046cfSSam Ravnborg 		waddch(win, ACS_HLINE);
1256f6046cfSSam Ravnborg 	}
1266f6046cfSSam Ravnborg 
1276f6046cfSSam Ravnborg 	wmove(win, cur_y, cur_x);
1286f6046cfSSam Ravnborg 	wrefresh(win);
1296f6046cfSSam Ravnborg }
1306f6046cfSSam Ravnborg 
1316f6046cfSSam Ravnborg /*
1326f6046cfSSam Ravnborg  * Display the termination buttons.
1336f6046cfSSam Ravnborg  */
print_buttons(WINDOW * win,int height,int width,int selected)1346f6046cfSSam Ravnborg static void print_buttons(WINDOW * win, int height, int width, int selected)
1356f6046cfSSam Ravnborg {
1366364fd0cSWang YanQing 	int x = width / 2 - 28;
1376f6046cfSSam Ravnborg 	int y = height - 2;
1386f6046cfSSam Ravnborg 
139694c49a7SSam Ravnborg 	print_button(win, "Select", y, x, selected == 0);
140694c49a7SSam Ravnborg 	print_button(win, " Exit ", y, x + 12, selected == 1);
141694c49a7SSam Ravnborg 	print_button(win, " Help ", y, x + 24, selected == 2);
142694c49a7SSam Ravnborg 	print_button(win, " Save ", y, x + 36, selected == 3);
143694c49a7SSam Ravnborg 	print_button(win, " Load ", y, x + 48, selected == 4);
1446f6046cfSSam Ravnborg 
1456f6046cfSSam Ravnborg 	wmove(win, y, x + 1 + 12 * selected);
1466f6046cfSSam Ravnborg 	wrefresh(win);
1476f6046cfSSam Ravnborg }
1486f6046cfSSam Ravnborg 
1496f6046cfSSam Ravnborg /* scroll up n lines (n may be negative) */
do_scroll(WINDOW * win,int * scroll,int n)1506f6046cfSSam Ravnborg static void do_scroll(WINDOW *win, int *scroll, int n)
1516f6046cfSSam Ravnborg {
1526f6046cfSSam Ravnborg 	/* Scroll menu up */
1536f6046cfSSam Ravnborg 	scrollok(win, TRUE);
1546f6046cfSSam Ravnborg 	wscrl(win, n);
1556f6046cfSSam Ravnborg 	scrollok(win, FALSE);
1566f6046cfSSam Ravnborg 	*scroll = *scroll + n;
1576f6046cfSSam Ravnborg 	wrefresh(win);
1586f6046cfSSam Ravnborg }
1596f6046cfSSam Ravnborg 
1606f6046cfSSam Ravnborg /*
1616f6046cfSSam Ravnborg  * Display a menu for choosing among a number of options
1626f6046cfSSam Ravnborg  */
dialog_menu(const char * title,const char * prompt,const void * selected,int * s_scroll)163c8dc68adSSam Ravnborg int dialog_menu(const char *title, const char *prompt,
164c8dc68adSSam Ravnborg 		const void *selected, int *s_scroll)
1656f6046cfSSam Ravnborg {
1666f6046cfSSam Ravnborg 	int i, j, x, y, box_x, box_y;
167c8dc68adSSam Ravnborg 	int height, width, menu_height;
1686f6046cfSSam Ravnborg 	int key = 0, button = 0, scroll = 0, choice = 0;
1696f6046cfSSam Ravnborg 	int first_item =  0, max_choice;
1706f6046cfSSam Ravnborg 	WINDOW *dialog, *menu;
1716f6046cfSSam Ravnborg 
172c8dc68adSSam Ravnborg do_resize:
173c8dc68adSSam Ravnborg 	height = getmaxy(stdscr);
174c8dc68adSSam Ravnborg 	width = getmaxx(stdscr);
175851f6657SSedat Dilek 	if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)
176c8dc68adSSam Ravnborg 		return -ERRDISPLAYTOOSMALL;
177c8dc68adSSam Ravnborg 
178c8dc68adSSam Ravnborg 	height -= 4;
179c8dc68adSSam Ravnborg 	width  -= 5;
180c8dc68adSSam Ravnborg 	menu_height = height - 10;
181c8dc68adSSam Ravnborg 
1822982de69SSam Ravnborg 	max_choice = MIN(menu_height, item_count());
1836f6046cfSSam Ravnborg 
1846f6046cfSSam Ravnborg 	/* center dialog box on screen */
1854f2de3e1SDirk Gouders 	x = (getmaxx(stdscr) - width) / 2;
1864f2de3e1SDirk Gouders 	y = (getmaxy(stdscr) - height) / 2;
1876f6046cfSSam Ravnborg 
1886f6046cfSSam Ravnborg 	draw_shadow(stdscr, y, x, height, width);
1896f6046cfSSam Ravnborg 
1906f6046cfSSam Ravnborg 	dialog = newwin(height, width, y, x);
1916f6046cfSSam Ravnborg 	keypad(dialog, TRUE);
1926f6046cfSSam Ravnborg 
19398e5a157SSam Ravnborg 	draw_box(dialog, 0, 0, height, width,
19498e5a157SSam Ravnborg 		 dlg.dialog.atr, dlg.border.atr);
19598e5a157SSam Ravnborg 	wattrset(dialog, dlg.border.atr);
1966f6046cfSSam Ravnborg 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
1976f6046cfSSam Ravnborg 	for (i = 0; i < width - 2; i++)
1986f6046cfSSam Ravnborg 		waddch(dialog, ACS_HLINE);
19998e5a157SSam Ravnborg 	wattrset(dialog, dlg.dialog.atr);
20098e5a157SSam Ravnborg 	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
2016f6046cfSSam Ravnborg 	waddch(dialog, ACS_RTEE);
2026f6046cfSSam Ravnborg 
2036f6046cfSSam Ravnborg 	print_title(dialog, title, width);
2046f6046cfSSam Ravnborg 
20598e5a157SSam Ravnborg 	wattrset(dialog, dlg.dialog.atr);
2066f6046cfSSam Ravnborg 	print_autowrap(dialog, prompt, width - 2, 1, 3);
2076f6046cfSSam Ravnborg 
2086f6046cfSSam Ravnborg 	menu_width = width - 6;
2096f6046cfSSam Ravnborg 	box_y = height - menu_height - 5;
2106f6046cfSSam Ravnborg 	box_x = (width - menu_width) / 2 - 1;
2116f6046cfSSam Ravnborg 
2126f6046cfSSam Ravnborg 	/* create new window for the menu */
2136f6046cfSSam Ravnborg 	menu = subwin(dialog, menu_height, menu_width,
2146f6046cfSSam Ravnborg 		      y + box_y + 1, x + box_x + 1);
2156f6046cfSSam Ravnborg 	keypad(menu, TRUE);
2166f6046cfSSam Ravnborg 
2176f6046cfSSam Ravnborg 	/* draw a box around the menu items */
2186f6046cfSSam Ravnborg 	draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
21998e5a157SSam Ravnborg 		 dlg.menubox_border.atr, dlg.menubox.atr);
2206f6046cfSSam Ravnborg 
221c8dc68adSSam Ravnborg 	if (menu_width >= 80)
22294f2505bSRoman Zippel 		item_x = (menu_width - 70) / 2;
223c8dc68adSSam Ravnborg 	else
224c8dc68adSSam Ravnborg 		item_x = 4;
22594f2505bSRoman Zippel 
2266f6046cfSSam Ravnborg 	/* Set choice to default item */
2272982de69SSam Ravnborg 	item_foreach()
2282982de69SSam Ravnborg 		if (selected && (selected == item_data()))
2292982de69SSam Ravnborg 			choice = item_n();
2302982de69SSam Ravnborg 	/* get the saved scroll info */
2312982de69SSam Ravnborg 	scroll = *s_scroll;
2322982de69SSam Ravnborg 	if ((scroll <= choice) && (scroll + max_choice > choice) &&
2332982de69SSam Ravnborg 	   (scroll >= 0) && (scroll + max_choice <= item_count())) {
2346f6046cfSSam Ravnborg 		first_item = scroll;
2356f6046cfSSam Ravnborg 		choice = choice - scroll;
2366f6046cfSSam Ravnborg 	} else {
2376f6046cfSSam Ravnborg 		scroll = 0;
2386f6046cfSSam Ravnborg 	}
2392982de69SSam Ravnborg 	if ((choice >= max_choice)) {
2402982de69SSam Ravnborg 		if (choice >= item_count() - max_choice / 2)
2412982de69SSam Ravnborg 			scroll = first_item = item_count() - max_choice;
2426f6046cfSSam Ravnborg 		else
2436f6046cfSSam Ravnborg 			scroll = first_item = choice - max_choice / 2;
2446f6046cfSSam Ravnborg 		choice = choice - scroll;
2456f6046cfSSam Ravnborg 	}
2466f6046cfSSam Ravnborg 
2476f6046cfSSam Ravnborg 	/* Print the menu */
2486f6046cfSSam Ravnborg 	for (i = 0; i < max_choice; i++) {
2496f6046cfSSam Ravnborg 		print_item(first_item + i, i, i == choice);
2506f6046cfSSam Ravnborg 	}
2516f6046cfSSam Ravnborg 
2526f6046cfSSam Ravnborg 	wnoutrefresh(menu);
2536f6046cfSSam Ravnborg 
2542982de69SSam Ravnborg 	print_arrows(dialog, item_count(), scroll,
25594f2505bSRoman Zippel 		     box_y, box_x + item_x + 1, menu_height);
2566f6046cfSSam Ravnborg 
2576f6046cfSSam Ravnborg 	print_buttons(dialog, height, width, 0);
25894f2505bSRoman Zippel 	wmove(menu, choice, item_x + 1);
2596f6046cfSSam Ravnborg 	wrefresh(menu);
2606f6046cfSSam Ravnborg 
261f3cbcdc9SSam Ravnborg 	while (key != KEY_ESC) {
2626f6046cfSSam Ravnborg 		key = wgetch(menu);
2636f6046cfSSam Ravnborg 
2646f6046cfSSam Ravnborg 		if (key < 256 && isalpha(key))
2656f6046cfSSam Ravnborg 			key = tolower(key);
2666f6046cfSSam Ravnborg 
2676f6046cfSSam Ravnborg 		if (strchr("ynmh", key))
2686f6046cfSSam Ravnborg 			i = max_choice;
2696f6046cfSSam Ravnborg 		else {
2706f6046cfSSam Ravnborg 			for (i = choice + 1; i < max_choice; i++) {
2712982de69SSam Ravnborg 				item_set(scroll + i);
2722982de69SSam Ravnborg 				j = first_alpha(item_str(), "YyNnMmHh");
2732982de69SSam Ravnborg 				if (key == tolower(item_str()[j]))
2746f6046cfSSam Ravnborg 					break;
2756f6046cfSSam Ravnborg 			}
2766f6046cfSSam Ravnborg 			if (i == max_choice)
2776f6046cfSSam Ravnborg 				for (i = 0; i < max_choice; i++) {
2782982de69SSam Ravnborg 					item_set(scroll + i);
2792982de69SSam Ravnborg 					j = first_alpha(item_str(), "YyNnMmHh");
2802982de69SSam Ravnborg 					if (key == tolower(item_str()[j]))
2816f6046cfSSam Ravnborg 						break;
2826f6046cfSSam Ravnborg 				}
2836f6046cfSSam Ravnborg 		}
2846f6046cfSSam Ravnborg 
285063f4661SDirk Gouders 		if (item_count() != 0 &&
286063f4661SDirk Gouders 		    (i < max_choice ||
2876f6046cfSSam Ravnborg 		     key == KEY_UP || key == KEY_DOWN ||
2886f6046cfSSam Ravnborg 		     key == '-' || key == '+' ||
289063f4661SDirk Gouders 		     key == KEY_PPAGE || key == KEY_NPAGE)) {
2906f6046cfSSam Ravnborg 			/* Remove highligt of current item */
2916f6046cfSSam Ravnborg 			print_item(scroll + choice, choice, FALSE);
2926f6046cfSSam Ravnborg 
2936f6046cfSSam Ravnborg 			if (key == KEY_UP || key == '-') {
2946f6046cfSSam Ravnborg 				if (choice < 2 && scroll) {
2956f6046cfSSam Ravnborg 					/* Scroll menu down */
2966f6046cfSSam Ravnborg 					do_scroll(menu, &scroll, -1);
2976f6046cfSSam Ravnborg 
2986f6046cfSSam Ravnborg 					print_item(scroll, 0, FALSE);
2996f6046cfSSam Ravnborg 				} else
3006f6046cfSSam Ravnborg 					choice = MAX(choice - 1, 0);
3016f6046cfSSam Ravnborg 
3026f6046cfSSam Ravnborg 			} else if (key == KEY_DOWN || key == '+') {
3036f6046cfSSam Ravnborg 				print_item(scroll+choice, choice, FALSE);
3046f6046cfSSam Ravnborg 
3056f6046cfSSam Ravnborg 				if ((choice > max_choice - 3) &&
3062982de69SSam Ravnborg 				    (scroll + max_choice < item_count())) {
3076f6046cfSSam Ravnborg 					/* Scroll menu up */
3086f6046cfSSam Ravnborg 					do_scroll(menu, &scroll, 1);
3096f6046cfSSam Ravnborg 
3106f6046cfSSam Ravnborg 					print_item(scroll+max_choice - 1,
3116f6046cfSSam Ravnborg 						   max_choice - 1, FALSE);
3126f6046cfSSam Ravnborg 				} else
3136f6046cfSSam Ravnborg 					choice = MIN(choice + 1, max_choice - 1);
3146f6046cfSSam Ravnborg 
3156f6046cfSSam Ravnborg 			} else if (key == KEY_PPAGE) {
3166f6046cfSSam Ravnborg 				scrollok(menu, TRUE);
3176f6046cfSSam Ravnborg 				for (i = 0; (i < max_choice); i++) {
3186f6046cfSSam Ravnborg 					if (scroll > 0) {
3196f6046cfSSam Ravnborg 						do_scroll(menu, &scroll, -1);
3206f6046cfSSam Ravnborg 						print_item(scroll, 0, FALSE);
3216f6046cfSSam Ravnborg 					} else {
3226f6046cfSSam Ravnborg 						if (choice > 0)
3236f6046cfSSam Ravnborg 							choice--;
3246f6046cfSSam Ravnborg 					}
3256f6046cfSSam Ravnborg 				}
3266f6046cfSSam Ravnborg 
3276f6046cfSSam Ravnborg 			} else if (key == KEY_NPAGE) {
3286f6046cfSSam Ravnborg 				for (i = 0; (i < max_choice); i++) {
3292982de69SSam Ravnborg 					if (scroll + max_choice < item_count()) {
3306f6046cfSSam Ravnborg 						do_scroll(menu, &scroll, 1);
3316f6046cfSSam Ravnborg 						print_item(scroll+max_choice-1,
3326f6046cfSSam Ravnborg 							   max_choice - 1, FALSE);
3336f6046cfSSam Ravnborg 					} else {
3346f6046cfSSam Ravnborg 						if (choice + 1 < max_choice)
3356f6046cfSSam Ravnborg 							choice++;
3366f6046cfSSam Ravnborg 					}
3376f6046cfSSam Ravnborg 				}
3386f6046cfSSam Ravnborg 			} else
3396f6046cfSSam Ravnborg 				choice = i;
3406f6046cfSSam Ravnborg 
3416f6046cfSSam Ravnborg 			print_item(scroll + choice, choice, TRUE);
3426f6046cfSSam Ravnborg 
3432982de69SSam Ravnborg 			print_arrows(dialog, item_count(), scroll,
34494f2505bSRoman Zippel 				     box_y, box_x + item_x + 1, menu_height);
3456f6046cfSSam Ravnborg 
3466f6046cfSSam Ravnborg 			wnoutrefresh(dialog);
3476f6046cfSSam Ravnborg 			wrefresh(menu);
3486f6046cfSSam Ravnborg 
3496f6046cfSSam Ravnborg 			continue;	/* wait for another key press */
3506f6046cfSSam Ravnborg 		}
3516f6046cfSSam Ravnborg 
3526f6046cfSSam Ravnborg 		switch (key) {
3536f6046cfSSam Ravnborg 		case KEY_LEFT:
3546f6046cfSSam Ravnborg 		case TAB:
3556f6046cfSSam Ravnborg 		case KEY_RIGHT:
3566f6046cfSSam Ravnborg 			button = ((key == KEY_LEFT ? --button : ++button) < 0)
3576364fd0cSWang YanQing 			    ? 4 : (button > 4 ? 0 : button);
3586f6046cfSSam Ravnborg 
3596f6046cfSSam Ravnborg 			print_buttons(dialog, height, width, button);
3606f6046cfSSam Ravnborg 			wrefresh(menu);
3616f6046cfSSam Ravnborg 			break;
3626f6046cfSSam Ravnborg 		case ' ':
3636f6046cfSSam Ravnborg 		case 's':
3646f6046cfSSam Ravnborg 		case 'y':
3656f6046cfSSam Ravnborg 		case 'n':
3666f6046cfSSam Ravnborg 		case 'm':
3676f6046cfSSam Ravnborg 		case '/':
36822c7eca6SLi Zefan 		case 'h':
36922c7eca6SLi Zefan 		case '?':
37022c7eca6SLi Zefan 		case 'z':
37122c7eca6SLi Zefan 		case '\n':
3726f6046cfSSam Ravnborg 			/* save scroll info */
3732982de69SSam Ravnborg 			*s_scroll = scroll;
3742982de69SSam Ravnborg 			delwin(menu);
3756f6046cfSSam Ravnborg 			delwin(dialog);
3762982de69SSam Ravnborg 			item_set(scroll + choice);
3772982de69SSam Ravnborg 			item_set_selected(1);
3786f6046cfSSam Ravnborg 			switch (key) {
37922c7eca6SLi Zefan 			case 'h':
38022c7eca6SLi Zefan 			case '?':
38122c7eca6SLi Zefan 				return 2;
3826f6046cfSSam Ravnborg 			case 's':
3836f6046cfSSam Ravnborg 			case 'y':
3846f6046cfSSam Ravnborg 				return 5;
3856364fd0cSWang YanQing 			case 'n':
3866f6046cfSSam Ravnborg 				return 6;
3876364fd0cSWang YanQing 			case 'm':
3886f6046cfSSam Ravnborg 				return 7;
3896364fd0cSWang YanQing 			case ' ':
39022c7eca6SLi Zefan 				return 8;
3916364fd0cSWang YanQing 			case '/':
3926364fd0cSWang YanQing 				return 9;
3936364fd0cSWang YanQing 			case 'z':
3946364fd0cSWang YanQing 				return 10;
39522c7eca6SLi Zefan 			case '\n':
39622c7eca6SLi Zefan 				return button;
3976f6046cfSSam Ravnborg 			}
3986f6046cfSSam Ravnborg 			return 0;
3996f6046cfSSam Ravnborg 		case 'e':
4006f6046cfSSam Ravnborg 		case 'x':
401f3cbcdc9SSam Ravnborg 			key = KEY_ESC;
402f3cbcdc9SSam Ravnborg 			break;
403f3cbcdc9SSam Ravnborg 		case KEY_ESC:
404f3cbcdc9SSam Ravnborg 			key = on_key_esc(menu);
4056f6046cfSSam Ravnborg 			break;
406c8dc68adSSam Ravnborg 		case KEY_RESIZE:
407c8dc68adSSam Ravnborg 			on_key_resize();
408c8dc68adSSam Ravnborg 			delwin(menu);
409c8dc68adSSam Ravnborg 			delwin(dialog);
410c8dc68adSSam Ravnborg 			goto do_resize;
4116f6046cfSSam Ravnborg 		}
4126f6046cfSSam Ravnborg 	}
4132982de69SSam Ravnborg 	delwin(menu);
4146f6046cfSSam Ravnborg 	delwin(dialog);
415f3cbcdc9SSam Ravnborg 	return key;		/* ESC pressed */
4166f6046cfSSam Ravnborg }
417