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