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