xref: /rk3399_rockchip-uboot/scripts/kconfig/nconf.gui.c (revision bf7ab1e70fd7621fea5dea07b6975c576119b86e)
10a9064fbSMasahiro Yamada /*
20a9064fbSMasahiro Yamada  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
30a9064fbSMasahiro Yamada  * Released under the terms of the GNU GPL v2.0.
40a9064fbSMasahiro Yamada  *
50a9064fbSMasahiro Yamada  * Derived from menuconfig.
60a9064fbSMasahiro Yamada  *
70a9064fbSMasahiro Yamada  */
80a9064fbSMasahiro Yamada #include "nconf.h"
90a9064fbSMasahiro Yamada 
100a9064fbSMasahiro Yamada /* a list of all the different widgets we use */
110a9064fbSMasahiro Yamada attributes_t attributes[ATTR_MAX+1] = {0};
120a9064fbSMasahiro Yamada 
130a9064fbSMasahiro Yamada /* available colors:
140a9064fbSMasahiro Yamada    COLOR_BLACK   0
150a9064fbSMasahiro Yamada    COLOR_RED     1
160a9064fbSMasahiro Yamada    COLOR_GREEN   2
170a9064fbSMasahiro Yamada    COLOR_YELLOW  3
180a9064fbSMasahiro Yamada    COLOR_BLUE    4
190a9064fbSMasahiro Yamada    COLOR_MAGENTA 5
200a9064fbSMasahiro Yamada    COLOR_CYAN    6
210a9064fbSMasahiro Yamada    COLOR_WHITE   7
220a9064fbSMasahiro Yamada    */
set_normal_colors(void)230a9064fbSMasahiro Yamada static void set_normal_colors(void)
240a9064fbSMasahiro Yamada {
250a9064fbSMasahiro Yamada 	init_pair(NORMAL, -1, -1);
260a9064fbSMasahiro Yamada 	init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
270a9064fbSMasahiro Yamada 
280a9064fbSMasahiro Yamada 	/* FORE is for the selected item */
290a9064fbSMasahiro Yamada 	init_pair(MAIN_MENU_FORE, -1, -1);
300a9064fbSMasahiro Yamada 	/* BACK for all the rest */
310a9064fbSMasahiro Yamada 	init_pair(MAIN_MENU_BACK, -1, -1);
320a9064fbSMasahiro Yamada 	init_pair(MAIN_MENU_GREY, -1, -1);
330a9064fbSMasahiro Yamada 	init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
340a9064fbSMasahiro Yamada 	init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
350a9064fbSMasahiro Yamada 
360a9064fbSMasahiro Yamada 	init_pair(SCROLLWIN_TEXT, -1, -1);
370a9064fbSMasahiro Yamada 	init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
380a9064fbSMasahiro Yamada 	init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
390a9064fbSMasahiro Yamada 
400a9064fbSMasahiro Yamada 	init_pair(DIALOG_TEXT, -1, -1);
410a9064fbSMasahiro Yamada 	init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
420a9064fbSMasahiro Yamada 	init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
430a9064fbSMasahiro Yamada 	init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
440a9064fbSMasahiro Yamada 
450a9064fbSMasahiro Yamada 	init_pair(INPUT_BOX, COLOR_YELLOW, -1);
460a9064fbSMasahiro Yamada 	init_pair(INPUT_HEADING, COLOR_GREEN, -1);
470a9064fbSMasahiro Yamada 	init_pair(INPUT_TEXT, -1, -1);
480a9064fbSMasahiro Yamada 	init_pair(INPUT_FIELD, -1, -1);
490a9064fbSMasahiro Yamada 
500a9064fbSMasahiro Yamada 	init_pair(FUNCTION_HIGHLIGHT, -1, -1);
510a9064fbSMasahiro Yamada 	init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1);
520a9064fbSMasahiro Yamada }
530a9064fbSMasahiro Yamada 
540a9064fbSMasahiro Yamada /* available attributes:
550a9064fbSMasahiro Yamada    A_NORMAL        Normal display (no highlight)
560a9064fbSMasahiro Yamada    A_STANDOUT      Best highlighting mode of the terminal.
570a9064fbSMasahiro Yamada    A_UNDERLINE     Underlining
580a9064fbSMasahiro Yamada    A_REVERSE       Reverse video
590a9064fbSMasahiro Yamada    A_BLINK         Blinking
600a9064fbSMasahiro Yamada    A_DIM           Half bright
610a9064fbSMasahiro Yamada    A_BOLD          Extra bright or bold
620a9064fbSMasahiro Yamada    A_PROTECT       Protected mode
630a9064fbSMasahiro Yamada    A_INVIS         Invisible or blank mode
640a9064fbSMasahiro Yamada    A_ALTCHARSET    Alternate character set
650a9064fbSMasahiro Yamada    A_CHARTEXT      Bit-mask to extract a character
660a9064fbSMasahiro Yamada    COLOR_PAIR(n)   Color-pair number n
670a9064fbSMasahiro Yamada    */
normal_color_theme(void)680a9064fbSMasahiro Yamada static void normal_color_theme(void)
690a9064fbSMasahiro Yamada {
700a9064fbSMasahiro Yamada 	/* automatically add color... */
710a9064fbSMasahiro Yamada #define mkattr(name, attr) do { \
720a9064fbSMasahiro Yamada attributes[name] = attr | COLOR_PAIR(name); } while (0)
730a9064fbSMasahiro Yamada 	mkattr(NORMAL, NORMAL);
740a9064fbSMasahiro Yamada 	mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
750a9064fbSMasahiro Yamada 
760a9064fbSMasahiro Yamada 	mkattr(MAIN_MENU_FORE, A_REVERSE);
770a9064fbSMasahiro Yamada 	mkattr(MAIN_MENU_BACK, A_NORMAL);
780a9064fbSMasahiro Yamada 	mkattr(MAIN_MENU_GREY, A_NORMAL);
790a9064fbSMasahiro Yamada 	mkattr(MAIN_MENU_HEADING, A_BOLD);
800a9064fbSMasahiro Yamada 	mkattr(MAIN_MENU_BOX, A_NORMAL);
810a9064fbSMasahiro Yamada 
820a9064fbSMasahiro Yamada 	mkattr(SCROLLWIN_TEXT, A_NORMAL);
830a9064fbSMasahiro Yamada 	mkattr(SCROLLWIN_HEADING, A_BOLD);
840a9064fbSMasahiro Yamada 	mkattr(SCROLLWIN_BOX, A_BOLD);
850a9064fbSMasahiro Yamada 
860a9064fbSMasahiro Yamada 	mkattr(DIALOG_TEXT, A_BOLD);
870a9064fbSMasahiro Yamada 	mkattr(DIALOG_BOX, A_BOLD);
880a9064fbSMasahiro Yamada 	mkattr(DIALOG_MENU_FORE, A_STANDOUT);
890a9064fbSMasahiro Yamada 	mkattr(DIALOG_MENU_BACK, A_NORMAL);
900a9064fbSMasahiro Yamada 
910a9064fbSMasahiro Yamada 	mkattr(INPUT_BOX, A_NORMAL);
920a9064fbSMasahiro Yamada 	mkattr(INPUT_HEADING, A_BOLD);
930a9064fbSMasahiro Yamada 	mkattr(INPUT_TEXT, A_NORMAL);
940a9064fbSMasahiro Yamada 	mkattr(INPUT_FIELD, A_UNDERLINE);
950a9064fbSMasahiro Yamada 
960a9064fbSMasahiro Yamada 	mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
970a9064fbSMasahiro Yamada 	mkattr(FUNCTION_TEXT, A_REVERSE);
980a9064fbSMasahiro Yamada }
990a9064fbSMasahiro Yamada 
no_colors_theme(void)1000a9064fbSMasahiro Yamada static void no_colors_theme(void)
1010a9064fbSMasahiro Yamada {
1020a9064fbSMasahiro Yamada 	/* automatically add highlight, no color */
1030a9064fbSMasahiro Yamada #define mkattrn(name, attr) { attributes[name] = attr; }
1040a9064fbSMasahiro Yamada 
1050a9064fbSMasahiro Yamada 	mkattrn(NORMAL, NORMAL);
1060a9064fbSMasahiro Yamada 	mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
1070a9064fbSMasahiro Yamada 
1080a9064fbSMasahiro Yamada 	mkattrn(MAIN_MENU_FORE, A_STANDOUT);
1090a9064fbSMasahiro Yamada 	mkattrn(MAIN_MENU_BACK, A_NORMAL);
1100a9064fbSMasahiro Yamada 	mkattrn(MAIN_MENU_GREY, A_NORMAL);
1110a9064fbSMasahiro Yamada 	mkattrn(MAIN_MENU_HEADING, A_BOLD);
1120a9064fbSMasahiro Yamada 	mkattrn(MAIN_MENU_BOX, A_NORMAL);
1130a9064fbSMasahiro Yamada 
1140a9064fbSMasahiro Yamada 	mkattrn(SCROLLWIN_TEXT, A_NORMAL);
1150a9064fbSMasahiro Yamada 	mkattrn(SCROLLWIN_HEADING, A_BOLD);
1160a9064fbSMasahiro Yamada 	mkattrn(SCROLLWIN_BOX, A_BOLD);
1170a9064fbSMasahiro Yamada 
1180a9064fbSMasahiro Yamada 	mkattrn(DIALOG_TEXT, A_NORMAL);
1190a9064fbSMasahiro Yamada 	mkattrn(DIALOG_BOX, A_BOLD);
1200a9064fbSMasahiro Yamada 	mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
1210a9064fbSMasahiro Yamada 	mkattrn(DIALOG_MENU_BACK, A_NORMAL);
1220a9064fbSMasahiro Yamada 
1230a9064fbSMasahiro Yamada 	mkattrn(INPUT_BOX, A_BOLD);
1240a9064fbSMasahiro Yamada 	mkattrn(INPUT_HEADING, A_BOLD);
1250a9064fbSMasahiro Yamada 	mkattrn(INPUT_TEXT, A_NORMAL);
1260a9064fbSMasahiro Yamada 	mkattrn(INPUT_FIELD, A_UNDERLINE);
1270a9064fbSMasahiro Yamada 
1280a9064fbSMasahiro Yamada 	mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
1290a9064fbSMasahiro Yamada 	mkattrn(FUNCTION_TEXT, A_REVERSE);
1300a9064fbSMasahiro Yamada }
1310a9064fbSMasahiro Yamada 
set_colors()1320a9064fbSMasahiro Yamada void set_colors()
1330a9064fbSMasahiro Yamada {
1340a9064fbSMasahiro Yamada 	start_color();
1350a9064fbSMasahiro Yamada 	use_default_colors();
1360a9064fbSMasahiro Yamada 	set_normal_colors();
1370a9064fbSMasahiro Yamada 	if (has_colors()) {
1380a9064fbSMasahiro Yamada 		normal_color_theme();
1390a9064fbSMasahiro Yamada 	} else {
1400a9064fbSMasahiro Yamada 		/* give defaults */
1410a9064fbSMasahiro Yamada 		no_colors_theme();
1420a9064fbSMasahiro Yamada 	}
1430a9064fbSMasahiro Yamada }
1440a9064fbSMasahiro Yamada 
1450a9064fbSMasahiro Yamada 
1460a9064fbSMasahiro Yamada /* this changes the windows attributes !!! */
print_in_middle(WINDOW * win,int starty,int startx,int width,const char * string,chtype color)1470a9064fbSMasahiro Yamada void print_in_middle(WINDOW *win,
1480a9064fbSMasahiro Yamada 		int starty,
1490a9064fbSMasahiro Yamada 		int startx,
1500a9064fbSMasahiro Yamada 		int width,
1510a9064fbSMasahiro Yamada 		const char *string,
1520a9064fbSMasahiro Yamada 		chtype color)
1530a9064fbSMasahiro Yamada {      int length, x, y;
1540a9064fbSMasahiro Yamada 	float temp;
1550a9064fbSMasahiro Yamada 
1560a9064fbSMasahiro Yamada 
1570a9064fbSMasahiro Yamada 	if (win == NULL)
1580a9064fbSMasahiro Yamada 		win = stdscr;
1590a9064fbSMasahiro Yamada 	getyx(win, y, x);
1600a9064fbSMasahiro Yamada 	if (startx != 0)
1610a9064fbSMasahiro Yamada 		x = startx;
1620a9064fbSMasahiro Yamada 	if (starty != 0)
1630a9064fbSMasahiro Yamada 		y = starty;
1640a9064fbSMasahiro Yamada 	if (width == 0)
1650a9064fbSMasahiro Yamada 		width = 80;
1660a9064fbSMasahiro Yamada 
1670a9064fbSMasahiro Yamada 	length = strlen(string);
1680a9064fbSMasahiro Yamada 	temp = (width - length) / 2;
1690a9064fbSMasahiro Yamada 	x = startx + (int)temp;
1700a9064fbSMasahiro Yamada 	(void) wattrset(win, color);
1710a9064fbSMasahiro Yamada 	mvwprintw(win, y, x, "%s", string);
1720a9064fbSMasahiro Yamada 	refresh();
1730a9064fbSMasahiro Yamada }
1740a9064fbSMasahiro Yamada 
get_line_no(const char * text)1750a9064fbSMasahiro Yamada int get_line_no(const char *text)
1760a9064fbSMasahiro Yamada {
1770a9064fbSMasahiro Yamada 	int i;
1780a9064fbSMasahiro Yamada 	int total = 1;
1790a9064fbSMasahiro Yamada 
1800a9064fbSMasahiro Yamada 	if (!text)
1810a9064fbSMasahiro Yamada 		return 0;
1820a9064fbSMasahiro Yamada 
1830a9064fbSMasahiro Yamada 	for (i = 0; text[i] != '\0'; i++)
1840a9064fbSMasahiro Yamada 		if (text[i] == '\n')
1850a9064fbSMasahiro Yamada 			total++;
1860a9064fbSMasahiro Yamada 	return total;
1870a9064fbSMasahiro Yamada }
1880a9064fbSMasahiro Yamada 
get_line(const char * text,int line_no)1890a9064fbSMasahiro Yamada const char *get_line(const char *text, int line_no)
1900a9064fbSMasahiro Yamada {
1910a9064fbSMasahiro Yamada 	int i;
1920a9064fbSMasahiro Yamada 	int lines = 0;
1930a9064fbSMasahiro Yamada 
1940a9064fbSMasahiro Yamada 	if (!text)
1950a9064fbSMasahiro Yamada 		return 0;
1960a9064fbSMasahiro Yamada 
1970a9064fbSMasahiro Yamada 	for (i = 0; text[i] != '\0' && lines < line_no; i++)
1980a9064fbSMasahiro Yamada 		if (text[i] == '\n')
1990a9064fbSMasahiro Yamada 			lines++;
2000a9064fbSMasahiro Yamada 	return text+i;
2010a9064fbSMasahiro Yamada }
2020a9064fbSMasahiro Yamada 
get_line_length(const char * line)2030a9064fbSMasahiro Yamada int get_line_length(const char *line)
2040a9064fbSMasahiro Yamada {
2050a9064fbSMasahiro Yamada 	int res = 0;
2060a9064fbSMasahiro Yamada 	while (*line != '\0' && *line != '\n') {
2070a9064fbSMasahiro Yamada 		line++;
2080a9064fbSMasahiro Yamada 		res++;
2090a9064fbSMasahiro Yamada 	}
2100a9064fbSMasahiro Yamada 	return res;
2110a9064fbSMasahiro Yamada }
2120a9064fbSMasahiro Yamada 
2130a9064fbSMasahiro Yamada /* print all lines to the window. */
fill_window(WINDOW * win,const char * text)2140a9064fbSMasahiro Yamada void fill_window(WINDOW *win, const char *text)
2150a9064fbSMasahiro Yamada {
2160a9064fbSMasahiro Yamada 	int x, y;
2170a9064fbSMasahiro Yamada 	int total_lines = get_line_no(text);
2180a9064fbSMasahiro Yamada 	int i;
2190a9064fbSMasahiro Yamada 
2200a9064fbSMasahiro Yamada 	getmaxyx(win, y, x);
2210a9064fbSMasahiro Yamada 	/* do not go over end of line */
2220a9064fbSMasahiro Yamada 	total_lines = min(total_lines, y);
2230a9064fbSMasahiro Yamada 	for (i = 0; i < total_lines; i++) {
2240a9064fbSMasahiro Yamada 		char tmp[x+10];
2250a9064fbSMasahiro Yamada 		const char *line = get_line(text, i);
2260a9064fbSMasahiro Yamada 		int len = get_line_length(line);
2270a9064fbSMasahiro Yamada 		strncpy(tmp, line, min(len, x));
2280a9064fbSMasahiro Yamada 		tmp[len] = '\0';
2290a9064fbSMasahiro Yamada 		mvwprintw(win, i, 0, "%s", tmp);
2300a9064fbSMasahiro Yamada 	}
2310a9064fbSMasahiro Yamada }
2320a9064fbSMasahiro Yamada 
2330a9064fbSMasahiro Yamada /* get the message, and buttons.
2340a9064fbSMasahiro Yamada  * each button must be a char*
2350a9064fbSMasahiro Yamada  * return the selected button
2360a9064fbSMasahiro Yamada  *
2370a9064fbSMasahiro Yamada  * this dialog is used for 2 different things:
2380a9064fbSMasahiro Yamada  * 1) show a text box, no buttons.
2390a9064fbSMasahiro Yamada  * 2) show a dialog, with horizontal buttons
2400a9064fbSMasahiro Yamada  */
btn_dialog(WINDOW * main_window,const char * msg,int btn_num,...)2410a9064fbSMasahiro Yamada int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
2420a9064fbSMasahiro Yamada {
2430a9064fbSMasahiro Yamada 	va_list ap;
2440a9064fbSMasahiro Yamada 	char *btn;
2450a9064fbSMasahiro Yamada 	int btns_width = 0;
2460a9064fbSMasahiro Yamada 	int msg_lines = 0;
2470a9064fbSMasahiro Yamada 	int msg_width = 0;
2480a9064fbSMasahiro Yamada 	int total_width;
2490a9064fbSMasahiro Yamada 	int win_rows = 0;
2500a9064fbSMasahiro Yamada 	WINDOW *win;
2510a9064fbSMasahiro Yamada 	WINDOW *msg_win;
2520a9064fbSMasahiro Yamada 	WINDOW *menu_win;
2530a9064fbSMasahiro Yamada 	MENU *menu;
2540a9064fbSMasahiro Yamada 	ITEM *btns[btn_num+1];
2550a9064fbSMasahiro Yamada 	int i, x, y;
2560a9064fbSMasahiro Yamada 	int res = -1;
2570a9064fbSMasahiro Yamada 
2580a9064fbSMasahiro Yamada 
2590a9064fbSMasahiro Yamada 	va_start(ap, btn_num);
2600a9064fbSMasahiro Yamada 	for (i = 0; i < btn_num; i++) {
2610a9064fbSMasahiro Yamada 		btn = va_arg(ap, char *);
2620a9064fbSMasahiro Yamada 		btns[i] = new_item(btn, "");
2630a9064fbSMasahiro Yamada 		btns_width += strlen(btn)+1;
2640a9064fbSMasahiro Yamada 	}
2650a9064fbSMasahiro Yamada 	va_end(ap);
2660a9064fbSMasahiro Yamada 	btns[btn_num] = NULL;
2670a9064fbSMasahiro Yamada 
2680a9064fbSMasahiro Yamada 	/* find the widest line of msg: */
2690a9064fbSMasahiro Yamada 	msg_lines = get_line_no(msg);
2700a9064fbSMasahiro Yamada 	for (i = 0; i < msg_lines; i++) {
2710a9064fbSMasahiro Yamada 		const char *line = get_line(msg, i);
2720a9064fbSMasahiro Yamada 		int len = get_line_length(line);
2730a9064fbSMasahiro Yamada 		if (msg_width < len)
2740a9064fbSMasahiro Yamada 			msg_width = len;
2750a9064fbSMasahiro Yamada 	}
2760a9064fbSMasahiro Yamada 
2770a9064fbSMasahiro Yamada 	total_width = max(msg_width, btns_width);
2780a9064fbSMasahiro Yamada 	/* place dialog in middle of screen */
2790a9064fbSMasahiro Yamada 	y = (getmaxy(stdscr)-(msg_lines+4))/2;
2800a9064fbSMasahiro Yamada 	x = (getmaxx(stdscr)-(total_width+4))/2;
2810a9064fbSMasahiro Yamada 
2820a9064fbSMasahiro Yamada 
2830a9064fbSMasahiro Yamada 	/* create the windows */
2840a9064fbSMasahiro Yamada 	if (btn_num > 0)
2850a9064fbSMasahiro Yamada 		win_rows = msg_lines+4;
2860a9064fbSMasahiro Yamada 	else
2870a9064fbSMasahiro Yamada 		win_rows = msg_lines+2;
2880a9064fbSMasahiro Yamada 
2890a9064fbSMasahiro Yamada 	win = newwin(win_rows, total_width+4, y, x);
2900a9064fbSMasahiro Yamada 	keypad(win, TRUE);
2910a9064fbSMasahiro Yamada 	menu_win = derwin(win, 1, btns_width, win_rows-2,
2920a9064fbSMasahiro Yamada 			1+(total_width+2-btns_width)/2);
2930a9064fbSMasahiro Yamada 	menu = new_menu(btns);
2940a9064fbSMasahiro Yamada 	msg_win = derwin(win, win_rows-2, msg_width, 1,
2950a9064fbSMasahiro Yamada 			1+(total_width+2-msg_width)/2);
2960a9064fbSMasahiro Yamada 
2970a9064fbSMasahiro Yamada 	set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
2980a9064fbSMasahiro Yamada 	set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
2990a9064fbSMasahiro Yamada 
3000a9064fbSMasahiro Yamada 	(void) wattrset(win, attributes[DIALOG_BOX]);
3010a9064fbSMasahiro Yamada 	box(win, 0, 0);
3020a9064fbSMasahiro Yamada 
3030a9064fbSMasahiro Yamada 	/* print message */
3040a9064fbSMasahiro Yamada 	(void) wattrset(msg_win, attributes[DIALOG_TEXT]);
3050a9064fbSMasahiro Yamada 	fill_window(msg_win, msg);
3060a9064fbSMasahiro Yamada 
3070a9064fbSMasahiro Yamada 	set_menu_win(menu, win);
3080a9064fbSMasahiro Yamada 	set_menu_sub(menu, menu_win);
3090a9064fbSMasahiro Yamada 	set_menu_format(menu, 1, btn_num);
3100a9064fbSMasahiro Yamada 	menu_opts_off(menu, O_SHOWDESC);
3110a9064fbSMasahiro Yamada 	menu_opts_off(menu, O_SHOWMATCH);
3120a9064fbSMasahiro Yamada 	menu_opts_on(menu, O_ONEVALUE);
3130a9064fbSMasahiro Yamada 	menu_opts_on(menu, O_NONCYCLIC);
3140a9064fbSMasahiro Yamada 	set_menu_mark(menu, "");
3150a9064fbSMasahiro Yamada 	post_menu(menu);
3160a9064fbSMasahiro Yamada 
3170a9064fbSMasahiro Yamada 
3180a9064fbSMasahiro Yamada 	touchwin(win);
3190a9064fbSMasahiro Yamada 	refresh_all_windows(main_window);
3200a9064fbSMasahiro Yamada 	while ((res = wgetch(win))) {
3210a9064fbSMasahiro Yamada 		switch (res) {
3220a9064fbSMasahiro Yamada 		case KEY_LEFT:
3230a9064fbSMasahiro Yamada 			menu_driver(menu, REQ_LEFT_ITEM);
3240a9064fbSMasahiro Yamada 			break;
3250a9064fbSMasahiro Yamada 		case KEY_RIGHT:
3260a9064fbSMasahiro Yamada 			menu_driver(menu, REQ_RIGHT_ITEM);
3270a9064fbSMasahiro Yamada 			break;
3280a9064fbSMasahiro Yamada 		case 10: /* ENTER */
3290a9064fbSMasahiro Yamada 		case 27: /* ESCAPE */
3300a9064fbSMasahiro Yamada 		case ' ':
3310a9064fbSMasahiro Yamada 		case KEY_F(F_BACK):
3320a9064fbSMasahiro Yamada 		case KEY_F(F_EXIT):
3330a9064fbSMasahiro Yamada 			break;
3340a9064fbSMasahiro Yamada 		}
3350a9064fbSMasahiro Yamada 		touchwin(win);
3360a9064fbSMasahiro Yamada 		refresh_all_windows(main_window);
3370a9064fbSMasahiro Yamada 
3380a9064fbSMasahiro Yamada 		if (res == 10 || res == ' ') {
3390a9064fbSMasahiro Yamada 			res = item_index(current_item(menu));
3400a9064fbSMasahiro Yamada 			break;
3410a9064fbSMasahiro Yamada 		} else if (res == 27 || res == KEY_F(F_BACK) ||
3420a9064fbSMasahiro Yamada 				res == KEY_F(F_EXIT)) {
3430a9064fbSMasahiro Yamada 			res = KEY_EXIT;
3440a9064fbSMasahiro Yamada 			break;
3450a9064fbSMasahiro Yamada 		}
3460a9064fbSMasahiro Yamada 	}
3470a9064fbSMasahiro Yamada 
3480a9064fbSMasahiro Yamada 	unpost_menu(menu);
3490a9064fbSMasahiro Yamada 	free_menu(menu);
3500a9064fbSMasahiro Yamada 	for (i = 0; i < btn_num; i++)
3510a9064fbSMasahiro Yamada 		free_item(btns[i]);
3520a9064fbSMasahiro Yamada 
3530a9064fbSMasahiro Yamada 	delwin(win);
3540a9064fbSMasahiro Yamada 	return res;
3550a9064fbSMasahiro Yamada }
3560a9064fbSMasahiro Yamada 
dialog_inputbox(WINDOW * main_window,const char * title,const char * prompt,const char * init,char ** resultp,int * result_len)3570a9064fbSMasahiro Yamada int dialog_inputbox(WINDOW *main_window,
3580a9064fbSMasahiro Yamada 		const char *title, const char *prompt,
3590a9064fbSMasahiro Yamada 		const char *init, char **resultp, int *result_len)
3600a9064fbSMasahiro Yamada {
3610a9064fbSMasahiro Yamada 	int prompt_lines = 0;
3620a9064fbSMasahiro Yamada 	int prompt_width = 0;
3630a9064fbSMasahiro Yamada 	WINDOW *win;
3640a9064fbSMasahiro Yamada 	WINDOW *prompt_win;
3650a9064fbSMasahiro Yamada 	WINDOW *form_win;
3660a9064fbSMasahiro Yamada 	PANEL *panel;
367*bf7ab1e7SMasahiro Yamada 	int i, x, y, lines, columns, win_lines, win_cols;
3680a9064fbSMasahiro Yamada 	int res = -1;
3690a9064fbSMasahiro Yamada 	int cursor_position = strlen(init);
3700a9064fbSMasahiro Yamada 	int cursor_form_win;
3710a9064fbSMasahiro Yamada 	char *result = *resultp;
3720a9064fbSMasahiro Yamada 
373*bf7ab1e7SMasahiro Yamada 	getmaxyx(stdscr, lines, columns);
374*bf7ab1e7SMasahiro Yamada 
3750a9064fbSMasahiro Yamada 	if (strlen(init)+1 > *result_len) {
3760a9064fbSMasahiro Yamada 		*result_len = strlen(init)+1;
3770a9064fbSMasahiro Yamada 		*resultp = result = realloc(result, *result_len);
3780a9064fbSMasahiro Yamada 	}
3790a9064fbSMasahiro Yamada 
3800a9064fbSMasahiro Yamada 	/* find the widest line of msg: */
3810a9064fbSMasahiro Yamada 	prompt_lines = get_line_no(prompt);
3820a9064fbSMasahiro Yamada 	for (i = 0; i < prompt_lines; i++) {
3830a9064fbSMasahiro Yamada 		const char *line = get_line(prompt, i);
3840a9064fbSMasahiro Yamada 		int len = get_line_length(line);
3850a9064fbSMasahiro Yamada 		prompt_width = max(prompt_width, len);
3860a9064fbSMasahiro Yamada 	}
3870a9064fbSMasahiro Yamada 
3880a9064fbSMasahiro Yamada 	if (title)
3890a9064fbSMasahiro Yamada 		prompt_width = max(prompt_width, strlen(title));
3900a9064fbSMasahiro Yamada 
391*bf7ab1e7SMasahiro Yamada 	win_lines = min(prompt_lines+6, lines-2);
392*bf7ab1e7SMasahiro Yamada 	win_cols = min(prompt_width+7, columns-2);
393*bf7ab1e7SMasahiro Yamada 	prompt_lines = max(win_lines-6, 0);
394*bf7ab1e7SMasahiro Yamada 	prompt_width = max(win_cols-7, 0);
395*bf7ab1e7SMasahiro Yamada 
3960a9064fbSMasahiro Yamada 	/* place dialog in middle of screen */
397*bf7ab1e7SMasahiro Yamada 	y = (lines-win_lines)/2;
398*bf7ab1e7SMasahiro Yamada 	x = (columns-win_cols)/2;
3990a9064fbSMasahiro Yamada 
4000a9064fbSMasahiro Yamada 	strncpy(result, init, *result_len);
4010a9064fbSMasahiro Yamada 
4020a9064fbSMasahiro Yamada 	/* create the windows */
403*bf7ab1e7SMasahiro Yamada 	win = newwin(win_lines, win_cols, y, x);
4040a9064fbSMasahiro Yamada 	prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
4050a9064fbSMasahiro Yamada 	form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
4060a9064fbSMasahiro Yamada 	keypad(form_win, TRUE);
4070a9064fbSMasahiro Yamada 
4080a9064fbSMasahiro Yamada 	(void) wattrset(form_win, attributes[INPUT_FIELD]);
4090a9064fbSMasahiro Yamada 
4100a9064fbSMasahiro Yamada 	(void) wattrset(win, attributes[INPUT_BOX]);
4110a9064fbSMasahiro Yamada 	box(win, 0, 0);
4120a9064fbSMasahiro Yamada 	(void) wattrset(win, attributes[INPUT_HEADING]);
4130a9064fbSMasahiro Yamada 	if (title)
4140a9064fbSMasahiro Yamada 		mvwprintw(win, 0, 3, "%s", title);
4150a9064fbSMasahiro Yamada 
4160a9064fbSMasahiro Yamada 	/* print message */
4170a9064fbSMasahiro Yamada 	(void) wattrset(prompt_win, attributes[INPUT_TEXT]);
4180a9064fbSMasahiro Yamada 	fill_window(prompt_win, prompt);
4190a9064fbSMasahiro Yamada 
4200a9064fbSMasahiro Yamada 	mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
4210a9064fbSMasahiro Yamada 	cursor_form_win = min(cursor_position, prompt_width-1);
4220a9064fbSMasahiro Yamada 	mvwprintw(form_win, 0, 0, "%s",
4230a9064fbSMasahiro Yamada 		  result + cursor_position-cursor_form_win);
4240a9064fbSMasahiro Yamada 
4250a9064fbSMasahiro Yamada 	/* create panels */
4260a9064fbSMasahiro Yamada 	panel = new_panel(win);
4270a9064fbSMasahiro Yamada 
4280a9064fbSMasahiro Yamada 	/* show the cursor */
4290a9064fbSMasahiro Yamada 	curs_set(1);
4300a9064fbSMasahiro Yamada 
4310a9064fbSMasahiro Yamada 	touchwin(win);
4320a9064fbSMasahiro Yamada 	refresh_all_windows(main_window);
4330a9064fbSMasahiro Yamada 	while ((res = wgetch(form_win))) {
4340a9064fbSMasahiro Yamada 		int len = strlen(result);
4350a9064fbSMasahiro Yamada 		switch (res) {
4360a9064fbSMasahiro Yamada 		case 10: /* ENTER */
4370a9064fbSMasahiro Yamada 		case 27: /* ESCAPE */
4380a9064fbSMasahiro Yamada 		case KEY_F(F_HELP):
4390a9064fbSMasahiro Yamada 		case KEY_F(F_EXIT):
4400a9064fbSMasahiro Yamada 		case KEY_F(F_BACK):
4410a9064fbSMasahiro Yamada 			break;
4420a9064fbSMasahiro Yamada 		case 127:
4430a9064fbSMasahiro Yamada 		case KEY_BACKSPACE:
4440a9064fbSMasahiro Yamada 			if (cursor_position > 0) {
4450a9064fbSMasahiro Yamada 				memmove(&result[cursor_position-1],
4460a9064fbSMasahiro Yamada 						&result[cursor_position],
4470a9064fbSMasahiro Yamada 						len-cursor_position+1);
4480a9064fbSMasahiro Yamada 				cursor_position--;
4490a9064fbSMasahiro Yamada 				cursor_form_win--;
4500a9064fbSMasahiro Yamada 				len--;
4510a9064fbSMasahiro Yamada 			}
4520a9064fbSMasahiro Yamada 			break;
4530a9064fbSMasahiro Yamada 		case KEY_DC:
4540a9064fbSMasahiro Yamada 			if (cursor_position >= 0 && cursor_position < len) {
4550a9064fbSMasahiro Yamada 				memmove(&result[cursor_position],
4560a9064fbSMasahiro Yamada 						&result[cursor_position+1],
4570a9064fbSMasahiro Yamada 						len-cursor_position+1);
4580a9064fbSMasahiro Yamada 				len--;
4590a9064fbSMasahiro Yamada 			}
4600a9064fbSMasahiro Yamada 			break;
4610a9064fbSMasahiro Yamada 		case KEY_UP:
4620a9064fbSMasahiro Yamada 		case KEY_RIGHT:
4630a9064fbSMasahiro Yamada 			if (cursor_position < len) {
4640a9064fbSMasahiro Yamada 				cursor_position++;
4650a9064fbSMasahiro Yamada 				cursor_form_win++;
4660a9064fbSMasahiro Yamada 			}
4670a9064fbSMasahiro Yamada 			break;
4680a9064fbSMasahiro Yamada 		case KEY_DOWN:
4690a9064fbSMasahiro Yamada 		case KEY_LEFT:
4700a9064fbSMasahiro Yamada 			if (cursor_position > 0) {
4710a9064fbSMasahiro Yamada 				cursor_position--;
4720a9064fbSMasahiro Yamada 				cursor_form_win--;
4730a9064fbSMasahiro Yamada 			}
4740a9064fbSMasahiro Yamada 			break;
4750a9064fbSMasahiro Yamada 		case KEY_HOME:
4760a9064fbSMasahiro Yamada 			cursor_position = 0;
4770a9064fbSMasahiro Yamada 			cursor_form_win = 0;
4780a9064fbSMasahiro Yamada 			break;
4790a9064fbSMasahiro Yamada 		case KEY_END:
4800a9064fbSMasahiro Yamada 			cursor_position = len;
4810a9064fbSMasahiro Yamada 			cursor_form_win = min(cursor_position, prompt_width-1);
4820a9064fbSMasahiro Yamada 			break;
4830a9064fbSMasahiro Yamada 		default:
4840a9064fbSMasahiro Yamada 			if ((isgraph(res) || isspace(res))) {
4850a9064fbSMasahiro Yamada 				/* one for new char, one for '\0' */
4860a9064fbSMasahiro Yamada 				if (len+2 > *result_len) {
4870a9064fbSMasahiro Yamada 					*result_len = len+2;
4880a9064fbSMasahiro Yamada 					*resultp = result = realloc(result,
4890a9064fbSMasahiro Yamada 								*result_len);
4900a9064fbSMasahiro Yamada 				}
4910a9064fbSMasahiro Yamada 				/* insert the char at the proper position */
4920a9064fbSMasahiro Yamada 				memmove(&result[cursor_position+1],
4930a9064fbSMasahiro Yamada 						&result[cursor_position],
4940a9064fbSMasahiro Yamada 						len-cursor_position+1);
4950a9064fbSMasahiro Yamada 				result[cursor_position] = res;
4960a9064fbSMasahiro Yamada 				cursor_position++;
4970a9064fbSMasahiro Yamada 				cursor_form_win++;
4980a9064fbSMasahiro Yamada 				len++;
4990a9064fbSMasahiro Yamada 			} else {
5000a9064fbSMasahiro Yamada 				mvprintw(0, 0, "unknown key: %d\n", res);
5010a9064fbSMasahiro Yamada 			}
5020a9064fbSMasahiro Yamada 			break;
5030a9064fbSMasahiro Yamada 		}
5040a9064fbSMasahiro Yamada 		if (cursor_form_win < 0)
5050a9064fbSMasahiro Yamada 			cursor_form_win = 0;
5060a9064fbSMasahiro Yamada 		else if (cursor_form_win > prompt_width-1)
5070a9064fbSMasahiro Yamada 			cursor_form_win = prompt_width-1;
5080a9064fbSMasahiro Yamada 
5090a9064fbSMasahiro Yamada 		wmove(form_win, 0, 0);
5100a9064fbSMasahiro Yamada 		wclrtoeol(form_win);
5110a9064fbSMasahiro Yamada 		mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
5120a9064fbSMasahiro Yamada 		mvwprintw(form_win, 0, 0, "%s",
5130a9064fbSMasahiro Yamada 			result + cursor_position-cursor_form_win);
5140a9064fbSMasahiro Yamada 		wmove(form_win, 0, cursor_form_win);
5150a9064fbSMasahiro Yamada 		touchwin(win);
5160a9064fbSMasahiro Yamada 		refresh_all_windows(main_window);
5170a9064fbSMasahiro Yamada 
5180a9064fbSMasahiro Yamada 		if (res == 10) {
5190a9064fbSMasahiro Yamada 			res = 0;
5200a9064fbSMasahiro Yamada 			break;
5210a9064fbSMasahiro Yamada 		} else if (res == 27 || res == KEY_F(F_BACK) ||
5220a9064fbSMasahiro Yamada 				res == KEY_F(F_EXIT)) {
5230a9064fbSMasahiro Yamada 			res = KEY_EXIT;
5240a9064fbSMasahiro Yamada 			break;
5250a9064fbSMasahiro Yamada 		} else if (res == KEY_F(F_HELP)) {
5260a9064fbSMasahiro Yamada 			res = 1;
5270a9064fbSMasahiro Yamada 			break;
5280a9064fbSMasahiro Yamada 		}
5290a9064fbSMasahiro Yamada 	}
5300a9064fbSMasahiro Yamada 
5310a9064fbSMasahiro Yamada 	/* hide the cursor */
5320a9064fbSMasahiro Yamada 	curs_set(0);
5330a9064fbSMasahiro Yamada 	del_panel(panel);
5340a9064fbSMasahiro Yamada 	delwin(prompt_win);
5350a9064fbSMasahiro Yamada 	delwin(form_win);
5360a9064fbSMasahiro Yamada 	delwin(win);
5370a9064fbSMasahiro Yamada 	return res;
5380a9064fbSMasahiro Yamada }
5390a9064fbSMasahiro Yamada 
5400a9064fbSMasahiro Yamada /* refresh all windows in the correct order */
refresh_all_windows(WINDOW * main_window)5410a9064fbSMasahiro Yamada void refresh_all_windows(WINDOW *main_window)
5420a9064fbSMasahiro Yamada {
5430a9064fbSMasahiro Yamada 	update_panels();
5440a9064fbSMasahiro Yamada 	touchwin(main_window);
5450a9064fbSMasahiro Yamada 	refresh();
5460a9064fbSMasahiro Yamada }
5470a9064fbSMasahiro Yamada 
5480a9064fbSMasahiro Yamada /* layman's scrollable window... */
show_scroll_win(WINDOW * main_window,const char * title,const char * text)5490a9064fbSMasahiro Yamada void show_scroll_win(WINDOW *main_window,
5500a9064fbSMasahiro Yamada 		const char *title,
5510a9064fbSMasahiro Yamada 		const char *text)
5520a9064fbSMasahiro Yamada {
5530a9064fbSMasahiro Yamada 	int res;
5540a9064fbSMasahiro Yamada 	int total_lines = get_line_no(text);
5550a9064fbSMasahiro Yamada 	int x, y, lines, columns;
5560a9064fbSMasahiro Yamada 	int start_x = 0, start_y = 0;
5570a9064fbSMasahiro Yamada 	int text_lines = 0, text_cols = 0;
5580a9064fbSMasahiro Yamada 	int total_cols = 0;
5590a9064fbSMasahiro Yamada 	int win_cols = 0;
5600a9064fbSMasahiro Yamada 	int win_lines = 0;
5610a9064fbSMasahiro Yamada 	int i = 0;
5620a9064fbSMasahiro Yamada 	WINDOW *win;
5630a9064fbSMasahiro Yamada 	WINDOW *pad;
5640a9064fbSMasahiro Yamada 	PANEL *panel;
5650a9064fbSMasahiro Yamada 
5660a9064fbSMasahiro Yamada 	getmaxyx(stdscr, lines, columns);
5670a9064fbSMasahiro Yamada 
5680a9064fbSMasahiro Yamada 	/* find the widest line of msg: */
5690a9064fbSMasahiro Yamada 	total_lines = get_line_no(text);
5700a9064fbSMasahiro Yamada 	for (i = 0; i < total_lines; i++) {
5710a9064fbSMasahiro Yamada 		const char *line = get_line(text, i);
5720a9064fbSMasahiro Yamada 		int len = get_line_length(line);
5730a9064fbSMasahiro Yamada 		total_cols = max(total_cols, len+2);
5740a9064fbSMasahiro Yamada 	}
5750a9064fbSMasahiro Yamada 
5760a9064fbSMasahiro Yamada 	/* create the pad */
5770a9064fbSMasahiro Yamada 	pad = newpad(total_lines+10, total_cols+10);
5780a9064fbSMasahiro Yamada 	(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
5790a9064fbSMasahiro Yamada 	fill_window(pad, text);
5800a9064fbSMasahiro Yamada 
5810a9064fbSMasahiro Yamada 	win_lines = min(total_lines+4, lines-2);
5820a9064fbSMasahiro Yamada 	win_cols = min(total_cols+2, columns-2);
5830a9064fbSMasahiro Yamada 	text_lines = max(win_lines-4, 0);
5840a9064fbSMasahiro Yamada 	text_cols = max(win_cols-2, 0);
5850a9064fbSMasahiro Yamada 
5860a9064fbSMasahiro Yamada 	/* place window in middle of screen */
5870a9064fbSMasahiro Yamada 	y = (lines-win_lines)/2;
5880a9064fbSMasahiro Yamada 	x = (columns-win_cols)/2;
5890a9064fbSMasahiro Yamada 
5900a9064fbSMasahiro Yamada 	win = newwin(win_lines, win_cols, y, x);
5910a9064fbSMasahiro Yamada 	keypad(win, TRUE);
5920a9064fbSMasahiro Yamada 	/* show the help in the help window, and show the help panel */
5930a9064fbSMasahiro Yamada 	(void) wattrset(win, attributes[SCROLLWIN_BOX]);
5940a9064fbSMasahiro Yamada 	box(win, 0, 0);
5950a9064fbSMasahiro Yamada 	(void) wattrset(win, attributes[SCROLLWIN_HEADING]);
5960a9064fbSMasahiro Yamada 	mvwprintw(win, 0, 3, " %s ", title);
5970a9064fbSMasahiro Yamada 	panel = new_panel(win);
5980a9064fbSMasahiro Yamada 
5990a9064fbSMasahiro Yamada 	/* handle scrolling */
6000a9064fbSMasahiro Yamada 	do {
6010a9064fbSMasahiro Yamada 
6020a9064fbSMasahiro Yamada 		copywin(pad, win, start_y, start_x, 2, 2, text_lines,
6030a9064fbSMasahiro Yamada 				text_cols, 0);
6040a9064fbSMasahiro Yamada 		print_in_middle(win,
6050a9064fbSMasahiro Yamada 				text_lines+2,
6060a9064fbSMasahiro Yamada 				0,
6070a9064fbSMasahiro Yamada 				text_cols,
6080a9064fbSMasahiro Yamada 				"<OK>",
6090a9064fbSMasahiro Yamada 				attributes[DIALOG_MENU_FORE]);
6100a9064fbSMasahiro Yamada 		wrefresh(win);
6110a9064fbSMasahiro Yamada 
6120a9064fbSMasahiro Yamada 		res = wgetch(win);
6130a9064fbSMasahiro Yamada 		switch (res) {
6140a9064fbSMasahiro Yamada 		case KEY_NPAGE:
6150a9064fbSMasahiro Yamada 		case ' ':
6160a9064fbSMasahiro Yamada 		case 'd':
6170a9064fbSMasahiro Yamada 			start_y += text_lines-2;
6180a9064fbSMasahiro Yamada 			break;
6190a9064fbSMasahiro Yamada 		case KEY_PPAGE:
6200a9064fbSMasahiro Yamada 		case 'u':
6210a9064fbSMasahiro Yamada 			start_y -= text_lines+2;
6220a9064fbSMasahiro Yamada 			break;
6230a9064fbSMasahiro Yamada 		case KEY_HOME:
6240a9064fbSMasahiro Yamada 			start_y = 0;
6250a9064fbSMasahiro Yamada 			break;
6260a9064fbSMasahiro Yamada 		case KEY_END:
6270a9064fbSMasahiro Yamada 			start_y = total_lines-text_lines;
6280a9064fbSMasahiro Yamada 			break;
6290a9064fbSMasahiro Yamada 		case KEY_DOWN:
6300a9064fbSMasahiro Yamada 		case 'j':
6310a9064fbSMasahiro Yamada 			start_y++;
6320a9064fbSMasahiro Yamada 			break;
6330a9064fbSMasahiro Yamada 		case KEY_UP:
6340a9064fbSMasahiro Yamada 		case 'k':
6350a9064fbSMasahiro Yamada 			start_y--;
6360a9064fbSMasahiro Yamada 			break;
6370a9064fbSMasahiro Yamada 		case KEY_LEFT:
6380a9064fbSMasahiro Yamada 		case 'h':
6390a9064fbSMasahiro Yamada 			start_x--;
6400a9064fbSMasahiro Yamada 			break;
6410a9064fbSMasahiro Yamada 		case KEY_RIGHT:
6420a9064fbSMasahiro Yamada 		case 'l':
6430a9064fbSMasahiro Yamada 			start_x++;
6440a9064fbSMasahiro Yamada 			break;
6450a9064fbSMasahiro Yamada 		}
6460a9064fbSMasahiro Yamada 		if (res == 10 || res == 27 || res == 'q' ||
6470a9064fbSMasahiro Yamada 			res == KEY_F(F_HELP) || res == KEY_F(F_BACK) ||
6480a9064fbSMasahiro Yamada 			res == KEY_F(F_EXIT))
6490a9064fbSMasahiro Yamada 			break;
6500a9064fbSMasahiro Yamada 		if (start_y < 0)
6510a9064fbSMasahiro Yamada 			start_y = 0;
6520a9064fbSMasahiro Yamada 		if (start_y >= total_lines-text_lines)
6530a9064fbSMasahiro Yamada 			start_y = total_lines-text_lines;
6540a9064fbSMasahiro Yamada 		if (start_x < 0)
6550a9064fbSMasahiro Yamada 			start_x = 0;
6560a9064fbSMasahiro Yamada 		if (start_x >= total_cols-text_cols)
6570a9064fbSMasahiro Yamada 			start_x = total_cols-text_cols;
6580a9064fbSMasahiro Yamada 	} while (res);
6590a9064fbSMasahiro Yamada 
6600a9064fbSMasahiro Yamada 	del_panel(panel);
6610a9064fbSMasahiro Yamada 	delwin(win);
6620a9064fbSMasahiro Yamada 	refresh_all_windows(main_window);
6630a9064fbSMasahiro Yamada }
664