162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * inputbox.c -- implements the input box 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 662306a36Sopenharmony_ci * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "dialog.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cichar dialog_input_result[MAX_LEN + 1]; 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * Print the termination buttons 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_cistatic void print_buttons(WINDOW * dialog, int height, int width, int selected) 1762306a36Sopenharmony_ci{ 1862306a36Sopenharmony_ci int x = width / 2 - 11; 1962306a36Sopenharmony_ci int y = height - 2; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci print_button(dialog, " Ok ", y, x, selected == 0); 2262306a36Sopenharmony_ci print_button(dialog, " Help ", y, x + 14, selected == 1); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci wmove(dialog, y, x + 1 + 14 * selected); 2562306a36Sopenharmony_ci wrefresh(dialog); 2662306a36Sopenharmony_ci} 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* 2962306a36Sopenharmony_ci * Display a dialog box for inputing a string 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_ciint dialog_inputbox(const char *title, const char *prompt, int height, int width, 3262306a36Sopenharmony_ci const char *init) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci int i, x, y, box_y, box_x, box_width; 3562306a36Sopenharmony_ci int input_x = 0, key = 0, button = -1; 3662306a36Sopenharmony_ci int show_x, len, pos; 3762306a36Sopenharmony_ci char *instr = dialog_input_result; 3862306a36Sopenharmony_ci WINDOW *dialog; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci if (!init) 4162306a36Sopenharmony_ci instr[0] = '\0'; 4262306a36Sopenharmony_ci else 4362306a36Sopenharmony_ci strcpy(instr, init); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cido_resize: 4662306a36Sopenharmony_ci if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN)) 4762306a36Sopenharmony_ci return -ERRDISPLAYTOOSMALL; 4862306a36Sopenharmony_ci if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN)) 4962306a36Sopenharmony_ci return -ERRDISPLAYTOOSMALL; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci /* center dialog box on screen */ 5262306a36Sopenharmony_ci x = (getmaxx(stdscr) - width) / 2; 5362306a36Sopenharmony_ci y = (getmaxy(stdscr) - height) / 2; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci draw_shadow(stdscr, y, x, height, width); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci dialog = newwin(height, width, y, x); 5862306a36Sopenharmony_ci keypad(dialog, TRUE); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci draw_box(dialog, 0, 0, height, width, 6162306a36Sopenharmony_ci dlg.dialog.atr, dlg.border.atr); 6262306a36Sopenharmony_ci wattrset(dialog, dlg.border.atr); 6362306a36Sopenharmony_ci mvwaddch(dialog, height - 3, 0, ACS_LTEE); 6462306a36Sopenharmony_ci for (i = 0; i < width - 2; i++) 6562306a36Sopenharmony_ci waddch(dialog, ACS_HLINE); 6662306a36Sopenharmony_ci wattrset(dialog, dlg.dialog.atr); 6762306a36Sopenharmony_ci waddch(dialog, ACS_RTEE); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci print_title(dialog, title, width); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci wattrset(dialog, dlg.dialog.atr); 7262306a36Sopenharmony_ci print_autowrap(dialog, prompt, width - 2, 1, 3); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci /* Draw the input field box */ 7562306a36Sopenharmony_ci box_width = width - 6; 7662306a36Sopenharmony_ci getyx(dialog, y, x); 7762306a36Sopenharmony_ci box_y = y + 2; 7862306a36Sopenharmony_ci box_x = (width - box_width) / 2; 7962306a36Sopenharmony_ci draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, 8062306a36Sopenharmony_ci dlg.dialog.atr, dlg.border.atr); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci print_buttons(dialog, height, width, 0); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci /* Set up the initial value */ 8562306a36Sopenharmony_ci wmove(dialog, box_y, box_x); 8662306a36Sopenharmony_ci wattrset(dialog, dlg.inputbox.atr); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci len = strlen(instr); 8962306a36Sopenharmony_ci pos = len; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci if (len >= box_width) { 9262306a36Sopenharmony_ci show_x = len - box_width + 1; 9362306a36Sopenharmony_ci input_x = box_width - 1; 9462306a36Sopenharmony_ci for (i = 0; i < box_width - 1; i++) 9562306a36Sopenharmony_ci waddch(dialog, instr[show_x + i]); 9662306a36Sopenharmony_ci } else { 9762306a36Sopenharmony_ci show_x = 0; 9862306a36Sopenharmony_ci input_x = len; 9962306a36Sopenharmony_ci waddstr(dialog, instr); 10062306a36Sopenharmony_ci } 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci wmove(dialog, box_y, box_x + input_x); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci wrefresh(dialog); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci while (key != KEY_ESC) { 10762306a36Sopenharmony_ci key = wgetch(dialog); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci if (button == -1) { /* Input box selected */ 11062306a36Sopenharmony_ci switch (key) { 11162306a36Sopenharmony_ci case TAB: 11262306a36Sopenharmony_ci case KEY_UP: 11362306a36Sopenharmony_ci case KEY_DOWN: 11462306a36Sopenharmony_ci break; 11562306a36Sopenharmony_ci case KEY_BACKSPACE: 11662306a36Sopenharmony_ci case 8: /* ^H */ 11762306a36Sopenharmony_ci case 127: /* ^? */ 11862306a36Sopenharmony_ci if (pos) { 11962306a36Sopenharmony_ci wattrset(dialog, dlg.inputbox.atr); 12062306a36Sopenharmony_ci if (input_x == 0) { 12162306a36Sopenharmony_ci show_x--; 12262306a36Sopenharmony_ci } else 12362306a36Sopenharmony_ci input_x--; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci if (pos < len) { 12662306a36Sopenharmony_ci for (i = pos - 1; i < len; i++) { 12762306a36Sopenharmony_ci instr[i] = instr[i+1]; 12862306a36Sopenharmony_ci } 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci pos--; 13262306a36Sopenharmony_ci len--; 13362306a36Sopenharmony_ci instr[len] = '\0'; 13462306a36Sopenharmony_ci wmove(dialog, box_y, box_x); 13562306a36Sopenharmony_ci for (i = 0; i < box_width; i++) { 13662306a36Sopenharmony_ci if (!instr[show_x + i]) { 13762306a36Sopenharmony_ci waddch(dialog, ' '); 13862306a36Sopenharmony_ci break; 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci waddch(dialog, instr[show_x + i]); 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci wmove(dialog, box_y, input_x + box_x); 14362306a36Sopenharmony_ci wrefresh(dialog); 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci continue; 14662306a36Sopenharmony_ci case KEY_LEFT: 14762306a36Sopenharmony_ci if (pos > 0) { 14862306a36Sopenharmony_ci if (input_x > 0) { 14962306a36Sopenharmony_ci wmove(dialog, box_y, --input_x + box_x); 15062306a36Sopenharmony_ci } else if (input_x == 0) { 15162306a36Sopenharmony_ci show_x--; 15262306a36Sopenharmony_ci wmove(dialog, box_y, box_x); 15362306a36Sopenharmony_ci for (i = 0; i < box_width; i++) { 15462306a36Sopenharmony_ci if (!instr[show_x + i]) { 15562306a36Sopenharmony_ci waddch(dialog, ' '); 15662306a36Sopenharmony_ci break; 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci waddch(dialog, instr[show_x + i]); 15962306a36Sopenharmony_ci } 16062306a36Sopenharmony_ci wmove(dialog, box_y, box_x); 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci pos--; 16362306a36Sopenharmony_ci } 16462306a36Sopenharmony_ci continue; 16562306a36Sopenharmony_ci case KEY_RIGHT: 16662306a36Sopenharmony_ci if (pos < len) { 16762306a36Sopenharmony_ci if (input_x < box_width - 1) { 16862306a36Sopenharmony_ci wmove(dialog, box_y, ++input_x + box_x); 16962306a36Sopenharmony_ci } else if (input_x == box_width - 1) { 17062306a36Sopenharmony_ci show_x++; 17162306a36Sopenharmony_ci wmove(dialog, box_y, box_x); 17262306a36Sopenharmony_ci for (i = 0; i < box_width; i++) { 17362306a36Sopenharmony_ci if (!instr[show_x + i]) { 17462306a36Sopenharmony_ci waddch(dialog, ' '); 17562306a36Sopenharmony_ci break; 17662306a36Sopenharmony_ci } 17762306a36Sopenharmony_ci waddch(dialog, instr[show_x + i]); 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci wmove(dialog, box_y, input_x + box_x); 18062306a36Sopenharmony_ci } 18162306a36Sopenharmony_ci pos++; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci continue; 18462306a36Sopenharmony_ci default: 18562306a36Sopenharmony_ci if (key < 0x100 && isprint(key)) { 18662306a36Sopenharmony_ci if (len < MAX_LEN) { 18762306a36Sopenharmony_ci wattrset(dialog, dlg.inputbox.atr); 18862306a36Sopenharmony_ci if (pos < len) { 18962306a36Sopenharmony_ci for (i = len; i > pos; i--) 19062306a36Sopenharmony_ci instr[i] = instr[i-1]; 19162306a36Sopenharmony_ci instr[pos] = key; 19262306a36Sopenharmony_ci } else { 19362306a36Sopenharmony_ci instr[len] = key; 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci pos++; 19662306a36Sopenharmony_ci len++; 19762306a36Sopenharmony_ci instr[len] = '\0'; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if (input_x == box_width - 1) { 20062306a36Sopenharmony_ci show_x++; 20162306a36Sopenharmony_ci } else { 20262306a36Sopenharmony_ci input_x++; 20362306a36Sopenharmony_ci } 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci wmove(dialog, box_y, box_x); 20662306a36Sopenharmony_ci for (i = 0; i < box_width; i++) { 20762306a36Sopenharmony_ci if (!instr[show_x + i]) { 20862306a36Sopenharmony_ci waddch(dialog, ' '); 20962306a36Sopenharmony_ci break; 21062306a36Sopenharmony_ci } 21162306a36Sopenharmony_ci waddch(dialog, instr[show_x + i]); 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci wmove(dialog, box_y, input_x + box_x); 21462306a36Sopenharmony_ci wrefresh(dialog); 21562306a36Sopenharmony_ci } else 21662306a36Sopenharmony_ci flash(); /* Alarm user about overflow */ 21762306a36Sopenharmony_ci continue; 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci } 22062306a36Sopenharmony_ci } 22162306a36Sopenharmony_ci switch (key) { 22262306a36Sopenharmony_ci case 'O': 22362306a36Sopenharmony_ci case 'o': 22462306a36Sopenharmony_ci delwin(dialog); 22562306a36Sopenharmony_ci return 0; 22662306a36Sopenharmony_ci case 'H': 22762306a36Sopenharmony_ci case 'h': 22862306a36Sopenharmony_ci delwin(dialog); 22962306a36Sopenharmony_ci return 1; 23062306a36Sopenharmony_ci case KEY_UP: 23162306a36Sopenharmony_ci case KEY_LEFT: 23262306a36Sopenharmony_ci switch (button) { 23362306a36Sopenharmony_ci case -1: 23462306a36Sopenharmony_ci button = 1; /* Indicates "Help" button is selected */ 23562306a36Sopenharmony_ci print_buttons(dialog, height, width, 1); 23662306a36Sopenharmony_ci break; 23762306a36Sopenharmony_ci case 0: 23862306a36Sopenharmony_ci button = -1; /* Indicates input box is selected */ 23962306a36Sopenharmony_ci print_buttons(dialog, height, width, 0); 24062306a36Sopenharmony_ci wmove(dialog, box_y, box_x + input_x); 24162306a36Sopenharmony_ci wrefresh(dialog); 24262306a36Sopenharmony_ci break; 24362306a36Sopenharmony_ci case 1: 24462306a36Sopenharmony_ci button = 0; /* Indicates "OK" button is selected */ 24562306a36Sopenharmony_ci print_buttons(dialog, height, width, 0); 24662306a36Sopenharmony_ci break; 24762306a36Sopenharmony_ci } 24862306a36Sopenharmony_ci break; 24962306a36Sopenharmony_ci case TAB: 25062306a36Sopenharmony_ci case KEY_DOWN: 25162306a36Sopenharmony_ci case KEY_RIGHT: 25262306a36Sopenharmony_ci switch (button) { 25362306a36Sopenharmony_ci case -1: 25462306a36Sopenharmony_ci button = 0; /* Indicates "OK" button is selected */ 25562306a36Sopenharmony_ci print_buttons(dialog, height, width, 0); 25662306a36Sopenharmony_ci break; 25762306a36Sopenharmony_ci case 0: 25862306a36Sopenharmony_ci button = 1; /* Indicates "Help" button is selected */ 25962306a36Sopenharmony_ci print_buttons(dialog, height, width, 1); 26062306a36Sopenharmony_ci break; 26162306a36Sopenharmony_ci case 1: 26262306a36Sopenharmony_ci button = -1; /* Indicates input box is selected */ 26362306a36Sopenharmony_ci print_buttons(dialog, height, width, 0); 26462306a36Sopenharmony_ci wmove(dialog, box_y, box_x + input_x); 26562306a36Sopenharmony_ci wrefresh(dialog); 26662306a36Sopenharmony_ci break; 26762306a36Sopenharmony_ci } 26862306a36Sopenharmony_ci break; 26962306a36Sopenharmony_ci case ' ': 27062306a36Sopenharmony_ci case '\n': 27162306a36Sopenharmony_ci delwin(dialog); 27262306a36Sopenharmony_ci return (button == -1 ? 0 : button); 27362306a36Sopenharmony_ci case 'X': 27462306a36Sopenharmony_ci case 'x': 27562306a36Sopenharmony_ci key = KEY_ESC; 27662306a36Sopenharmony_ci break; 27762306a36Sopenharmony_ci case KEY_ESC: 27862306a36Sopenharmony_ci key = on_key_esc(dialog); 27962306a36Sopenharmony_ci break; 28062306a36Sopenharmony_ci case KEY_RESIZE: 28162306a36Sopenharmony_ci delwin(dialog); 28262306a36Sopenharmony_ci on_key_resize(); 28362306a36Sopenharmony_ci goto do_resize; 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci } 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci delwin(dialog); 28862306a36Sopenharmony_ci return KEY_ESC; /* ESC pressed */ 28962306a36Sopenharmony_ci} 290