15257cf54a5810105bc4a75703a06740d756d8e8landley/*
25257cf54a5810105bc4a75703a06740d756d8e8landley *  menubox.c -- implements the menu box
35257cf54a5810105bc4a75703a06740d756d8e8landley *
45257cf54a5810105bc4a75703a06740d756d8e8landley *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
55257cf54a5810105bc4a75703a06740d756d8e8landley *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
65257cf54a5810105bc4a75703a06740d756d8e8landley *
75257cf54a5810105bc4a75703a06740d756d8e8landley *  This program is free software; you can redistribute it and/or
85257cf54a5810105bc4a75703a06740d756d8e8landley *  modify it under the terms of the GNU General Public License
95257cf54a5810105bc4a75703a06740d756d8e8landley *  as published by the Free Software Foundation; either version 2
105257cf54a5810105bc4a75703a06740d756d8e8landley *  of the License, or (at your option) any later version.
115257cf54a5810105bc4a75703a06740d756d8e8landley *
125257cf54a5810105bc4a75703a06740d756d8e8landley *  This program is distributed in the hope that it will be useful,
135257cf54a5810105bc4a75703a06740d756d8e8landley *  but WITHOUT ANY WARRANTY; without even the implied warranty of
145257cf54a5810105bc4a75703a06740d756d8e8landley *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155257cf54a5810105bc4a75703a06740d756d8e8landley *  GNU General Public License for more details.
165257cf54a5810105bc4a75703a06740d756d8e8landley *
175257cf54a5810105bc4a75703a06740d756d8e8landley *  You should have received a copy of the GNU General Public License
185257cf54a5810105bc4a75703a06740d756d8e8landley *  along with this program; if not, write to the Free Software
195257cf54a5810105bc4a75703a06740d756d8e8landley *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
205257cf54a5810105bc4a75703a06740d756d8e8landley */
215257cf54a5810105bc4a75703a06740d756d8e8landley
225257cf54a5810105bc4a75703a06740d756d8e8landley/*
235257cf54a5810105bc4a75703a06740d756d8e8landley *  Changes by Clifford Wolf (god@clifford.at)
245257cf54a5810105bc4a75703a06740d756d8e8landley *
255257cf54a5810105bc4a75703a06740d756d8e8landley *  [ 1998-06-13 ]
265257cf54a5810105bc4a75703a06740d756d8e8landley *
275257cf54a5810105bc4a75703a06740d756d8e8landley *    *)  A bugfix for the Page-Down problem
285257cf54a5810105bc4a75703a06740d756d8e8landley *
295257cf54a5810105bc4a75703a06740d756d8e8landley *    *)  Formerly when I used Page Down and Page Up, the cursor would be set
305257cf54a5810105bc4a75703a06740d756d8e8landley *        to the first position in the menu box.  Now lxdialog is a bit
315257cf54a5810105bc4a75703a06740d756d8e8landley *        smarter and works more like other menu systems (just have a look at
325257cf54a5810105bc4a75703a06740d756d8e8landley *        it).
335257cf54a5810105bc4a75703a06740d756d8e8landley *
345257cf54a5810105bc4a75703a06740d756d8e8landley *    *)  Formerly if I selected something my scrolling would be broken because
355257cf54a5810105bc4a75703a06740d756d8e8landley *        lxdialog is re-invoked by the Menuconfig shell script, can't
365257cf54a5810105bc4a75703a06740d756d8e8landley *        remember the last scrolling position, and just sets it so that the
375257cf54a5810105bc4a75703a06740d756d8e8landley *        cursor is at the bottom of the box.  Now it writes the temporary file
385257cf54a5810105bc4a75703a06740d756d8e8landley *        lxdialog.scrltmp which contains this information. The file is
395257cf54a5810105bc4a75703a06740d756d8e8landley *        deleted by lxdialog if the user leaves a submenu or enters a new
405257cf54a5810105bc4a75703a06740d756d8e8landley *        one, but it would be nice if Menuconfig could make another "rm -f"
415257cf54a5810105bc4a75703a06740d756d8e8landley *        just to be sure.  Just try it out - you will recognise a difference!
425257cf54a5810105bc4a75703a06740d756d8e8landley *
435257cf54a5810105bc4a75703a06740d756d8e8landley *  [ 1998-06-14 ]
445257cf54a5810105bc4a75703a06740d756d8e8landley *
455257cf54a5810105bc4a75703a06740d756d8e8landley *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
465257cf54a5810105bc4a75703a06740d756d8e8landley *        and menus change their size on the fly.
475257cf54a5810105bc4a75703a06740d756d8e8landley *
485257cf54a5810105bc4a75703a06740d756d8e8landley *    *)  If for some reason the last scrolling position is not saved by
495257cf54a5810105bc4a75703a06740d756d8e8landley *        lxdialog, it sets the scrolling so that the selected item is in the
505257cf54a5810105bc4a75703a06740d756d8e8landley *        middle of the menu box, not at the bottom.
515257cf54a5810105bc4a75703a06740d756d8e8landley *
525257cf54a5810105bc4a75703a06740d756d8e8landley * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
535257cf54a5810105bc4a75703a06740d756d8e8landley * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
545257cf54a5810105bc4a75703a06740d756d8e8landley * This fixes a bug in Menuconfig where using ' ' to descend into menus
555257cf54a5810105bc4a75703a06740d756d8e8landley * would leave mis-synchronized lxdialog.scrltmp files lying around,
565257cf54a5810105bc4a75703a06740d756d8e8landley * fscanf would read in 'scroll', and eventually that value would get used.
575257cf54a5810105bc4a75703a06740d756d8e8landley */
585257cf54a5810105bc4a75703a06740d756d8e8landley
595257cf54a5810105bc4a75703a06740d756d8e8landley#include "dialog.h"
605257cf54a5810105bc4a75703a06740d756d8e8landley
615257cf54a5810105bc4a75703a06740d756d8e8landleystatic int menu_width, item_x;
625257cf54a5810105bc4a75703a06740d756d8e8landley
635257cf54a5810105bc4a75703a06740d756d8e8landley/*
645257cf54a5810105bc4a75703a06740d756d8e8landley * Print menu item
655257cf54a5810105bc4a75703a06740d756d8e8landley */
665257cf54a5810105bc4a75703a06740d756d8e8landleystatic void do_print_item(WINDOW * win, const char *item, int line_y,
675257cf54a5810105bc4a75703a06740d756d8e8landley                          int selected, int hotkey)
685257cf54a5810105bc4a75703a06740d756d8e8landley{
695257cf54a5810105bc4a75703a06740d756d8e8landley	int j;
705257cf54a5810105bc4a75703a06740d756d8e8landley	char *menu_item = malloc(menu_width + 1);
715257cf54a5810105bc4a75703a06740d756d8e8landley
725257cf54a5810105bc4a75703a06740d756d8e8landley	strncpy(menu_item, item, menu_width - item_x);
735257cf54a5810105bc4a75703a06740d756d8e8landley	menu_item[menu_width - item_x] = '\0';
745257cf54a5810105bc4a75703a06740d756d8e8landley	j = first_alpha(menu_item, "YyNnMmHh");
755257cf54a5810105bc4a75703a06740d756d8e8landley
765257cf54a5810105bc4a75703a06740d756d8e8landley	/* Clear 'residue' of last item */
775257cf54a5810105bc4a75703a06740d756d8e8landley	wattrset(win, dlg.menubox.atr);
785257cf54a5810105bc4a75703a06740d756d8e8landley	wmove(win, line_y, 0);
795257cf54a5810105bc4a75703a06740d756d8e8landley#if OLD_NCURSES
805257cf54a5810105bc4a75703a06740d756d8e8landley	{
815257cf54a5810105bc4a75703a06740d756d8e8landley		int i;
825257cf54a5810105bc4a75703a06740d756d8e8landley		for (i = 0; i < menu_width; i++)
835257cf54a5810105bc4a75703a06740d756d8e8landley			waddch(win, ' ');
845257cf54a5810105bc4a75703a06740d756d8e8landley	}
855257cf54a5810105bc4a75703a06740d756d8e8landley#else
865257cf54a5810105bc4a75703a06740d756d8e8landley	wclrtoeol(win);
875257cf54a5810105bc4a75703a06740d756d8e8landley#endif
885257cf54a5810105bc4a75703a06740d756d8e8landley	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
895257cf54a5810105bc4a75703a06740d756d8e8landley	mvwaddstr(win, line_y, item_x, menu_item);
905257cf54a5810105bc4a75703a06740d756d8e8landley	if (hotkey) {
915257cf54a5810105bc4a75703a06740d756d8e8landley		wattrset(win, selected ? dlg.tag_key_selected.atr
925257cf54a5810105bc4a75703a06740d756d8e8landley			 : dlg.tag_key.atr);
935257cf54a5810105bc4a75703a06740d756d8e8landley		mvwaddch(win, line_y, item_x + j, menu_item[j]);
945257cf54a5810105bc4a75703a06740d756d8e8landley	}
955257cf54a5810105bc4a75703a06740d756d8e8landley	if (selected) {
965257cf54a5810105bc4a75703a06740d756d8e8landley		wmove(win, line_y, item_x + 1);
975257cf54a5810105bc4a75703a06740d756d8e8landley	}
985257cf54a5810105bc4a75703a06740d756d8e8landley	free(menu_item);
995257cf54a5810105bc4a75703a06740d756d8e8landley	wrefresh(win);
1005257cf54a5810105bc4a75703a06740d756d8e8landley}
1015257cf54a5810105bc4a75703a06740d756d8e8landley
1025257cf54a5810105bc4a75703a06740d756d8e8landley#define print_item(index, choice, selected)				\
1035257cf54a5810105bc4a75703a06740d756d8e8landleydo {									\
1045257cf54a5810105bc4a75703a06740d756d8e8landley	item_set(index);						\
1055257cf54a5810105bc4a75703a06740d756d8e8landley	do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
1065257cf54a5810105bc4a75703a06740d756d8e8landley} while (0)
1075257cf54a5810105bc4a75703a06740d756d8e8landley
1085257cf54a5810105bc4a75703a06740d756d8e8landley/*
1095257cf54a5810105bc4a75703a06740d756d8e8landley * Print the scroll indicators.
1105257cf54a5810105bc4a75703a06740d756d8e8landley */
1115257cf54a5810105bc4a75703a06740d756d8e8landleystatic void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
1125257cf54a5810105bc4a75703a06740d756d8e8landley			 int height)
1135257cf54a5810105bc4a75703a06740d756d8e8landley{
1145257cf54a5810105bc4a75703a06740d756d8e8landley	int cur_y, cur_x;
1155257cf54a5810105bc4a75703a06740d756d8e8landley
1165257cf54a5810105bc4a75703a06740d756d8e8landley	getyx(win, cur_y, cur_x);
1175257cf54a5810105bc4a75703a06740d756d8e8landley
1185257cf54a5810105bc4a75703a06740d756d8e8landley	wmove(win, y, x);
1195257cf54a5810105bc4a75703a06740d756d8e8landley
1205257cf54a5810105bc4a75703a06740d756d8e8landley	if (scroll > 0) {
1215257cf54a5810105bc4a75703a06740d756d8e8landley		wattrset(win, dlg.uarrow.atr);
1225257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_UARROW);
1235257cf54a5810105bc4a75703a06740d756d8e8landley		waddstr(win, "(-)");
1245257cf54a5810105bc4a75703a06740d756d8e8landley	} else {
1255257cf54a5810105bc4a75703a06740d756d8e8landley		wattrset(win, dlg.menubox.atr);
1265257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1275257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1285257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1295257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1305257cf54a5810105bc4a75703a06740d756d8e8landley	}
1315257cf54a5810105bc4a75703a06740d756d8e8landley
1325257cf54a5810105bc4a75703a06740d756d8e8landley	y = y + height + 1;
1335257cf54a5810105bc4a75703a06740d756d8e8landley	wmove(win, y, x);
1345257cf54a5810105bc4a75703a06740d756d8e8landley	wrefresh(win);
1355257cf54a5810105bc4a75703a06740d756d8e8landley
1365257cf54a5810105bc4a75703a06740d756d8e8landley	if ((height < item_no) && (scroll + height < item_no)) {
1375257cf54a5810105bc4a75703a06740d756d8e8landley		wattrset(win, dlg.darrow.atr);
1385257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_DARROW);
1395257cf54a5810105bc4a75703a06740d756d8e8landley		waddstr(win, "(+)");
1405257cf54a5810105bc4a75703a06740d756d8e8landley	} else {
1415257cf54a5810105bc4a75703a06740d756d8e8landley		wattrset(win, dlg.menubox_border.atr);
1425257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1435257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1445257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1455257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(win, ACS_HLINE);
1465257cf54a5810105bc4a75703a06740d756d8e8landley	}
1475257cf54a5810105bc4a75703a06740d756d8e8landley
1485257cf54a5810105bc4a75703a06740d756d8e8landley	wmove(win, cur_y, cur_x);
1495257cf54a5810105bc4a75703a06740d756d8e8landley	wrefresh(win);
1505257cf54a5810105bc4a75703a06740d756d8e8landley}
1515257cf54a5810105bc4a75703a06740d756d8e8landley
1525257cf54a5810105bc4a75703a06740d756d8e8landley/*
1535257cf54a5810105bc4a75703a06740d756d8e8landley * Display the termination buttons.
1545257cf54a5810105bc4a75703a06740d756d8e8landley */
1555257cf54a5810105bc4a75703a06740d756d8e8landleystatic void print_buttons(WINDOW * win, int height, int width, int selected)
1565257cf54a5810105bc4a75703a06740d756d8e8landley{
1575257cf54a5810105bc4a75703a06740d756d8e8landley	int x = width / 2 - 16;
1585257cf54a5810105bc4a75703a06740d756d8e8landley	int y = height - 2;
1595257cf54a5810105bc4a75703a06740d756d8e8landley
1605257cf54a5810105bc4a75703a06740d756d8e8landley	print_button(win, "Select", y, x, selected == 0);
1615257cf54a5810105bc4a75703a06740d756d8e8landley	print_button(win, " Exit ", y, x + 12, selected == 1);
1625257cf54a5810105bc4a75703a06740d756d8e8landley	print_button(win, " Help ", y, x + 24, selected == 2);
1635257cf54a5810105bc4a75703a06740d756d8e8landley
1645257cf54a5810105bc4a75703a06740d756d8e8landley	wmove(win, y, x + 1 + 12 * selected);
1655257cf54a5810105bc4a75703a06740d756d8e8landley	wrefresh(win);
1665257cf54a5810105bc4a75703a06740d756d8e8landley}
1675257cf54a5810105bc4a75703a06740d756d8e8landley
1685257cf54a5810105bc4a75703a06740d756d8e8landley/* scroll up n lines (n may be negative) */
1695257cf54a5810105bc4a75703a06740d756d8e8landleystatic void do_scroll(WINDOW *win, int *scroll, int n)
1705257cf54a5810105bc4a75703a06740d756d8e8landley{
1715257cf54a5810105bc4a75703a06740d756d8e8landley	/* Scroll menu up */
1725257cf54a5810105bc4a75703a06740d756d8e8landley	scrollok(win, TRUE);
1735257cf54a5810105bc4a75703a06740d756d8e8landley	wscrl(win, n);
1745257cf54a5810105bc4a75703a06740d756d8e8landley	scrollok(win, FALSE);
1755257cf54a5810105bc4a75703a06740d756d8e8landley	*scroll = *scroll + n;
1765257cf54a5810105bc4a75703a06740d756d8e8landley	wrefresh(win);
1775257cf54a5810105bc4a75703a06740d756d8e8landley}
1785257cf54a5810105bc4a75703a06740d756d8e8landley
1795257cf54a5810105bc4a75703a06740d756d8e8landley/*
1805257cf54a5810105bc4a75703a06740d756d8e8landley * Display a menu for choosing among a number of options
1815257cf54a5810105bc4a75703a06740d756d8e8landley */
1825257cf54a5810105bc4a75703a06740d756d8e8landleyint dialog_menu(const char *title, const char *prompt,
1835257cf54a5810105bc4a75703a06740d756d8e8landley                const void *selected, int *s_scroll)
1845257cf54a5810105bc4a75703a06740d756d8e8landley{
1855257cf54a5810105bc4a75703a06740d756d8e8landley	int i, j, x, y, box_x, box_y;
1865257cf54a5810105bc4a75703a06740d756d8e8landley	int height, width, menu_height;
1875257cf54a5810105bc4a75703a06740d756d8e8landley	int key = 0, button = 0, scroll = 0, choice = 0;
1885257cf54a5810105bc4a75703a06740d756d8e8landley	int first_item =  0, max_choice;
1895257cf54a5810105bc4a75703a06740d756d8e8landley	WINDOW *dialog, *menu;
1905257cf54a5810105bc4a75703a06740d756d8e8landley
1915257cf54a5810105bc4a75703a06740d756d8e8landleydo_resize:
1925257cf54a5810105bc4a75703a06740d756d8e8landley	height = getmaxy(stdscr);
1935257cf54a5810105bc4a75703a06740d756d8e8landley	width = getmaxx(stdscr);
1945257cf54a5810105bc4a75703a06740d756d8e8landley	if (height < 15 || width < 65)
1955257cf54a5810105bc4a75703a06740d756d8e8landley		return -ERRDISPLAYTOOSMALL;
1965257cf54a5810105bc4a75703a06740d756d8e8landley
1975257cf54a5810105bc4a75703a06740d756d8e8landley	height -= 4;
1985257cf54a5810105bc4a75703a06740d756d8e8landley	width  -= 5;
1995257cf54a5810105bc4a75703a06740d756d8e8landley	menu_height = height - 10;
2005257cf54a5810105bc4a75703a06740d756d8e8landley
2015257cf54a5810105bc4a75703a06740d756d8e8landley	max_choice = MIN(menu_height, item_count());
2025257cf54a5810105bc4a75703a06740d756d8e8landley
2035257cf54a5810105bc4a75703a06740d756d8e8landley	/* center dialog box on screen */
2045257cf54a5810105bc4a75703a06740d756d8e8landley	x = (COLS - width) / 2;
2055257cf54a5810105bc4a75703a06740d756d8e8landley	y = (LINES - height) / 2;
2065257cf54a5810105bc4a75703a06740d756d8e8landley
2075257cf54a5810105bc4a75703a06740d756d8e8landley	draw_shadow(stdscr, y, x, height, width);
2085257cf54a5810105bc4a75703a06740d756d8e8landley
2095257cf54a5810105bc4a75703a06740d756d8e8landley	dialog = newwin(height, width, y, x);
2105257cf54a5810105bc4a75703a06740d756d8e8landley	keypad(dialog, TRUE);
2115257cf54a5810105bc4a75703a06740d756d8e8landley
2125257cf54a5810105bc4a75703a06740d756d8e8landley	draw_box(dialog, 0, 0, height, width,
2135257cf54a5810105bc4a75703a06740d756d8e8landley		 dlg.dialog.atr, dlg.border.atr);
2145257cf54a5810105bc4a75703a06740d756d8e8landley	wattrset(dialog, dlg.border.atr);
2155257cf54a5810105bc4a75703a06740d756d8e8landley	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
2165257cf54a5810105bc4a75703a06740d756d8e8landley	for (i = 0; i < width - 2; i++)
2175257cf54a5810105bc4a75703a06740d756d8e8landley		waddch(dialog, ACS_HLINE);
2185257cf54a5810105bc4a75703a06740d756d8e8landley	wattrset(dialog, dlg.dialog.atr);
2195257cf54a5810105bc4a75703a06740d756d8e8landley	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
2205257cf54a5810105bc4a75703a06740d756d8e8landley	waddch(dialog, ACS_RTEE);
2215257cf54a5810105bc4a75703a06740d756d8e8landley
2225257cf54a5810105bc4a75703a06740d756d8e8landley	print_title(dialog, title, width);
2235257cf54a5810105bc4a75703a06740d756d8e8landley
2245257cf54a5810105bc4a75703a06740d756d8e8landley	wattrset(dialog, dlg.dialog.atr);
2255257cf54a5810105bc4a75703a06740d756d8e8landley	print_autowrap(dialog, prompt, width - 2, 1, 3);
2265257cf54a5810105bc4a75703a06740d756d8e8landley
2275257cf54a5810105bc4a75703a06740d756d8e8landley	menu_width = width - 6;
2285257cf54a5810105bc4a75703a06740d756d8e8landley	box_y = height - menu_height - 5;
2295257cf54a5810105bc4a75703a06740d756d8e8landley	box_x = (width - menu_width) / 2 - 1;
2305257cf54a5810105bc4a75703a06740d756d8e8landley
2315257cf54a5810105bc4a75703a06740d756d8e8landley	/* create new window for the menu */
2325257cf54a5810105bc4a75703a06740d756d8e8landley	menu = subwin(dialog, menu_height, menu_width,
2335257cf54a5810105bc4a75703a06740d756d8e8landley		      y + box_y + 1, x + box_x + 1);
2345257cf54a5810105bc4a75703a06740d756d8e8landley	keypad(menu, TRUE);
2355257cf54a5810105bc4a75703a06740d756d8e8landley
2365257cf54a5810105bc4a75703a06740d756d8e8landley	/* draw a box around the menu items */
2375257cf54a5810105bc4a75703a06740d756d8e8landley	draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
2385257cf54a5810105bc4a75703a06740d756d8e8landley		 dlg.menubox_border.atr, dlg.menubox.atr);
2395257cf54a5810105bc4a75703a06740d756d8e8landley
2405257cf54a5810105bc4a75703a06740d756d8e8landley	if (menu_width >= 80)
2415257cf54a5810105bc4a75703a06740d756d8e8landley		item_x = (menu_width - 70) / 2;
2425257cf54a5810105bc4a75703a06740d756d8e8landley	else
2435257cf54a5810105bc4a75703a06740d756d8e8landley		item_x = 4;
2445257cf54a5810105bc4a75703a06740d756d8e8landley
2455257cf54a5810105bc4a75703a06740d756d8e8landley	/* Set choice to default item */
2465257cf54a5810105bc4a75703a06740d756d8e8landley	item_foreach()
2475257cf54a5810105bc4a75703a06740d756d8e8landley		if (selected && (selected == item_data()))
2485257cf54a5810105bc4a75703a06740d756d8e8landley			choice = item_n();
2495257cf54a5810105bc4a75703a06740d756d8e8landley	/* get the saved scroll info */
2505257cf54a5810105bc4a75703a06740d756d8e8landley	scroll = *s_scroll;
2515257cf54a5810105bc4a75703a06740d756d8e8landley	if ((scroll <= choice) && (scroll + max_choice > choice) &&
2525257cf54a5810105bc4a75703a06740d756d8e8landley	   (scroll >= 0) && (scroll + max_choice <= item_count())) {
2535257cf54a5810105bc4a75703a06740d756d8e8landley		first_item = scroll;
2545257cf54a5810105bc4a75703a06740d756d8e8landley		choice = choice - scroll;
2555257cf54a5810105bc4a75703a06740d756d8e8landley	} else {
2565257cf54a5810105bc4a75703a06740d756d8e8landley		scroll = 0;
2575257cf54a5810105bc4a75703a06740d756d8e8landley	}
2585257cf54a5810105bc4a75703a06740d756d8e8landley	if ((choice >= max_choice)) {
2595257cf54a5810105bc4a75703a06740d756d8e8landley		if (choice >= item_count() - max_choice / 2)
2605257cf54a5810105bc4a75703a06740d756d8e8landley			scroll = first_item = item_count() - max_choice;
2615257cf54a5810105bc4a75703a06740d756d8e8landley		else
2625257cf54a5810105bc4a75703a06740d756d8e8landley			scroll = first_item = choice - max_choice / 2;
2635257cf54a5810105bc4a75703a06740d756d8e8landley		choice = choice - scroll;
2645257cf54a5810105bc4a75703a06740d756d8e8landley	}
2655257cf54a5810105bc4a75703a06740d756d8e8landley
2665257cf54a5810105bc4a75703a06740d756d8e8landley	/* Print the menu */
2675257cf54a5810105bc4a75703a06740d756d8e8landley	for (i = 0; i < max_choice; i++) {
2685257cf54a5810105bc4a75703a06740d756d8e8landley		print_item(first_item + i, i, i == choice);
2695257cf54a5810105bc4a75703a06740d756d8e8landley	}
2705257cf54a5810105bc4a75703a06740d756d8e8landley
2715257cf54a5810105bc4a75703a06740d756d8e8landley	wnoutrefresh(menu);
2725257cf54a5810105bc4a75703a06740d756d8e8landley
2735257cf54a5810105bc4a75703a06740d756d8e8landley	print_arrows(dialog, item_count(), scroll,
2745257cf54a5810105bc4a75703a06740d756d8e8landley		     box_y, box_x + item_x + 1, menu_height);
2755257cf54a5810105bc4a75703a06740d756d8e8landley
2765257cf54a5810105bc4a75703a06740d756d8e8landley	print_buttons(dialog, height, width, 0);
2775257cf54a5810105bc4a75703a06740d756d8e8landley	wmove(menu, choice, item_x + 1);
2785257cf54a5810105bc4a75703a06740d756d8e8landley	wrefresh(menu);
2795257cf54a5810105bc4a75703a06740d756d8e8landley
2805257cf54a5810105bc4a75703a06740d756d8e8landley	while (key != KEY_ESC) {
2815257cf54a5810105bc4a75703a06740d756d8e8landley		key = wgetch(menu);
2825257cf54a5810105bc4a75703a06740d756d8e8landley
2835257cf54a5810105bc4a75703a06740d756d8e8landley		if (key < 256 && isalpha(key))
2845257cf54a5810105bc4a75703a06740d756d8e8landley			key = tolower(key);
2855257cf54a5810105bc4a75703a06740d756d8e8landley
2865257cf54a5810105bc4a75703a06740d756d8e8landley		if (strchr("ynmh", key))
2875257cf54a5810105bc4a75703a06740d756d8e8landley			i = max_choice;
2885257cf54a5810105bc4a75703a06740d756d8e8landley		else {
2895257cf54a5810105bc4a75703a06740d756d8e8landley			for (i = choice + 1; i < max_choice; i++) {
2905257cf54a5810105bc4a75703a06740d756d8e8landley				item_set(scroll + i);
2915257cf54a5810105bc4a75703a06740d756d8e8landley				j = first_alpha(item_str(), "YyNnMmHh");
2925257cf54a5810105bc4a75703a06740d756d8e8landley				if (key == tolower(item_str()[j]))
2935257cf54a5810105bc4a75703a06740d756d8e8landley					break;
2945257cf54a5810105bc4a75703a06740d756d8e8landley			}
2955257cf54a5810105bc4a75703a06740d756d8e8landley			if (i == max_choice)
2965257cf54a5810105bc4a75703a06740d756d8e8landley				for (i = 0; i < max_choice; i++) {
2975257cf54a5810105bc4a75703a06740d756d8e8landley					item_set(scroll + i);
2985257cf54a5810105bc4a75703a06740d756d8e8landley					j = first_alpha(item_str(), "YyNnMmHh");
2995257cf54a5810105bc4a75703a06740d756d8e8landley					if (key == tolower(item_str()[j]))
3005257cf54a5810105bc4a75703a06740d756d8e8landley						break;
3015257cf54a5810105bc4a75703a06740d756d8e8landley				}
3025257cf54a5810105bc4a75703a06740d756d8e8landley		}
3035257cf54a5810105bc4a75703a06740d756d8e8landley
3045257cf54a5810105bc4a75703a06740d756d8e8landley		if (i < max_choice ||
3055257cf54a5810105bc4a75703a06740d756d8e8landley		    key == KEY_UP || key == KEY_DOWN ||
3065257cf54a5810105bc4a75703a06740d756d8e8landley		    key == '-' || key == '+' ||
3075257cf54a5810105bc4a75703a06740d756d8e8landley		    key == KEY_PPAGE || key == KEY_NPAGE) {
3085257cf54a5810105bc4a75703a06740d756d8e8landley			/* Remove highligt of current item */
3095257cf54a5810105bc4a75703a06740d756d8e8landley			print_item(scroll + choice, choice, FALSE);
3105257cf54a5810105bc4a75703a06740d756d8e8landley
3115257cf54a5810105bc4a75703a06740d756d8e8landley			if (key == KEY_UP || key == '-') {
3125257cf54a5810105bc4a75703a06740d756d8e8landley				if (choice < 2 && scroll) {
3135257cf54a5810105bc4a75703a06740d756d8e8landley					/* Scroll menu down */
3145257cf54a5810105bc4a75703a06740d756d8e8landley					do_scroll(menu, &scroll, -1);
3155257cf54a5810105bc4a75703a06740d756d8e8landley
3165257cf54a5810105bc4a75703a06740d756d8e8landley					print_item(scroll, 0, FALSE);
3175257cf54a5810105bc4a75703a06740d756d8e8landley				} else
3185257cf54a5810105bc4a75703a06740d756d8e8landley					choice = MAX(choice - 1, 0);
3195257cf54a5810105bc4a75703a06740d756d8e8landley
3205257cf54a5810105bc4a75703a06740d756d8e8landley			} else if (key == KEY_DOWN || key == '+') {
3215257cf54a5810105bc4a75703a06740d756d8e8landley				print_item(scroll+choice, choice, FALSE);
3225257cf54a5810105bc4a75703a06740d756d8e8landley
3235257cf54a5810105bc4a75703a06740d756d8e8landley				if ((choice > max_choice - 3) &&
3245257cf54a5810105bc4a75703a06740d756d8e8landley				    (scroll + max_choice < item_count())) {
3255257cf54a5810105bc4a75703a06740d756d8e8landley					/* Scroll menu up */
3265257cf54a5810105bc4a75703a06740d756d8e8landley					do_scroll(menu, &scroll, 1);
3275257cf54a5810105bc4a75703a06740d756d8e8landley
3285257cf54a5810105bc4a75703a06740d756d8e8landley					print_item(scroll+max_choice - 1,
3295257cf54a5810105bc4a75703a06740d756d8e8landley						   max_choice - 1, FALSE);
3305257cf54a5810105bc4a75703a06740d756d8e8landley				} else
3315257cf54a5810105bc4a75703a06740d756d8e8landley					choice = MIN(choice + 1, max_choice - 1);
3325257cf54a5810105bc4a75703a06740d756d8e8landley
3335257cf54a5810105bc4a75703a06740d756d8e8landley			} else if (key == KEY_PPAGE) {
3345257cf54a5810105bc4a75703a06740d756d8e8landley				scrollok(menu, TRUE);
3355257cf54a5810105bc4a75703a06740d756d8e8landley				for (i = 0; (i < max_choice); i++) {
3365257cf54a5810105bc4a75703a06740d756d8e8landley					if (scroll > 0) {
3375257cf54a5810105bc4a75703a06740d756d8e8landley						do_scroll(menu, &scroll, -1);
3385257cf54a5810105bc4a75703a06740d756d8e8landley						print_item(scroll, 0, FALSE);
3395257cf54a5810105bc4a75703a06740d756d8e8landley					} else {
3405257cf54a5810105bc4a75703a06740d756d8e8landley						if (choice > 0)
3415257cf54a5810105bc4a75703a06740d756d8e8landley							choice--;
3425257cf54a5810105bc4a75703a06740d756d8e8landley					}
3435257cf54a5810105bc4a75703a06740d756d8e8landley				}
3445257cf54a5810105bc4a75703a06740d756d8e8landley
3455257cf54a5810105bc4a75703a06740d756d8e8landley			} else if (key == KEY_NPAGE) {
3465257cf54a5810105bc4a75703a06740d756d8e8landley				for (i = 0; (i < max_choice); i++) {
3475257cf54a5810105bc4a75703a06740d756d8e8landley					if (scroll + max_choice < item_count()) {
3485257cf54a5810105bc4a75703a06740d756d8e8landley						do_scroll(menu, &scroll, 1);
3495257cf54a5810105bc4a75703a06740d756d8e8landley						print_item(scroll+max_choice-1,
3505257cf54a5810105bc4a75703a06740d756d8e8landley							   max_choice - 1, FALSE);
3515257cf54a5810105bc4a75703a06740d756d8e8landley					} else {
3525257cf54a5810105bc4a75703a06740d756d8e8landley						if (choice + 1 < max_choice)
3535257cf54a5810105bc4a75703a06740d756d8e8landley							choice++;
3545257cf54a5810105bc4a75703a06740d756d8e8landley					}
3555257cf54a5810105bc4a75703a06740d756d8e8landley				}
3565257cf54a5810105bc4a75703a06740d756d8e8landley			} else
3575257cf54a5810105bc4a75703a06740d756d8e8landley				choice = i;
3585257cf54a5810105bc4a75703a06740d756d8e8landley
3595257cf54a5810105bc4a75703a06740d756d8e8landley			print_item(scroll + choice, choice, TRUE);
3605257cf54a5810105bc4a75703a06740d756d8e8landley
3615257cf54a5810105bc4a75703a06740d756d8e8landley			print_arrows(dialog, item_count(), scroll,
3625257cf54a5810105bc4a75703a06740d756d8e8landley				     box_y, box_x + item_x + 1, menu_height);
3635257cf54a5810105bc4a75703a06740d756d8e8landley
3645257cf54a5810105bc4a75703a06740d756d8e8landley			wnoutrefresh(dialog);
3655257cf54a5810105bc4a75703a06740d756d8e8landley			wrefresh(menu);
3665257cf54a5810105bc4a75703a06740d756d8e8landley
3675257cf54a5810105bc4a75703a06740d756d8e8landley			continue;	/* wait for another key press */
3685257cf54a5810105bc4a75703a06740d756d8e8landley		}
3695257cf54a5810105bc4a75703a06740d756d8e8landley
3705257cf54a5810105bc4a75703a06740d756d8e8landley		switch (key) {
3715257cf54a5810105bc4a75703a06740d756d8e8landley		case KEY_LEFT:
3725257cf54a5810105bc4a75703a06740d756d8e8landley		case TAB:
3735257cf54a5810105bc4a75703a06740d756d8e8landley		case KEY_RIGHT:
3745257cf54a5810105bc4a75703a06740d756d8e8landley			button = ((key == KEY_LEFT ? --button : ++button) < 0)
3755257cf54a5810105bc4a75703a06740d756d8e8landley			    ? 2 : (button > 2 ? 0 : button);
3765257cf54a5810105bc4a75703a06740d756d8e8landley
3775257cf54a5810105bc4a75703a06740d756d8e8landley			print_buttons(dialog, height, width, button);
3785257cf54a5810105bc4a75703a06740d756d8e8landley			wrefresh(menu);
3795257cf54a5810105bc4a75703a06740d756d8e8landley			break;
3805257cf54a5810105bc4a75703a06740d756d8e8landley		case ' ':
3815257cf54a5810105bc4a75703a06740d756d8e8landley		case 's':
3825257cf54a5810105bc4a75703a06740d756d8e8landley		case 'y':
3835257cf54a5810105bc4a75703a06740d756d8e8landley		case 'n':
3845257cf54a5810105bc4a75703a06740d756d8e8landley		case 'm':
3855257cf54a5810105bc4a75703a06740d756d8e8landley		case '/':
3865257cf54a5810105bc4a75703a06740d756d8e8landley			/* save scroll info */
3875257cf54a5810105bc4a75703a06740d756d8e8landley			*s_scroll = scroll;
3885257cf54a5810105bc4a75703a06740d756d8e8landley			delwin(menu);
3895257cf54a5810105bc4a75703a06740d756d8e8landley			delwin(dialog);
3905257cf54a5810105bc4a75703a06740d756d8e8landley			item_set(scroll + choice);
3915257cf54a5810105bc4a75703a06740d756d8e8landley			item_set_selected(1);
3925257cf54a5810105bc4a75703a06740d756d8e8landley			switch (key) {
3935257cf54a5810105bc4a75703a06740d756d8e8landley			case 's':
3945257cf54a5810105bc4a75703a06740d756d8e8landley				return 3;
3955257cf54a5810105bc4a75703a06740d756d8e8landley			case 'y':
3965257cf54a5810105bc4a75703a06740d756d8e8landley				return 3;
3975257cf54a5810105bc4a75703a06740d756d8e8landley			case 'n':
3985257cf54a5810105bc4a75703a06740d756d8e8landley				return 4;
3995257cf54a5810105bc4a75703a06740d756d8e8landley			case 'm':
4005257cf54a5810105bc4a75703a06740d756d8e8landley				return 5;
4015257cf54a5810105bc4a75703a06740d756d8e8landley			case ' ':
4025257cf54a5810105bc4a75703a06740d756d8e8landley				return 6;
4035257cf54a5810105bc4a75703a06740d756d8e8landley			case '/':
4045257cf54a5810105bc4a75703a06740d756d8e8landley				return 7;
4055257cf54a5810105bc4a75703a06740d756d8e8landley			}
4065257cf54a5810105bc4a75703a06740d756d8e8landley			return 0;
4075257cf54a5810105bc4a75703a06740d756d8e8landley		case 'h':
4085257cf54a5810105bc4a75703a06740d756d8e8landley		case '?':
4095257cf54a5810105bc4a75703a06740d756d8e8landley			button = 2;
4105257cf54a5810105bc4a75703a06740d756d8e8landley		case '\n':
4115257cf54a5810105bc4a75703a06740d756d8e8landley			*s_scroll = scroll;
4125257cf54a5810105bc4a75703a06740d756d8e8landley			delwin(menu);
4135257cf54a5810105bc4a75703a06740d756d8e8landley			delwin(dialog);
4145257cf54a5810105bc4a75703a06740d756d8e8landley			item_set(scroll + choice);
4155257cf54a5810105bc4a75703a06740d756d8e8landley			item_set_selected(1);
4165257cf54a5810105bc4a75703a06740d756d8e8landley			return button;
4175257cf54a5810105bc4a75703a06740d756d8e8landley		case 'e':
4185257cf54a5810105bc4a75703a06740d756d8e8landley		case 'x':
4195257cf54a5810105bc4a75703a06740d756d8e8landley			key = KEY_ESC;
4205257cf54a5810105bc4a75703a06740d756d8e8landley			break;
4215257cf54a5810105bc4a75703a06740d756d8e8landley		case KEY_ESC:
4225257cf54a5810105bc4a75703a06740d756d8e8landley			key = on_key_esc(menu);
4235257cf54a5810105bc4a75703a06740d756d8e8landley			break;
4245257cf54a5810105bc4a75703a06740d756d8e8landley		case KEY_RESIZE:
4255257cf54a5810105bc4a75703a06740d756d8e8landley			on_key_resize();
4265257cf54a5810105bc4a75703a06740d756d8e8landley			delwin(menu);
4275257cf54a5810105bc4a75703a06740d756d8e8landley			delwin(dialog);
4285257cf54a5810105bc4a75703a06740d756d8e8landley			goto do_resize;
4295257cf54a5810105bc4a75703a06740d756d8e8landley		}
4305257cf54a5810105bc4a75703a06740d756d8e8landley	}
4315257cf54a5810105bc4a75703a06740d756d8e8landley	delwin(menu);
4325257cf54a5810105bc4a75703a06740d756d8e8landley	delwin(dialog);
4335257cf54a5810105bc4a75703a06740d756d8e8landley	return key;		/* ESC pressed */
4345257cf54a5810105bc4a75703a06740d756d8e8landley}
435