18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  menubox.c -- implements the menu box
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
68c2ecf20Sopenharmony_ci *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/*
108c2ecf20Sopenharmony_ci *  Changes by Clifford Wolf (god@clifford.at)
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci *  [ 1998-06-13 ]
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *    *)  A bugfix for the Page-Down problem
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *    *)  Formerly when I used Page Down and Page Up, the cursor would be set
178c2ecf20Sopenharmony_ci *        to the first position in the menu box.  Now lxdialog is a bit
188c2ecf20Sopenharmony_ci *        smarter and works more like other menu systems (just have a look at
198c2ecf20Sopenharmony_ci *        it).
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci *    *)  Formerly if I selected something my scrolling would be broken because
228c2ecf20Sopenharmony_ci *        lxdialog is re-invoked by the Menuconfig shell script, can't
238c2ecf20Sopenharmony_ci *        remember the last scrolling position, and just sets it so that the
248c2ecf20Sopenharmony_ci *        cursor is at the bottom of the box.  Now it writes the temporary file
258c2ecf20Sopenharmony_ci *        lxdialog.scrltmp which contains this information. The file is
268c2ecf20Sopenharmony_ci *        deleted by lxdialog if the user leaves a submenu or enters a new
278c2ecf20Sopenharmony_ci *        one, but it would be nice if Menuconfig could make another "rm -f"
288c2ecf20Sopenharmony_ci *        just to be sure.  Just try it out - you will recognise a difference!
298c2ecf20Sopenharmony_ci *
308c2ecf20Sopenharmony_ci *  [ 1998-06-14 ]
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
338c2ecf20Sopenharmony_ci *        and menus change their size on the fly.
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci *    *)  If for some reason the last scrolling position is not saved by
368c2ecf20Sopenharmony_ci *        lxdialog, it sets the scrolling so that the selected item is in the
378c2ecf20Sopenharmony_ci *        middle of the menu box, not at the bottom.
388c2ecf20Sopenharmony_ci *
398c2ecf20Sopenharmony_ci * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
408c2ecf20Sopenharmony_ci * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
418c2ecf20Sopenharmony_ci * This fixes a bug in Menuconfig where using ' ' to descend into menus
428c2ecf20Sopenharmony_ci * would leave mis-synchronized lxdialog.scrltmp files lying around,
438c2ecf20Sopenharmony_ci * fscanf would read in 'scroll', and eventually that value would get used.
448c2ecf20Sopenharmony_ci */
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#include "dialog.h"
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic int menu_width, item_x;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/*
518c2ecf20Sopenharmony_ci * Print menu item
528c2ecf20Sopenharmony_ci */
538c2ecf20Sopenharmony_cistatic void do_print_item(WINDOW * win, const char *item, int line_y,
548c2ecf20Sopenharmony_ci			  int selected, int hotkey)
558c2ecf20Sopenharmony_ci{
568c2ecf20Sopenharmony_ci	int j;
578c2ecf20Sopenharmony_ci	char *menu_item = malloc(menu_width + 1);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	strncpy(menu_item, item, menu_width - item_x);
608c2ecf20Sopenharmony_ci	menu_item[menu_width - item_x] = '\0';
618c2ecf20Sopenharmony_ci	j = first_alpha(menu_item, "YyNnMmHh");
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	/* Clear 'residue' of last item */
648c2ecf20Sopenharmony_ci	wattrset(win, dlg.menubox.atr);
658c2ecf20Sopenharmony_ci	wmove(win, line_y, 0);
668c2ecf20Sopenharmony_ci#if OLD_NCURSES
678c2ecf20Sopenharmony_ci	{
688c2ecf20Sopenharmony_ci		int i;
698c2ecf20Sopenharmony_ci		for (i = 0; i < menu_width; i++)
708c2ecf20Sopenharmony_ci			waddch(win, ' ');
718c2ecf20Sopenharmony_ci	}
728c2ecf20Sopenharmony_ci#else
738c2ecf20Sopenharmony_ci	wclrtoeol(win);
748c2ecf20Sopenharmony_ci#endif
758c2ecf20Sopenharmony_ci	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
768c2ecf20Sopenharmony_ci	mvwaddstr(win, line_y, item_x, menu_item);
778c2ecf20Sopenharmony_ci	if (hotkey) {
788c2ecf20Sopenharmony_ci		wattrset(win, selected ? dlg.tag_key_selected.atr
798c2ecf20Sopenharmony_ci			 : dlg.tag_key.atr);
808c2ecf20Sopenharmony_ci		mvwaddch(win, line_y, item_x + j, menu_item[j]);
818c2ecf20Sopenharmony_ci	}
828c2ecf20Sopenharmony_ci	if (selected) {
838c2ecf20Sopenharmony_ci		wmove(win, line_y, item_x + 1);
848c2ecf20Sopenharmony_ci	}
858c2ecf20Sopenharmony_ci	free(menu_item);
868c2ecf20Sopenharmony_ci	wrefresh(win);
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci#define print_item(index, choice, selected)				\
908c2ecf20Sopenharmony_cido {									\
918c2ecf20Sopenharmony_ci	item_set(index);						\
928c2ecf20Sopenharmony_ci	do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
938c2ecf20Sopenharmony_ci} while (0)
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/*
968c2ecf20Sopenharmony_ci * Print the scroll indicators.
978c2ecf20Sopenharmony_ci */
988c2ecf20Sopenharmony_cistatic void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
998c2ecf20Sopenharmony_ci			 int height)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci	int cur_y, cur_x;
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	getyx(win, cur_y, cur_x);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	wmove(win, y, x);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	if (scroll > 0) {
1088c2ecf20Sopenharmony_ci		wattrset(win, dlg.uarrow.atr);
1098c2ecf20Sopenharmony_ci		waddch(win, ACS_UARROW);
1108c2ecf20Sopenharmony_ci		waddstr(win, "(-)");
1118c2ecf20Sopenharmony_ci	} else {
1128c2ecf20Sopenharmony_ci		wattrset(win, dlg.menubox.atr);
1138c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1148c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1158c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1168c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1178c2ecf20Sopenharmony_ci	}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	y = y + height + 1;
1208c2ecf20Sopenharmony_ci	wmove(win, y, x);
1218c2ecf20Sopenharmony_ci	wrefresh(win);
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	if ((height < item_no) && (scroll + height < item_no)) {
1248c2ecf20Sopenharmony_ci		wattrset(win, dlg.darrow.atr);
1258c2ecf20Sopenharmony_ci		waddch(win, ACS_DARROW);
1268c2ecf20Sopenharmony_ci		waddstr(win, "(+)");
1278c2ecf20Sopenharmony_ci	} else {
1288c2ecf20Sopenharmony_ci		wattrset(win, dlg.menubox_border.atr);
1298c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1308c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1318c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1328c2ecf20Sopenharmony_ci		waddch(win, ACS_HLINE);
1338c2ecf20Sopenharmony_ci	}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	wmove(win, cur_y, cur_x);
1368c2ecf20Sopenharmony_ci	wrefresh(win);
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci/*
1408c2ecf20Sopenharmony_ci * Display the termination buttons.
1418c2ecf20Sopenharmony_ci */
1428c2ecf20Sopenharmony_cistatic void print_buttons(WINDOW * win, int height, int width, int selected)
1438c2ecf20Sopenharmony_ci{
1448c2ecf20Sopenharmony_ci	int x = width / 2 - 28;
1458c2ecf20Sopenharmony_ci	int y = height - 2;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	print_button(win, "Select", y, x, selected == 0);
1488c2ecf20Sopenharmony_ci	print_button(win, " Exit ", y, x + 12, selected == 1);
1498c2ecf20Sopenharmony_ci	print_button(win, " Help ", y, x + 24, selected == 2);
1508c2ecf20Sopenharmony_ci	print_button(win, " Save ", y, x + 36, selected == 3);
1518c2ecf20Sopenharmony_ci	print_button(win, " Load ", y, x + 48, selected == 4);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	wmove(win, y, x + 1 + 12 * selected);
1548c2ecf20Sopenharmony_ci	wrefresh(win);
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci/* scroll up n lines (n may be negative) */
1588c2ecf20Sopenharmony_cistatic void do_scroll(WINDOW *win, int *scroll, int n)
1598c2ecf20Sopenharmony_ci{
1608c2ecf20Sopenharmony_ci	/* Scroll menu up */
1618c2ecf20Sopenharmony_ci	scrollok(win, TRUE);
1628c2ecf20Sopenharmony_ci	wscrl(win, n);
1638c2ecf20Sopenharmony_ci	scrollok(win, FALSE);
1648c2ecf20Sopenharmony_ci	*scroll = *scroll + n;
1658c2ecf20Sopenharmony_ci	wrefresh(win);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci/*
1698c2ecf20Sopenharmony_ci * Display a menu for choosing among a number of options
1708c2ecf20Sopenharmony_ci */
1718c2ecf20Sopenharmony_ciint dialog_menu(const char *title, const char *prompt,
1728c2ecf20Sopenharmony_ci		const void *selected, int *s_scroll)
1738c2ecf20Sopenharmony_ci{
1748c2ecf20Sopenharmony_ci	int i, j, x, y, box_x, box_y;
1758c2ecf20Sopenharmony_ci	int height, width, menu_height;
1768c2ecf20Sopenharmony_ci	int key = 0, button = 0, scroll = 0, choice = 0;
1778c2ecf20Sopenharmony_ci	int first_item =  0, max_choice;
1788c2ecf20Sopenharmony_ci	WINDOW *dialog, *menu;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_cido_resize:
1818c2ecf20Sopenharmony_ci	height = getmaxy(stdscr);
1828c2ecf20Sopenharmony_ci	width = getmaxx(stdscr);
1838c2ecf20Sopenharmony_ci	if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)
1848c2ecf20Sopenharmony_ci		return -ERRDISPLAYTOOSMALL;
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	height -= 4;
1878c2ecf20Sopenharmony_ci	width  -= 5;
1888c2ecf20Sopenharmony_ci	menu_height = height - 10;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	max_choice = MIN(menu_height, item_count());
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	/* center dialog box on screen */
1938c2ecf20Sopenharmony_ci	x = (getmaxx(stdscr) - width) / 2;
1948c2ecf20Sopenharmony_ci	y = (getmaxy(stdscr) - height) / 2;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	draw_shadow(stdscr, y, x, height, width);
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	dialog = newwin(height, width, y, x);
1998c2ecf20Sopenharmony_ci	keypad(dialog, TRUE);
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci	draw_box(dialog, 0, 0, height, width,
2028c2ecf20Sopenharmony_ci		 dlg.dialog.atr, dlg.border.atr);
2038c2ecf20Sopenharmony_ci	wattrset(dialog, dlg.border.atr);
2048c2ecf20Sopenharmony_ci	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
2058c2ecf20Sopenharmony_ci	for (i = 0; i < width - 2; i++)
2068c2ecf20Sopenharmony_ci		waddch(dialog, ACS_HLINE);
2078c2ecf20Sopenharmony_ci	wattrset(dialog, dlg.dialog.atr);
2088c2ecf20Sopenharmony_ci	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
2098c2ecf20Sopenharmony_ci	waddch(dialog, ACS_RTEE);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	print_title(dialog, title, width);
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	wattrset(dialog, dlg.dialog.atr);
2148c2ecf20Sopenharmony_ci	print_autowrap(dialog, prompt, width - 2, 1, 3);
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	menu_width = width - 6;
2178c2ecf20Sopenharmony_ci	box_y = height - menu_height - 5;
2188c2ecf20Sopenharmony_ci	box_x = (width - menu_width) / 2 - 1;
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	/* create new window for the menu */
2218c2ecf20Sopenharmony_ci	menu = subwin(dialog, menu_height, menu_width,
2228c2ecf20Sopenharmony_ci		      y + box_y + 1, x + box_x + 1);
2238c2ecf20Sopenharmony_ci	keypad(menu, TRUE);
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	/* draw a box around the menu items */
2268c2ecf20Sopenharmony_ci	draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
2278c2ecf20Sopenharmony_ci		 dlg.menubox_border.atr, dlg.menubox.atr);
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	if (menu_width >= 80)
2308c2ecf20Sopenharmony_ci		item_x = (menu_width - 70) / 2;
2318c2ecf20Sopenharmony_ci	else
2328c2ecf20Sopenharmony_ci		item_x = 4;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	/* Set choice to default item */
2358c2ecf20Sopenharmony_ci	item_foreach()
2368c2ecf20Sopenharmony_ci		if (selected && (selected == item_data()))
2378c2ecf20Sopenharmony_ci			choice = item_n();
2388c2ecf20Sopenharmony_ci	/* get the saved scroll info */
2398c2ecf20Sopenharmony_ci	scroll = *s_scroll;
2408c2ecf20Sopenharmony_ci	if ((scroll <= choice) && (scroll + max_choice > choice) &&
2418c2ecf20Sopenharmony_ci	   (scroll >= 0) && (scroll + max_choice <= item_count())) {
2428c2ecf20Sopenharmony_ci		first_item = scroll;
2438c2ecf20Sopenharmony_ci		choice = choice - scroll;
2448c2ecf20Sopenharmony_ci	} else {
2458c2ecf20Sopenharmony_ci		scroll = 0;
2468c2ecf20Sopenharmony_ci	}
2478c2ecf20Sopenharmony_ci	if ((choice >= max_choice)) {
2488c2ecf20Sopenharmony_ci		if (choice >= item_count() - max_choice / 2)
2498c2ecf20Sopenharmony_ci			scroll = first_item = item_count() - max_choice;
2508c2ecf20Sopenharmony_ci		else
2518c2ecf20Sopenharmony_ci			scroll = first_item = choice - max_choice / 2;
2528c2ecf20Sopenharmony_ci		choice = choice - scroll;
2538c2ecf20Sopenharmony_ci	}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	/* Print the menu */
2568c2ecf20Sopenharmony_ci	for (i = 0; i < max_choice; i++) {
2578c2ecf20Sopenharmony_ci		print_item(first_item + i, i, i == choice);
2588c2ecf20Sopenharmony_ci	}
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	wnoutrefresh(menu);
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	print_arrows(dialog, item_count(), scroll,
2638c2ecf20Sopenharmony_ci		     box_y, box_x + item_x + 1, menu_height);
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	print_buttons(dialog, height, width, 0);
2668c2ecf20Sopenharmony_ci	wmove(menu, choice, item_x + 1);
2678c2ecf20Sopenharmony_ci	wrefresh(menu);
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	while (key != KEY_ESC) {
2708c2ecf20Sopenharmony_ci		key = wgetch(menu);
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci		if (key < 256 && isalpha(key))
2738c2ecf20Sopenharmony_ci			key = tolower(key);
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci		if (strchr("ynmh", key))
2768c2ecf20Sopenharmony_ci			i = max_choice;
2778c2ecf20Sopenharmony_ci		else {
2788c2ecf20Sopenharmony_ci			for (i = choice + 1; i < max_choice; i++) {
2798c2ecf20Sopenharmony_ci				item_set(scroll + i);
2808c2ecf20Sopenharmony_ci				j = first_alpha(item_str(), "YyNnMmHh");
2818c2ecf20Sopenharmony_ci				if (key == tolower(item_str()[j]))
2828c2ecf20Sopenharmony_ci					break;
2838c2ecf20Sopenharmony_ci			}
2848c2ecf20Sopenharmony_ci			if (i == max_choice)
2858c2ecf20Sopenharmony_ci				for (i = 0; i < max_choice; i++) {
2868c2ecf20Sopenharmony_ci					item_set(scroll + i);
2878c2ecf20Sopenharmony_ci					j = first_alpha(item_str(), "YyNnMmHh");
2888c2ecf20Sopenharmony_ci					if (key == tolower(item_str()[j]))
2898c2ecf20Sopenharmony_ci						break;
2908c2ecf20Sopenharmony_ci				}
2918c2ecf20Sopenharmony_ci		}
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci		if (item_count() != 0 &&
2948c2ecf20Sopenharmony_ci		    (i < max_choice ||
2958c2ecf20Sopenharmony_ci		     key == KEY_UP || key == KEY_DOWN ||
2968c2ecf20Sopenharmony_ci		     key == '-' || key == '+' ||
2978c2ecf20Sopenharmony_ci		     key == KEY_PPAGE || key == KEY_NPAGE)) {
2988c2ecf20Sopenharmony_ci			/* Remove highligt of current item */
2998c2ecf20Sopenharmony_ci			print_item(scroll + choice, choice, FALSE);
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci			if (key == KEY_UP || key == '-') {
3028c2ecf20Sopenharmony_ci				if (choice < 2 && scroll) {
3038c2ecf20Sopenharmony_ci					/* Scroll menu down */
3048c2ecf20Sopenharmony_ci					do_scroll(menu, &scroll, -1);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci					print_item(scroll, 0, FALSE);
3078c2ecf20Sopenharmony_ci				} else
3088c2ecf20Sopenharmony_ci					choice = MAX(choice - 1, 0);
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci			} else if (key == KEY_DOWN || key == '+') {
3118c2ecf20Sopenharmony_ci				print_item(scroll+choice, choice, FALSE);
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci				if ((choice > max_choice - 3) &&
3148c2ecf20Sopenharmony_ci				    (scroll + max_choice < item_count())) {
3158c2ecf20Sopenharmony_ci					/* Scroll menu up */
3168c2ecf20Sopenharmony_ci					do_scroll(menu, &scroll, 1);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci					print_item(scroll+max_choice - 1,
3198c2ecf20Sopenharmony_ci						   max_choice - 1, FALSE);
3208c2ecf20Sopenharmony_ci				} else
3218c2ecf20Sopenharmony_ci					choice = MIN(choice + 1, max_choice - 1);
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci			} else if (key == KEY_PPAGE) {
3248c2ecf20Sopenharmony_ci				scrollok(menu, TRUE);
3258c2ecf20Sopenharmony_ci				for (i = 0; (i < max_choice); i++) {
3268c2ecf20Sopenharmony_ci					if (scroll > 0) {
3278c2ecf20Sopenharmony_ci						do_scroll(menu, &scroll, -1);
3288c2ecf20Sopenharmony_ci						print_item(scroll, 0, FALSE);
3298c2ecf20Sopenharmony_ci					} else {
3308c2ecf20Sopenharmony_ci						if (choice > 0)
3318c2ecf20Sopenharmony_ci							choice--;
3328c2ecf20Sopenharmony_ci					}
3338c2ecf20Sopenharmony_ci				}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci			} else if (key == KEY_NPAGE) {
3368c2ecf20Sopenharmony_ci				for (i = 0; (i < max_choice); i++) {
3378c2ecf20Sopenharmony_ci					if (scroll + max_choice < item_count()) {
3388c2ecf20Sopenharmony_ci						do_scroll(menu, &scroll, 1);
3398c2ecf20Sopenharmony_ci						print_item(scroll+max_choice-1,
3408c2ecf20Sopenharmony_ci							   max_choice - 1, FALSE);
3418c2ecf20Sopenharmony_ci					} else {
3428c2ecf20Sopenharmony_ci						if (choice + 1 < max_choice)
3438c2ecf20Sopenharmony_ci							choice++;
3448c2ecf20Sopenharmony_ci					}
3458c2ecf20Sopenharmony_ci				}
3468c2ecf20Sopenharmony_ci			} else
3478c2ecf20Sopenharmony_ci				choice = i;
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci			print_item(scroll + choice, choice, TRUE);
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci			print_arrows(dialog, item_count(), scroll,
3528c2ecf20Sopenharmony_ci				     box_y, box_x + item_x + 1, menu_height);
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci			wnoutrefresh(dialog);
3558c2ecf20Sopenharmony_ci			wrefresh(menu);
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_ci			continue;	/* wait for another key press */
3588c2ecf20Sopenharmony_ci		}
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci		switch (key) {
3618c2ecf20Sopenharmony_ci		case KEY_LEFT:
3628c2ecf20Sopenharmony_ci		case TAB:
3638c2ecf20Sopenharmony_ci		case KEY_RIGHT:
3648c2ecf20Sopenharmony_ci			button = ((key == KEY_LEFT ? --button : ++button) < 0)
3658c2ecf20Sopenharmony_ci			    ? 4 : (button > 4 ? 0 : button);
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci			print_buttons(dialog, height, width, button);
3688c2ecf20Sopenharmony_ci			wrefresh(menu);
3698c2ecf20Sopenharmony_ci			break;
3708c2ecf20Sopenharmony_ci		case ' ':
3718c2ecf20Sopenharmony_ci		case 's':
3728c2ecf20Sopenharmony_ci		case 'y':
3738c2ecf20Sopenharmony_ci		case 'n':
3748c2ecf20Sopenharmony_ci		case 'm':
3758c2ecf20Sopenharmony_ci		case '/':
3768c2ecf20Sopenharmony_ci		case 'h':
3778c2ecf20Sopenharmony_ci		case '?':
3788c2ecf20Sopenharmony_ci		case 'z':
3798c2ecf20Sopenharmony_ci		case '\n':
3808c2ecf20Sopenharmony_ci			/* save scroll info */
3818c2ecf20Sopenharmony_ci			*s_scroll = scroll;
3828c2ecf20Sopenharmony_ci			delwin(menu);
3838c2ecf20Sopenharmony_ci			delwin(dialog);
3848c2ecf20Sopenharmony_ci			item_set(scroll + choice);
3858c2ecf20Sopenharmony_ci			item_set_selected(1);
3868c2ecf20Sopenharmony_ci			switch (key) {
3878c2ecf20Sopenharmony_ci			case 'h':
3888c2ecf20Sopenharmony_ci			case '?':
3898c2ecf20Sopenharmony_ci				return 2;
3908c2ecf20Sopenharmony_ci			case 's':
3918c2ecf20Sopenharmony_ci			case 'y':
3928c2ecf20Sopenharmony_ci				return 5;
3938c2ecf20Sopenharmony_ci			case 'n':
3948c2ecf20Sopenharmony_ci				return 6;
3958c2ecf20Sopenharmony_ci			case 'm':
3968c2ecf20Sopenharmony_ci				return 7;
3978c2ecf20Sopenharmony_ci			case ' ':
3988c2ecf20Sopenharmony_ci				return 8;
3998c2ecf20Sopenharmony_ci			case '/':
4008c2ecf20Sopenharmony_ci				return 9;
4018c2ecf20Sopenharmony_ci			case 'z':
4028c2ecf20Sopenharmony_ci				return 10;
4038c2ecf20Sopenharmony_ci			case '\n':
4048c2ecf20Sopenharmony_ci				return button;
4058c2ecf20Sopenharmony_ci			}
4068c2ecf20Sopenharmony_ci			return 0;
4078c2ecf20Sopenharmony_ci		case 'e':
4088c2ecf20Sopenharmony_ci		case 'x':
4098c2ecf20Sopenharmony_ci			key = KEY_ESC;
4108c2ecf20Sopenharmony_ci			break;
4118c2ecf20Sopenharmony_ci		case KEY_ESC:
4128c2ecf20Sopenharmony_ci			key = on_key_esc(menu);
4138c2ecf20Sopenharmony_ci			break;
4148c2ecf20Sopenharmony_ci		case KEY_RESIZE:
4158c2ecf20Sopenharmony_ci			on_key_resize();
4168c2ecf20Sopenharmony_ci			delwin(menu);
4178c2ecf20Sopenharmony_ci			delwin(dialog);
4188c2ecf20Sopenharmony_ci			goto do_resize;
4198c2ecf20Sopenharmony_ci		}
4208c2ecf20Sopenharmony_ci	}
4218c2ecf20Sopenharmony_ci	delwin(menu);
4228c2ecf20Sopenharmony_ci	delwin(dialog);
4238c2ecf20Sopenharmony_ci	return key;		/* ESC pressed */
4248c2ecf20Sopenharmony_ci}
425