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