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