18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com>
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Derived from menuconfig.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include "nconf.h"
88c2ecf20Sopenharmony_ci#include "lkc.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/* a list of all the different widgets we use */
118c2ecf20Sopenharmony_ciattributes_t attributes[ATTR_MAX+1] = {0};
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/* available colors:
148c2ecf20Sopenharmony_ci   COLOR_BLACK   0
158c2ecf20Sopenharmony_ci   COLOR_RED     1
168c2ecf20Sopenharmony_ci   COLOR_GREEN   2
178c2ecf20Sopenharmony_ci   COLOR_YELLOW  3
188c2ecf20Sopenharmony_ci   COLOR_BLUE    4
198c2ecf20Sopenharmony_ci   COLOR_MAGENTA 5
208c2ecf20Sopenharmony_ci   COLOR_CYAN    6
218c2ecf20Sopenharmony_ci   COLOR_WHITE   7
228c2ecf20Sopenharmony_ci   */
238c2ecf20Sopenharmony_cistatic void set_normal_colors(void)
248c2ecf20Sopenharmony_ci{
258c2ecf20Sopenharmony_ci	init_pair(NORMAL, -1, -1);
268c2ecf20Sopenharmony_ci	init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	/* FORE is for the selected item */
298c2ecf20Sopenharmony_ci	init_pair(MAIN_MENU_FORE, -1, -1);
308c2ecf20Sopenharmony_ci	/* BACK for all the rest */
318c2ecf20Sopenharmony_ci	init_pair(MAIN_MENU_BACK, -1, -1);
328c2ecf20Sopenharmony_ci	init_pair(MAIN_MENU_GREY, -1, -1);
338c2ecf20Sopenharmony_ci	init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
348c2ecf20Sopenharmony_ci	init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	init_pair(SCROLLWIN_TEXT, -1, -1);
378c2ecf20Sopenharmony_ci	init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
388c2ecf20Sopenharmony_ci	init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	init_pair(DIALOG_TEXT, -1, -1);
418c2ecf20Sopenharmony_ci	init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
428c2ecf20Sopenharmony_ci	init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
438c2ecf20Sopenharmony_ci	init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	init_pair(INPUT_BOX, COLOR_YELLOW, -1);
468c2ecf20Sopenharmony_ci	init_pair(INPUT_HEADING, COLOR_GREEN, -1);
478c2ecf20Sopenharmony_ci	init_pair(INPUT_TEXT, -1, -1);
488c2ecf20Sopenharmony_ci	init_pair(INPUT_FIELD, -1, -1);
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	init_pair(FUNCTION_HIGHLIGHT, -1, -1);
518c2ecf20Sopenharmony_ci	init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1);
528c2ecf20Sopenharmony_ci}
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/* available attributes:
558c2ecf20Sopenharmony_ci   A_NORMAL        Normal display (no highlight)
568c2ecf20Sopenharmony_ci   A_STANDOUT      Best highlighting mode of the terminal.
578c2ecf20Sopenharmony_ci   A_UNDERLINE     Underlining
588c2ecf20Sopenharmony_ci   A_REVERSE       Reverse video
598c2ecf20Sopenharmony_ci   A_BLINK         Blinking
608c2ecf20Sopenharmony_ci   A_DIM           Half bright
618c2ecf20Sopenharmony_ci   A_BOLD          Extra bright or bold
628c2ecf20Sopenharmony_ci   A_PROTECT       Protected mode
638c2ecf20Sopenharmony_ci   A_INVIS         Invisible or blank mode
648c2ecf20Sopenharmony_ci   A_ALTCHARSET    Alternate character set
658c2ecf20Sopenharmony_ci   A_CHARTEXT      Bit-mask to extract a character
668c2ecf20Sopenharmony_ci   COLOR_PAIR(n)   Color-pair number n
678c2ecf20Sopenharmony_ci   */
688c2ecf20Sopenharmony_cistatic void normal_color_theme(void)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	/* automatically add color... */
718c2ecf20Sopenharmony_ci#define mkattr(name, attr) do { \
728c2ecf20Sopenharmony_ciattributes[name] = attr | COLOR_PAIR(name); } while (0)
738c2ecf20Sopenharmony_ci	mkattr(NORMAL, NORMAL);
748c2ecf20Sopenharmony_ci	mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	mkattr(MAIN_MENU_FORE, A_REVERSE);
778c2ecf20Sopenharmony_ci	mkattr(MAIN_MENU_BACK, A_NORMAL);
788c2ecf20Sopenharmony_ci	mkattr(MAIN_MENU_GREY, A_NORMAL);
798c2ecf20Sopenharmony_ci	mkattr(MAIN_MENU_HEADING, A_BOLD);
808c2ecf20Sopenharmony_ci	mkattr(MAIN_MENU_BOX, A_NORMAL);
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	mkattr(SCROLLWIN_TEXT, A_NORMAL);
838c2ecf20Sopenharmony_ci	mkattr(SCROLLWIN_HEADING, A_BOLD);
848c2ecf20Sopenharmony_ci	mkattr(SCROLLWIN_BOX, A_BOLD);
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	mkattr(DIALOG_TEXT, A_BOLD);
878c2ecf20Sopenharmony_ci	mkattr(DIALOG_BOX, A_BOLD);
888c2ecf20Sopenharmony_ci	mkattr(DIALOG_MENU_FORE, A_STANDOUT);
898c2ecf20Sopenharmony_ci	mkattr(DIALOG_MENU_BACK, A_NORMAL);
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	mkattr(INPUT_BOX, A_NORMAL);
928c2ecf20Sopenharmony_ci	mkattr(INPUT_HEADING, A_BOLD);
938c2ecf20Sopenharmony_ci	mkattr(INPUT_TEXT, A_NORMAL);
948c2ecf20Sopenharmony_ci	mkattr(INPUT_FIELD, A_UNDERLINE);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
978c2ecf20Sopenharmony_ci	mkattr(FUNCTION_TEXT, A_REVERSE);
988c2ecf20Sopenharmony_ci}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic void no_colors_theme(void)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	/* automatically add highlight, no color */
1038c2ecf20Sopenharmony_ci#define mkattrn(name, attr) { attributes[name] = attr; }
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	mkattrn(NORMAL, NORMAL);
1068c2ecf20Sopenharmony_ci	mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	mkattrn(MAIN_MENU_FORE, A_STANDOUT);
1098c2ecf20Sopenharmony_ci	mkattrn(MAIN_MENU_BACK, A_NORMAL);
1108c2ecf20Sopenharmony_ci	mkattrn(MAIN_MENU_GREY, A_NORMAL);
1118c2ecf20Sopenharmony_ci	mkattrn(MAIN_MENU_HEADING, A_BOLD);
1128c2ecf20Sopenharmony_ci	mkattrn(MAIN_MENU_BOX, A_NORMAL);
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	mkattrn(SCROLLWIN_TEXT, A_NORMAL);
1158c2ecf20Sopenharmony_ci	mkattrn(SCROLLWIN_HEADING, A_BOLD);
1168c2ecf20Sopenharmony_ci	mkattrn(SCROLLWIN_BOX, A_BOLD);
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	mkattrn(DIALOG_TEXT, A_NORMAL);
1198c2ecf20Sopenharmony_ci	mkattrn(DIALOG_BOX, A_BOLD);
1208c2ecf20Sopenharmony_ci	mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
1218c2ecf20Sopenharmony_ci	mkattrn(DIALOG_MENU_BACK, A_NORMAL);
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	mkattrn(INPUT_BOX, A_BOLD);
1248c2ecf20Sopenharmony_ci	mkattrn(INPUT_HEADING, A_BOLD);
1258c2ecf20Sopenharmony_ci	mkattrn(INPUT_TEXT, A_NORMAL);
1268c2ecf20Sopenharmony_ci	mkattrn(INPUT_FIELD, A_UNDERLINE);
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
1298c2ecf20Sopenharmony_ci	mkattrn(FUNCTION_TEXT, A_REVERSE);
1308c2ecf20Sopenharmony_ci}
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_civoid set_colors(void)
1338c2ecf20Sopenharmony_ci{
1348c2ecf20Sopenharmony_ci	start_color();
1358c2ecf20Sopenharmony_ci	use_default_colors();
1368c2ecf20Sopenharmony_ci	set_normal_colors();
1378c2ecf20Sopenharmony_ci	if (has_colors()) {
1388c2ecf20Sopenharmony_ci		normal_color_theme();
1398c2ecf20Sopenharmony_ci	} else {
1408c2ecf20Sopenharmony_ci		/* give defaults */
1418c2ecf20Sopenharmony_ci		no_colors_theme();
1428c2ecf20Sopenharmony_ci	}
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci/* this changes the windows attributes !!! */
1478c2ecf20Sopenharmony_civoid print_in_middle(WINDOW *win,
1488c2ecf20Sopenharmony_ci		int starty,
1498c2ecf20Sopenharmony_ci		int startx,
1508c2ecf20Sopenharmony_ci		int width,
1518c2ecf20Sopenharmony_ci		const char *string,
1528c2ecf20Sopenharmony_ci		chtype color)
1538c2ecf20Sopenharmony_ci{      int length, x, y;
1548c2ecf20Sopenharmony_ci	float temp;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	if (win == NULL)
1588c2ecf20Sopenharmony_ci		win = stdscr;
1598c2ecf20Sopenharmony_ci	getyx(win, y, x);
1608c2ecf20Sopenharmony_ci	if (startx != 0)
1618c2ecf20Sopenharmony_ci		x = startx;
1628c2ecf20Sopenharmony_ci	if (starty != 0)
1638c2ecf20Sopenharmony_ci		y = starty;
1648c2ecf20Sopenharmony_ci	if (width == 0)
1658c2ecf20Sopenharmony_ci		width = 80;
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	length = strlen(string);
1688c2ecf20Sopenharmony_ci	temp = (width - length) / 2;
1698c2ecf20Sopenharmony_ci	x = startx + (int)temp;
1708c2ecf20Sopenharmony_ci	(void) wattrset(win, color);
1718c2ecf20Sopenharmony_ci	mvwprintw(win, y, x, "%s", string);
1728c2ecf20Sopenharmony_ci	refresh();
1738c2ecf20Sopenharmony_ci}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ciint get_line_no(const char *text)
1768c2ecf20Sopenharmony_ci{
1778c2ecf20Sopenharmony_ci	int i;
1788c2ecf20Sopenharmony_ci	int total = 1;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	if (!text)
1818c2ecf20Sopenharmony_ci		return 0;
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	for (i = 0; text[i] != '\0'; i++)
1848c2ecf20Sopenharmony_ci		if (text[i] == '\n')
1858c2ecf20Sopenharmony_ci			total++;
1868c2ecf20Sopenharmony_ci	return total;
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ciconst char *get_line(const char *text, int line_no)
1908c2ecf20Sopenharmony_ci{
1918c2ecf20Sopenharmony_ci	int i;
1928c2ecf20Sopenharmony_ci	int lines = 0;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	if (!text)
1958c2ecf20Sopenharmony_ci		return NULL;
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	for (i = 0; text[i] != '\0' && lines < line_no; i++)
1988c2ecf20Sopenharmony_ci		if (text[i] == '\n')
1998c2ecf20Sopenharmony_ci			lines++;
2008c2ecf20Sopenharmony_ci	return text+i;
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ciint get_line_length(const char *line)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	int res = 0;
2068c2ecf20Sopenharmony_ci	while (*line != '\0' && *line != '\n') {
2078c2ecf20Sopenharmony_ci		line++;
2088c2ecf20Sopenharmony_ci		res++;
2098c2ecf20Sopenharmony_ci	}
2108c2ecf20Sopenharmony_ci	return res;
2118c2ecf20Sopenharmony_ci}
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci/* print all lines to the window. */
2148c2ecf20Sopenharmony_civoid fill_window(WINDOW *win, const char *text)
2158c2ecf20Sopenharmony_ci{
2168c2ecf20Sopenharmony_ci	int x, y;
2178c2ecf20Sopenharmony_ci	int total_lines = get_line_no(text);
2188c2ecf20Sopenharmony_ci	int i;
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	getmaxyx(win, y, x);
2218c2ecf20Sopenharmony_ci	/* do not go over end of line */
2228c2ecf20Sopenharmony_ci	total_lines = min(total_lines, y);
2238c2ecf20Sopenharmony_ci	for (i = 0; i < total_lines; i++) {
2248c2ecf20Sopenharmony_ci		char tmp[x+10];
2258c2ecf20Sopenharmony_ci		const char *line = get_line(text, i);
2268c2ecf20Sopenharmony_ci		int len = get_line_length(line);
2278c2ecf20Sopenharmony_ci		strncpy(tmp, line, min(len, x));
2288c2ecf20Sopenharmony_ci		tmp[len] = '\0';
2298c2ecf20Sopenharmony_ci		mvwprintw(win, i, 0, "%s", tmp);
2308c2ecf20Sopenharmony_ci	}
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci/* get the message, and buttons.
2348c2ecf20Sopenharmony_ci * each button must be a char*
2358c2ecf20Sopenharmony_ci * return the selected button
2368c2ecf20Sopenharmony_ci *
2378c2ecf20Sopenharmony_ci * this dialog is used for 2 different things:
2388c2ecf20Sopenharmony_ci * 1) show a text box, no buttons.
2398c2ecf20Sopenharmony_ci * 2) show a dialog, with horizontal buttons
2408c2ecf20Sopenharmony_ci */
2418c2ecf20Sopenharmony_ciint btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
2428c2ecf20Sopenharmony_ci{
2438c2ecf20Sopenharmony_ci	va_list ap;
2448c2ecf20Sopenharmony_ci	char *btn;
2458c2ecf20Sopenharmony_ci	int btns_width = 0;
2468c2ecf20Sopenharmony_ci	int msg_lines = 0;
2478c2ecf20Sopenharmony_ci	int msg_width = 0;
2488c2ecf20Sopenharmony_ci	int total_width;
2498c2ecf20Sopenharmony_ci	int win_rows = 0;
2508c2ecf20Sopenharmony_ci	WINDOW *win;
2518c2ecf20Sopenharmony_ci	WINDOW *msg_win;
2528c2ecf20Sopenharmony_ci	WINDOW *menu_win;
2538c2ecf20Sopenharmony_ci	MENU *menu;
2548c2ecf20Sopenharmony_ci	ITEM *btns[btn_num+1];
2558c2ecf20Sopenharmony_ci	int i, x, y;
2568c2ecf20Sopenharmony_ci	int res = -1;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	va_start(ap, btn_num);
2608c2ecf20Sopenharmony_ci	for (i = 0; i < btn_num; i++) {
2618c2ecf20Sopenharmony_ci		btn = va_arg(ap, char *);
2628c2ecf20Sopenharmony_ci		btns[i] = new_item(btn, "");
2638c2ecf20Sopenharmony_ci		btns_width += strlen(btn)+1;
2648c2ecf20Sopenharmony_ci	}
2658c2ecf20Sopenharmony_ci	va_end(ap);
2668c2ecf20Sopenharmony_ci	btns[btn_num] = NULL;
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	/* find the widest line of msg: */
2698c2ecf20Sopenharmony_ci	msg_lines = get_line_no(msg);
2708c2ecf20Sopenharmony_ci	for (i = 0; i < msg_lines; i++) {
2718c2ecf20Sopenharmony_ci		const char *line = get_line(msg, i);
2728c2ecf20Sopenharmony_ci		int len = get_line_length(line);
2738c2ecf20Sopenharmony_ci		if (msg_width < len)
2748c2ecf20Sopenharmony_ci			msg_width = len;
2758c2ecf20Sopenharmony_ci	}
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	total_width = max(msg_width, btns_width);
2788c2ecf20Sopenharmony_ci	/* place dialog in middle of screen */
2798c2ecf20Sopenharmony_ci	y = (getmaxy(stdscr)-(msg_lines+4))/2;
2808c2ecf20Sopenharmony_ci	x = (getmaxx(stdscr)-(total_width+4))/2;
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	/* create the windows */
2848c2ecf20Sopenharmony_ci	if (btn_num > 0)
2858c2ecf20Sopenharmony_ci		win_rows = msg_lines+4;
2868c2ecf20Sopenharmony_ci	else
2878c2ecf20Sopenharmony_ci		win_rows = msg_lines+2;
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci	win = newwin(win_rows, total_width+4, y, x);
2908c2ecf20Sopenharmony_ci	keypad(win, TRUE);
2918c2ecf20Sopenharmony_ci	menu_win = derwin(win, 1, btns_width, win_rows-2,
2928c2ecf20Sopenharmony_ci			1+(total_width+2-btns_width)/2);
2938c2ecf20Sopenharmony_ci	menu = new_menu(btns);
2948c2ecf20Sopenharmony_ci	msg_win = derwin(win, win_rows-2, msg_width, 1,
2958c2ecf20Sopenharmony_ci			1+(total_width+2-msg_width)/2);
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
2988c2ecf20Sopenharmony_ci	set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	(void) wattrset(win, attributes[DIALOG_BOX]);
3018c2ecf20Sopenharmony_ci	box(win, 0, 0);
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	/* print message */
3048c2ecf20Sopenharmony_ci	(void) wattrset(msg_win, attributes[DIALOG_TEXT]);
3058c2ecf20Sopenharmony_ci	fill_window(msg_win, msg);
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	set_menu_win(menu, win);
3088c2ecf20Sopenharmony_ci	set_menu_sub(menu, menu_win);
3098c2ecf20Sopenharmony_ci	set_menu_format(menu, 1, btn_num);
3108c2ecf20Sopenharmony_ci	menu_opts_off(menu, O_SHOWDESC);
3118c2ecf20Sopenharmony_ci	menu_opts_off(menu, O_SHOWMATCH);
3128c2ecf20Sopenharmony_ci	menu_opts_on(menu, O_ONEVALUE);
3138c2ecf20Sopenharmony_ci	menu_opts_on(menu, O_NONCYCLIC);
3148c2ecf20Sopenharmony_ci	set_menu_mark(menu, "");
3158c2ecf20Sopenharmony_ci	post_menu(menu);
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	touchwin(win);
3198c2ecf20Sopenharmony_ci	refresh_all_windows(main_window);
3208c2ecf20Sopenharmony_ci	while ((res = wgetch(win))) {
3218c2ecf20Sopenharmony_ci		switch (res) {
3228c2ecf20Sopenharmony_ci		case KEY_LEFT:
3238c2ecf20Sopenharmony_ci			menu_driver(menu, REQ_LEFT_ITEM);
3248c2ecf20Sopenharmony_ci			break;
3258c2ecf20Sopenharmony_ci		case KEY_RIGHT:
3268c2ecf20Sopenharmony_ci			menu_driver(menu, REQ_RIGHT_ITEM);
3278c2ecf20Sopenharmony_ci			break;
3288c2ecf20Sopenharmony_ci		case 10: /* ENTER */
3298c2ecf20Sopenharmony_ci		case 27: /* ESCAPE */
3308c2ecf20Sopenharmony_ci		case ' ':
3318c2ecf20Sopenharmony_ci		case KEY_F(F_BACK):
3328c2ecf20Sopenharmony_ci		case KEY_F(F_EXIT):
3338c2ecf20Sopenharmony_ci			break;
3348c2ecf20Sopenharmony_ci		}
3358c2ecf20Sopenharmony_ci		touchwin(win);
3368c2ecf20Sopenharmony_ci		refresh_all_windows(main_window);
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci		if (res == 10 || res == ' ') {
3398c2ecf20Sopenharmony_ci			res = item_index(current_item(menu));
3408c2ecf20Sopenharmony_ci			break;
3418c2ecf20Sopenharmony_ci		} else if (res == 27 || res == KEY_F(F_BACK) ||
3428c2ecf20Sopenharmony_ci				res == KEY_F(F_EXIT)) {
3438c2ecf20Sopenharmony_ci			res = KEY_EXIT;
3448c2ecf20Sopenharmony_ci			break;
3458c2ecf20Sopenharmony_ci		}
3468c2ecf20Sopenharmony_ci	}
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci	unpost_menu(menu);
3498c2ecf20Sopenharmony_ci	free_menu(menu);
3508c2ecf20Sopenharmony_ci	for (i = 0; i < btn_num; i++)
3518c2ecf20Sopenharmony_ci		free_item(btns[i]);
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	delwin(win);
3548c2ecf20Sopenharmony_ci	return res;
3558c2ecf20Sopenharmony_ci}
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_ciint dialog_inputbox(WINDOW *main_window,
3588c2ecf20Sopenharmony_ci		const char *title, const char *prompt,
3598c2ecf20Sopenharmony_ci		const char *init, char **resultp, int *result_len)
3608c2ecf20Sopenharmony_ci{
3618c2ecf20Sopenharmony_ci	int prompt_lines = 0;
3628c2ecf20Sopenharmony_ci	int prompt_width = 0;
3638c2ecf20Sopenharmony_ci	WINDOW *win;
3648c2ecf20Sopenharmony_ci	WINDOW *prompt_win;
3658c2ecf20Sopenharmony_ci	WINDOW *form_win;
3668c2ecf20Sopenharmony_ci	PANEL *panel;
3678c2ecf20Sopenharmony_ci	int i, x, y, lines, columns, win_lines, win_cols;
3688c2ecf20Sopenharmony_ci	int res = -1;
3698c2ecf20Sopenharmony_ci	int cursor_position = strlen(init);
3708c2ecf20Sopenharmony_ci	int cursor_form_win;
3718c2ecf20Sopenharmony_ci	char *result = *resultp;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	getmaxyx(stdscr, lines, columns);
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci	if (strlen(init)+1 > *result_len) {
3768c2ecf20Sopenharmony_ci		*result_len = strlen(init)+1;
3778c2ecf20Sopenharmony_ci		*resultp = result = xrealloc(result, *result_len);
3788c2ecf20Sopenharmony_ci	}
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	/* find the widest line of msg: */
3818c2ecf20Sopenharmony_ci	prompt_lines = get_line_no(prompt);
3828c2ecf20Sopenharmony_ci	for (i = 0; i < prompt_lines; i++) {
3838c2ecf20Sopenharmony_ci		const char *line = get_line(prompt, i);
3848c2ecf20Sopenharmony_ci		int len = get_line_length(line);
3858c2ecf20Sopenharmony_ci		prompt_width = max(prompt_width, len);
3868c2ecf20Sopenharmony_ci	}
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci	if (title)
3898c2ecf20Sopenharmony_ci		prompt_width = max(prompt_width, strlen(title));
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci	win_lines = min(prompt_lines+6, lines-2);
3928c2ecf20Sopenharmony_ci	win_cols = min(prompt_width+7, columns-2);
3938c2ecf20Sopenharmony_ci	prompt_lines = max(win_lines-6, 0);
3948c2ecf20Sopenharmony_ci	prompt_width = max(win_cols-7, 0);
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci	/* place dialog in middle of screen */
3978c2ecf20Sopenharmony_ci	y = (lines-win_lines)/2;
3988c2ecf20Sopenharmony_ci	x = (columns-win_cols)/2;
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	strncpy(result, init, *result_len);
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	/* create the windows */
4038c2ecf20Sopenharmony_ci	win = newwin(win_lines, win_cols, y, x);
4048c2ecf20Sopenharmony_ci	prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
4058c2ecf20Sopenharmony_ci	form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
4068c2ecf20Sopenharmony_ci	keypad(form_win, TRUE);
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	(void) wattrset(form_win, attributes[INPUT_FIELD]);
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci	(void) wattrset(win, attributes[INPUT_BOX]);
4118c2ecf20Sopenharmony_ci	box(win, 0, 0);
4128c2ecf20Sopenharmony_ci	(void) wattrset(win, attributes[INPUT_HEADING]);
4138c2ecf20Sopenharmony_ci	if (title)
4148c2ecf20Sopenharmony_ci		mvwprintw(win, 0, 3, "%s", title);
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	/* print message */
4178c2ecf20Sopenharmony_ci	(void) wattrset(prompt_win, attributes[INPUT_TEXT]);
4188c2ecf20Sopenharmony_ci	fill_window(prompt_win, prompt);
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
4218c2ecf20Sopenharmony_ci	cursor_form_win = min(cursor_position, prompt_width-1);
4228c2ecf20Sopenharmony_ci	mvwprintw(form_win, 0, 0, "%s",
4238c2ecf20Sopenharmony_ci		  result + cursor_position-cursor_form_win);
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	/* create panels */
4268c2ecf20Sopenharmony_ci	panel = new_panel(win);
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci	/* show the cursor */
4298c2ecf20Sopenharmony_ci	curs_set(1);
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci	touchwin(win);
4328c2ecf20Sopenharmony_ci	refresh_all_windows(main_window);
4338c2ecf20Sopenharmony_ci	while ((res = wgetch(form_win))) {
4348c2ecf20Sopenharmony_ci		int len = strlen(result);
4358c2ecf20Sopenharmony_ci		switch (res) {
4368c2ecf20Sopenharmony_ci		case 10: /* ENTER */
4378c2ecf20Sopenharmony_ci		case 27: /* ESCAPE */
4388c2ecf20Sopenharmony_ci		case KEY_F(F_HELP):
4398c2ecf20Sopenharmony_ci		case KEY_F(F_EXIT):
4408c2ecf20Sopenharmony_ci		case KEY_F(F_BACK):
4418c2ecf20Sopenharmony_ci			break;
4428c2ecf20Sopenharmony_ci		case 8:   /* ^H */
4438c2ecf20Sopenharmony_ci		case 127: /* ^? */
4448c2ecf20Sopenharmony_ci		case KEY_BACKSPACE:
4458c2ecf20Sopenharmony_ci			if (cursor_position > 0) {
4468c2ecf20Sopenharmony_ci				memmove(&result[cursor_position-1],
4478c2ecf20Sopenharmony_ci						&result[cursor_position],
4488c2ecf20Sopenharmony_ci						len-cursor_position+1);
4498c2ecf20Sopenharmony_ci				cursor_position--;
4508c2ecf20Sopenharmony_ci				cursor_form_win--;
4518c2ecf20Sopenharmony_ci				len--;
4528c2ecf20Sopenharmony_ci			}
4538c2ecf20Sopenharmony_ci			break;
4548c2ecf20Sopenharmony_ci		case KEY_DC:
4558c2ecf20Sopenharmony_ci			if (cursor_position >= 0 && cursor_position < len) {
4568c2ecf20Sopenharmony_ci				memmove(&result[cursor_position],
4578c2ecf20Sopenharmony_ci						&result[cursor_position+1],
4588c2ecf20Sopenharmony_ci						len-cursor_position+1);
4598c2ecf20Sopenharmony_ci				len--;
4608c2ecf20Sopenharmony_ci			}
4618c2ecf20Sopenharmony_ci			break;
4628c2ecf20Sopenharmony_ci		case KEY_UP:
4638c2ecf20Sopenharmony_ci		case KEY_RIGHT:
4648c2ecf20Sopenharmony_ci			if (cursor_position < len) {
4658c2ecf20Sopenharmony_ci				cursor_position++;
4668c2ecf20Sopenharmony_ci				cursor_form_win++;
4678c2ecf20Sopenharmony_ci			}
4688c2ecf20Sopenharmony_ci			break;
4698c2ecf20Sopenharmony_ci		case KEY_DOWN:
4708c2ecf20Sopenharmony_ci		case KEY_LEFT:
4718c2ecf20Sopenharmony_ci			if (cursor_position > 0) {
4728c2ecf20Sopenharmony_ci				cursor_position--;
4738c2ecf20Sopenharmony_ci				cursor_form_win--;
4748c2ecf20Sopenharmony_ci			}
4758c2ecf20Sopenharmony_ci			break;
4768c2ecf20Sopenharmony_ci		case KEY_HOME:
4778c2ecf20Sopenharmony_ci			cursor_position = 0;
4788c2ecf20Sopenharmony_ci			cursor_form_win = 0;
4798c2ecf20Sopenharmony_ci			break;
4808c2ecf20Sopenharmony_ci		case KEY_END:
4818c2ecf20Sopenharmony_ci			cursor_position = len;
4828c2ecf20Sopenharmony_ci			cursor_form_win = min(cursor_position, prompt_width-1);
4838c2ecf20Sopenharmony_ci			break;
4848c2ecf20Sopenharmony_ci		default:
4858c2ecf20Sopenharmony_ci			if ((isgraph(res) || isspace(res))) {
4868c2ecf20Sopenharmony_ci				/* one for new char, one for '\0' */
4878c2ecf20Sopenharmony_ci				if (len+2 > *result_len) {
4888c2ecf20Sopenharmony_ci					*result_len = len+2;
4898c2ecf20Sopenharmony_ci					*resultp = result = realloc(result,
4908c2ecf20Sopenharmony_ci								*result_len);
4918c2ecf20Sopenharmony_ci				}
4928c2ecf20Sopenharmony_ci				/* insert the char at the proper position */
4938c2ecf20Sopenharmony_ci				memmove(&result[cursor_position+1],
4948c2ecf20Sopenharmony_ci						&result[cursor_position],
4958c2ecf20Sopenharmony_ci						len-cursor_position+1);
4968c2ecf20Sopenharmony_ci				result[cursor_position] = res;
4978c2ecf20Sopenharmony_ci				cursor_position++;
4988c2ecf20Sopenharmony_ci				cursor_form_win++;
4998c2ecf20Sopenharmony_ci				len++;
5008c2ecf20Sopenharmony_ci			} else {
5018c2ecf20Sopenharmony_ci				mvprintw(0, 0, "unknown key: %d\n", res);
5028c2ecf20Sopenharmony_ci			}
5038c2ecf20Sopenharmony_ci			break;
5048c2ecf20Sopenharmony_ci		}
5058c2ecf20Sopenharmony_ci		if (cursor_form_win < 0)
5068c2ecf20Sopenharmony_ci			cursor_form_win = 0;
5078c2ecf20Sopenharmony_ci		else if (cursor_form_win > prompt_width-1)
5088c2ecf20Sopenharmony_ci			cursor_form_win = prompt_width-1;
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci		wmove(form_win, 0, 0);
5118c2ecf20Sopenharmony_ci		wclrtoeol(form_win);
5128c2ecf20Sopenharmony_ci		mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
5138c2ecf20Sopenharmony_ci		mvwprintw(form_win, 0, 0, "%s",
5148c2ecf20Sopenharmony_ci			result + cursor_position-cursor_form_win);
5158c2ecf20Sopenharmony_ci		wmove(form_win, 0, cursor_form_win);
5168c2ecf20Sopenharmony_ci		touchwin(win);
5178c2ecf20Sopenharmony_ci		refresh_all_windows(main_window);
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci		if (res == 10) {
5208c2ecf20Sopenharmony_ci			res = 0;
5218c2ecf20Sopenharmony_ci			break;
5228c2ecf20Sopenharmony_ci		} else if (res == 27 || res == KEY_F(F_BACK) ||
5238c2ecf20Sopenharmony_ci				res == KEY_F(F_EXIT)) {
5248c2ecf20Sopenharmony_ci			res = KEY_EXIT;
5258c2ecf20Sopenharmony_ci			break;
5268c2ecf20Sopenharmony_ci		} else if (res == KEY_F(F_HELP)) {
5278c2ecf20Sopenharmony_ci			res = 1;
5288c2ecf20Sopenharmony_ci			break;
5298c2ecf20Sopenharmony_ci		}
5308c2ecf20Sopenharmony_ci	}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci	/* hide the cursor */
5338c2ecf20Sopenharmony_ci	curs_set(0);
5348c2ecf20Sopenharmony_ci	del_panel(panel);
5358c2ecf20Sopenharmony_ci	delwin(prompt_win);
5368c2ecf20Sopenharmony_ci	delwin(form_win);
5378c2ecf20Sopenharmony_ci	delwin(win);
5388c2ecf20Sopenharmony_ci	return res;
5398c2ecf20Sopenharmony_ci}
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci/* refresh all windows in the correct order */
5428c2ecf20Sopenharmony_civoid refresh_all_windows(WINDOW *main_window)
5438c2ecf20Sopenharmony_ci{
5448c2ecf20Sopenharmony_ci	update_panels();
5458c2ecf20Sopenharmony_ci	touchwin(main_window);
5468c2ecf20Sopenharmony_ci	refresh();
5478c2ecf20Sopenharmony_ci}
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_ci/* layman's scrollable window... */
5508c2ecf20Sopenharmony_civoid show_scroll_win(WINDOW *main_window,
5518c2ecf20Sopenharmony_ci		const char *title,
5528c2ecf20Sopenharmony_ci		const char *text)
5538c2ecf20Sopenharmony_ci{
5548c2ecf20Sopenharmony_ci	int res;
5558c2ecf20Sopenharmony_ci	int total_lines = get_line_no(text);
5568c2ecf20Sopenharmony_ci	int x, y, lines, columns;
5578c2ecf20Sopenharmony_ci	int start_x = 0, start_y = 0;
5588c2ecf20Sopenharmony_ci	int text_lines = 0, text_cols = 0;
5598c2ecf20Sopenharmony_ci	int total_cols = 0;
5608c2ecf20Sopenharmony_ci	int win_cols = 0;
5618c2ecf20Sopenharmony_ci	int win_lines = 0;
5628c2ecf20Sopenharmony_ci	int i = 0;
5638c2ecf20Sopenharmony_ci	WINDOW *win;
5648c2ecf20Sopenharmony_ci	WINDOW *pad;
5658c2ecf20Sopenharmony_ci	PANEL *panel;
5668c2ecf20Sopenharmony_ci
5678c2ecf20Sopenharmony_ci	getmaxyx(stdscr, lines, columns);
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	/* find the widest line of msg: */
5708c2ecf20Sopenharmony_ci	total_lines = get_line_no(text);
5718c2ecf20Sopenharmony_ci	for (i = 0; i < total_lines; i++) {
5728c2ecf20Sopenharmony_ci		const char *line = get_line(text, i);
5738c2ecf20Sopenharmony_ci		int len = get_line_length(line);
5748c2ecf20Sopenharmony_ci		total_cols = max(total_cols, len+2);
5758c2ecf20Sopenharmony_ci	}
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci	/* create the pad */
5788c2ecf20Sopenharmony_ci	pad = newpad(total_lines+10, total_cols+10);
5798c2ecf20Sopenharmony_ci	(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
5808c2ecf20Sopenharmony_ci	fill_window(pad, text);
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ci	win_lines = min(total_lines+4, lines-2);
5838c2ecf20Sopenharmony_ci	win_cols = min(total_cols+2, columns-2);
5848c2ecf20Sopenharmony_ci	text_lines = max(win_lines-4, 0);
5858c2ecf20Sopenharmony_ci	text_cols = max(win_cols-2, 0);
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci	/* place window in middle of screen */
5888c2ecf20Sopenharmony_ci	y = (lines-win_lines)/2;
5898c2ecf20Sopenharmony_ci	x = (columns-win_cols)/2;
5908c2ecf20Sopenharmony_ci
5918c2ecf20Sopenharmony_ci	win = newwin(win_lines, win_cols, y, x);
5928c2ecf20Sopenharmony_ci	keypad(win, TRUE);
5938c2ecf20Sopenharmony_ci	/* show the help in the help window, and show the help panel */
5948c2ecf20Sopenharmony_ci	(void) wattrset(win, attributes[SCROLLWIN_BOX]);
5958c2ecf20Sopenharmony_ci	box(win, 0, 0);
5968c2ecf20Sopenharmony_ci	(void) wattrset(win, attributes[SCROLLWIN_HEADING]);
5978c2ecf20Sopenharmony_ci	mvwprintw(win, 0, 3, " %s ", title);
5988c2ecf20Sopenharmony_ci	panel = new_panel(win);
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	/* handle scrolling */
6018c2ecf20Sopenharmony_ci	do {
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci		copywin(pad, win, start_y, start_x, 2, 2, text_lines,
6048c2ecf20Sopenharmony_ci				text_cols, 0);
6058c2ecf20Sopenharmony_ci		print_in_middle(win,
6068c2ecf20Sopenharmony_ci				text_lines+2,
6078c2ecf20Sopenharmony_ci				0,
6088c2ecf20Sopenharmony_ci				text_cols,
6098c2ecf20Sopenharmony_ci				"<OK>",
6108c2ecf20Sopenharmony_ci				attributes[DIALOG_MENU_FORE]);
6118c2ecf20Sopenharmony_ci		wrefresh(win);
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ci		res = wgetch(win);
6148c2ecf20Sopenharmony_ci		switch (res) {
6158c2ecf20Sopenharmony_ci		case KEY_NPAGE:
6168c2ecf20Sopenharmony_ci		case ' ':
6178c2ecf20Sopenharmony_ci		case 'd':
6188c2ecf20Sopenharmony_ci			start_y += text_lines-2;
6198c2ecf20Sopenharmony_ci			break;
6208c2ecf20Sopenharmony_ci		case KEY_PPAGE:
6218c2ecf20Sopenharmony_ci		case 'u':
6228c2ecf20Sopenharmony_ci			start_y -= text_lines+2;
6238c2ecf20Sopenharmony_ci			break;
6248c2ecf20Sopenharmony_ci		case KEY_HOME:
6258c2ecf20Sopenharmony_ci			start_y = 0;
6268c2ecf20Sopenharmony_ci			break;
6278c2ecf20Sopenharmony_ci		case KEY_END:
6288c2ecf20Sopenharmony_ci			start_y = total_lines-text_lines;
6298c2ecf20Sopenharmony_ci			break;
6308c2ecf20Sopenharmony_ci		case KEY_DOWN:
6318c2ecf20Sopenharmony_ci		case 'j':
6328c2ecf20Sopenharmony_ci			start_y++;
6338c2ecf20Sopenharmony_ci			break;
6348c2ecf20Sopenharmony_ci		case KEY_UP:
6358c2ecf20Sopenharmony_ci		case 'k':
6368c2ecf20Sopenharmony_ci			start_y--;
6378c2ecf20Sopenharmony_ci			break;
6388c2ecf20Sopenharmony_ci		case KEY_LEFT:
6398c2ecf20Sopenharmony_ci		case 'h':
6408c2ecf20Sopenharmony_ci			start_x--;
6418c2ecf20Sopenharmony_ci			break;
6428c2ecf20Sopenharmony_ci		case KEY_RIGHT:
6438c2ecf20Sopenharmony_ci		case 'l':
6448c2ecf20Sopenharmony_ci			start_x++;
6458c2ecf20Sopenharmony_ci			break;
6468c2ecf20Sopenharmony_ci		}
6478c2ecf20Sopenharmony_ci		if (res == 10 || res == 27 || res == 'q' ||
6488c2ecf20Sopenharmony_ci			res == KEY_F(F_HELP) || res == KEY_F(F_BACK) ||
6498c2ecf20Sopenharmony_ci			res == KEY_F(F_EXIT))
6508c2ecf20Sopenharmony_ci			break;
6518c2ecf20Sopenharmony_ci		if (start_y < 0)
6528c2ecf20Sopenharmony_ci			start_y = 0;
6538c2ecf20Sopenharmony_ci		if (start_y >= total_lines-text_lines)
6548c2ecf20Sopenharmony_ci			start_y = total_lines-text_lines;
6558c2ecf20Sopenharmony_ci		if (start_x < 0)
6568c2ecf20Sopenharmony_ci			start_x = 0;
6578c2ecf20Sopenharmony_ci		if (start_x >= total_cols-text_cols)
6588c2ecf20Sopenharmony_ci			start_x = total_cols-text_cols;
6598c2ecf20Sopenharmony_ci	} while (res);
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	del_panel(panel);
6628c2ecf20Sopenharmony_ci	delwin(win);
6638c2ecf20Sopenharmony_ci	refresh_all_windows(main_window);
6648c2ecf20Sopenharmony_ci}
665