18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * inputbox.c -- implements the input box 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 68c2ecf20Sopenharmony_ci * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "dialog.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cichar dialog_input_result[MAX_LEN + 1]; 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Print the termination buttons 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_cistatic void print_buttons(WINDOW * dialog, int height, int width, int selected) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci int x = width / 2 - 11; 198c2ecf20Sopenharmony_ci int y = height - 2; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci print_button(dialog, " Ok ", y, x, selected == 0); 228c2ecf20Sopenharmony_ci print_button(dialog, " Help ", y, x + 14, selected == 1); 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci wmove(dialog, y, x + 1 + 14 * selected); 258c2ecf20Sopenharmony_ci wrefresh(dialog); 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* 298c2ecf20Sopenharmony_ci * Display a dialog box for inputing a string 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ciint dialog_inputbox(const char *title, const char *prompt, int height, int width, 328c2ecf20Sopenharmony_ci const char *init) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci int i, x, y, box_y, box_x, box_width; 358c2ecf20Sopenharmony_ci int input_x = 0, key = 0, button = -1; 368c2ecf20Sopenharmony_ci int show_x, len, pos; 378c2ecf20Sopenharmony_ci char *instr = dialog_input_result; 388c2ecf20Sopenharmony_ci WINDOW *dialog; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci if (!init) 418c2ecf20Sopenharmony_ci instr[0] = '\0'; 428c2ecf20Sopenharmony_ci else 438c2ecf20Sopenharmony_ci strcpy(instr, init); 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cido_resize: 468c2ecf20Sopenharmony_ci if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN)) 478c2ecf20Sopenharmony_ci return -ERRDISPLAYTOOSMALL; 488c2ecf20Sopenharmony_ci if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN)) 498c2ecf20Sopenharmony_ci return -ERRDISPLAYTOOSMALL; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci /* center dialog box on screen */ 528c2ecf20Sopenharmony_ci x = (getmaxx(stdscr) - width) / 2; 538c2ecf20Sopenharmony_ci y = (getmaxy(stdscr) - height) / 2; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci draw_shadow(stdscr, y, x, height, width); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci dialog = newwin(height, width, y, x); 588c2ecf20Sopenharmony_ci keypad(dialog, TRUE); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci draw_box(dialog, 0, 0, height, width, 618c2ecf20Sopenharmony_ci dlg.dialog.atr, dlg.border.atr); 628c2ecf20Sopenharmony_ci wattrset(dialog, dlg.border.atr); 638c2ecf20Sopenharmony_ci mvwaddch(dialog, height - 3, 0, ACS_LTEE); 648c2ecf20Sopenharmony_ci for (i = 0; i < width - 2; i++) 658c2ecf20Sopenharmony_ci waddch(dialog, ACS_HLINE); 668c2ecf20Sopenharmony_ci wattrset(dialog, dlg.dialog.atr); 678c2ecf20Sopenharmony_ci waddch(dialog, ACS_RTEE); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci print_title(dialog, title, width); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci wattrset(dialog, dlg.dialog.atr); 728c2ecf20Sopenharmony_ci print_autowrap(dialog, prompt, width - 2, 1, 3); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* Draw the input field box */ 758c2ecf20Sopenharmony_ci box_width = width - 6; 768c2ecf20Sopenharmony_ci getyx(dialog, y, x); 778c2ecf20Sopenharmony_ci box_y = y + 2; 788c2ecf20Sopenharmony_ci box_x = (width - box_width) / 2; 798c2ecf20Sopenharmony_ci draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, 808c2ecf20Sopenharmony_ci dlg.dialog.atr, dlg.border.atr); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci print_buttons(dialog, height, width, 0); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci /* Set up the initial value */ 858c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x); 868c2ecf20Sopenharmony_ci wattrset(dialog, dlg.inputbox.atr); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci len = strlen(instr); 898c2ecf20Sopenharmony_ci pos = len; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci if (len >= box_width) { 928c2ecf20Sopenharmony_ci show_x = len - box_width + 1; 938c2ecf20Sopenharmony_ci input_x = box_width - 1; 948c2ecf20Sopenharmony_ci for (i = 0; i < box_width - 1; i++) 958c2ecf20Sopenharmony_ci waddch(dialog, instr[show_x + i]); 968c2ecf20Sopenharmony_ci } else { 978c2ecf20Sopenharmony_ci show_x = 0; 988c2ecf20Sopenharmony_ci input_x = len; 998c2ecf20Sopenharmony_ci waddstr(dialog, instr); 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x + input_x); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci wrefresh(dialog); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci while (key != KEY_ESC) { 1078c2ecf20Sopenharmony_ci key = wgetch(dialog); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci if (button == -1) { /* Input box selected */ 1108c2ecf20Sopenharmony_ci switch (key) { 1118c2ecf20Sopenharmony_ci case TAB: 1128c2ecf20Sopenharmony_ci case KEY_UP: 1138c2ecf20Sopenharmony_ci case KEY_DOWN: 1148c2ecf20Sopenharmony_ci break; 1158c2ecf20Sopenharmony_ci case KEY_BACKSPACE: 1168c2ecf20Sopenharmony_ci case 8: /* ^H */ 1178c2ecf20Sopenharmony_ci case 127: /* ^? */ 1188c2ecf20Sopenharmony_ci if (pos) { 1198c2ecf20Sopenharmony_ci wattrset(dialog, dlg.inputbox.atr); 1208c2ecf20Sopenharmony_ci if (input_x == 0) { 1218c2ecf20Sopenharmony_ci show_x--; 1228c2ecf20Sopenharmony_ci } else 1238c2ecf20Sopenharmony_ci input_x--; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci if (pos < len) { 1268c2ecf20Sopenharmony_ci for (i = pos - 1; i < len; i++) { 1278c2ecf20Sopenharmony_ci instr[i] = instr[i+1]; 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci } 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci pos--; 1328c2ecf20Sopenharmony_ci len--; 1338c2ecf20Sopenharmony_ci instr[len] = '\0'; 1348c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x); 1358c2ecf20Sopenharmony_ci for (i = 0; i < box_width; i++) { 1368c2ecf20Sopenharmony_ci if (!instr[show_x + i]) { 1378c2ecf20Sopenharmony_ci waddch(dialog, ' '); 1388c2ecf20Sopenharmony_ci break; 1398c2ecf20Sopenharmony_ci } 1408c2ecf20Sopenharmony_ci waddch(dialog, instr[show_x + i]); 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci wmove(dialog, box_y, input_x + box_x); 1438c2ecf20Sopenharmony_ci wrefresh(dialog); 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci continue; 1468c2ecf20Sopenharmony_ci case KEY_LEFT: 1478c2ecf20Sopenharmony_ci if (pos > 0) { 1488c2ecf20Sopenharmony_ci if (input_x > 0) { 1498c2ecf20Sopenharmony_ci wmove(dialog, box_y, --input_x + box_x); 1508c2ecf20Sopenharmony_ci } else if (input_x == 0) { 1518c2ecf20Sopenharmony_ci show_x--; 1528c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x); 1538c2ecf20Sopenharmony_ci for (i = 0; i < box_width; i++) { 1548c2ecf20Sopenharmony_ci if (!instr[show_x + i]) { 1558c2ecf20Sopenharmony_ci waddch(dialog, ' '); 1568c2ecf20Sopenharmony_ci break; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci waddch(dialog, instr[show_x + i]); 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x); 1618c2ecf20Sopenharmony_ci } 1628c2ecf20Sopenharmony_ci pos--; 1638c2ecf20Sopenharmony_ci } 1648c2ecf20Sopenharmony_ci continue; 1658c2ecf20Sopenharmony_ci case KEY_RIGHT: 1668c2ecf20Sopenharmony_ci if (pos < len) { 1678c2ecf20Sopenharmony_ci if (input_x < box_width - 1) { 1688c2ecf20Sopenharmony_ci wmove(dialog, box_y, ++input_x + box_x); 1698c2ecf20Sopenharmony_ci } else if (input_x == box_width - 1) { 1708c2ecf20Sopenharmony_ci show_x++; 1718c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x); 1728c2ecf20Sopenharmony_ci for (i = 0; i < box_width; i++) { 1738c2ecf20Sopenharmony_ci if (!instr[show_x + i]) { 1748c2ecf20Sopenharmony_ci waddch(dialog, ' '); 1758c2ecf20Sopenharmony_ci break; 1768c2ecf20Sopenharmony_ci } 1778c2ecf20Sopenharmony_ci waddch(dialog, instr[show_x + i]); 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci wmove(dialog, box_y, input_x + box_x); 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci pos++; 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci continue; 1848c2ecf20Sopenharmony_ci default: 1858c2ecf20Sopenharmony_ci if (key < 0x100 && isprint(key)) { 1868c2ecf20Sopenharmony_ci if (len < MAX_LEN) { 1878c2ecf20Sopenharmony_ci wattrset(dialog, dlg.inputbox.atr); 1888c2ecf20Sopenharmony_ci if (pos < len) { 1898c2ecf20Sopenharmony_ci for (i = len; i > pos; i--) 1908c2ecf20Sopenharmony_ci instr[i] = instr[i-1]; 1918c2ecf20Sopenharmony_ci instr[pos] = key; 1928c2ecf20Sopenharmony_ci } else { 1938c2ecf20Sopenharmony_ci instr[len] = key; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci pos++; 1968c2ecf20Sopenharmony_ci len++; 1978c2ecf20Sopenharmony_ci instr[len] = '\0'; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci if (input_x == box_width - 1) { 2008c2ecf20Sopenharmony_ci show_x++; 2018c2ecf20Sopenharmony_ci } else { 2028c2ecf20Sopenharmony_ci input_x++; 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x); 2068c2ecf20Sopenharmony_ci for (i = 0; i < box_width; i++) { 2078c2ecf20Sopenharmony_ci if (!instr[show_x + i]) { 2088c2ecf20Sopenharmony_ci waddch(dialog, ' '); 2098c2ecf20Sopenharmony_ci break; 2108c2ecf20Sopenharmony_ci } 2118c2ecf20Sopenharmony_ci waddch(dialog, instr[show_x + i]); 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci wmove(dialog, box_y, input_x + box_x); 2148c2ecf20Sopenharmony_ci wrefresh(dialog); 2158c2ecf20Sopenharmony_ci } else 2168c2ecf20Sopenharmony_ci flash(); /* Alarm user about overflow */ 2178c2ecf20Sopenharmony_ci continue; 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci } 2218c2ecf20Sopenharmony_ci switch (key) { 2228c2ecf20Sopenharmony_ci case 'O': 2238c2ecf20Sopenharmony_ci case 'o': 2248c2ecf20Sopenharmony_ci delwin(dialog); 2258c2ecf20Sopenharmony_ci return 0; 2268c2ecf20Sopenharmony_ci case 'H': 2278c2ecf20Sopenharmony_ci case 'h': 2288c2ecf20Sopenharmony_ci delwin(dialog); 2298c2ecf20Sopenharmony_ci return 1; 2308c2ecf20Sopenharmony_ci case KEY_UP: 2318c2ecf20Sopenharmony_ci case KEY_LEFT: 2328c2ecf20Sopenharmony_ci switch (button) { 2338c2ecf20Sopenharmony_ci case -1: 2348c2ecf20Sopenharmony_ci button = 1; /* Indicates "Help" button is selected */ 2358c2ecf20Sopenharmony_ci print_buttons(dialog, height, width, 1); 2368c2ecf20Sopenharmony_ci break; 2378c2ecf20Sopenharmony_ci case 0: 2388c2ecf20Sopenharmony_ci button = -1; /* Indicates input box is selected */ 2398c2ecf20Sopenharmony_ci print_buttons(dialog, height, width, 0); 2408c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x + input_x); 2418c2ecf20Sopenharmony_ci wrefresh(dialog); 2428c2ecf20Sopenharmony_ci break; 2438c2ecf20Sopenharmony_ci case 1: 2448c2ecf20Sopenharmony_ci button = 0; /* Indicates "OK" button is selected */ 2458c2ecf20Sopenharmony_ci print_buttons(dialog, height, width, 0); 2468c2ecf20Sopenharmony_ci break; 2478c2ecf20Sopenharmony_ci } 2488c2ecf20Sopenharmony_ci break; 2498c2ecf20Sopenharmony_ci case TAB: 2508c2ecf20Sopenharmony_ci case KEY_DOWN: 2518c2ecf20Sopenharmony_ci case KEY_RIGHT: 2528c2ecf20Sopenharmony_ci switch (button) { 2538c2ecf20Sopenharmony_ci case -1: 2548c2ecf20Sopenharmony_ci button = 0; /* Indicates "OK" button is selected */ 2558c2ecf20Sopenharmony_ci print_buttons(dialog, height, width, 0); 2568c2ecf20Sopenharmony_ci break; 2578c2ecf20Sopenharmony_ci case 0: 2588c2ecf20Sopenharmony_ci button = 1; /* Indicates "Help" button is selected */ 2598c2ecf20Sopenharmony_ci print_buttons(dialog, height, width, 1); 2608c2ecf20Sopenharmony_ci break; 2618c2ecf20Sopenharmony_ci case 1: 2628c2ecf20Sopenharmony_ci button = -1; /* Indicates input box is selected */ 2638c2ecf20Sopenharmony_ci print_buttons(dialog, height, width, 0); 2648c2ecf20Sopenharmony_ci wmove(dialog, box_y, box_x + input_x); 2658c2ecf20Sopenharmony_ci wrefresh(dialog); 2668c2ecf20Sopenharmony_ci break; 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci break; 2698c2ecf20Sopenharmony_ci case ' ': 2708c2ecf20Sopenharmony_ci case '\n': 2718c2ecf20Sopenharmony_ci delwin(dialog); 2728c2ecf20Sopenharmony_ci return (button == -1 ? 0 : button); 2738c2ecf20Sopenharmony_ci case 'X': 2748c2ecf20Sopenharmony_ci case 'x': 2758c2ecf20Sopenharmony_ci key = KEY_ESC; 2768c2ecf20Sopenharmony_ci break; 2778c2ecf20Sopenharmony_ci case KEY_ESC: 2788c2ecf20Sopenharmony_ci key = on_key_esc(dialog); 2798c2ecf20Sopenharmony_ci break; 2808c2ecf20Sopenharmony_ci case KEY_RESIZE: 2818c2ecf20Sopenharmony_ci delwin(dialog); 2828c2ecf20Sopenharmony_ci on_key_resize(); 2838c2ecf20Sopenharmony_ci goto do_resize; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci delwin(dialog); 2888c2ecf20Sopenharmony_ci return KEY_ESC; /* ESC pressed */ 2898c2ecf20Sopenharmony_ci} 290