1*0a9064fbSMasahiro Yamada /* 2*0a9064fbSMasahiro Yamada * inputbox.c -- implements the input box 3*0a9064fbSMasahiro Yamada * 4*0a9064fbSMasahiro Yamada * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 5*0a9064fbSMasahiro Yamada * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 6*0a9064fbSMasahiro Yamada * 7*0a9064fbSMasahiro Yamada * This program is free software; you can redistribute it and/or 8*0a9064fbSMasahiro Yamada * modify it under the terms of the GNU General Public License 9*0a9064fbSMasahiro Yamada * as published by the Free Software Foundation; either version 2 10*0a9064fbSMasahiro Yamada * of the License, or (at your option) any later version. 11*0a9064fbSMasahiro Yamada * 12*0a9064fbSMasahiro Yamada * This program is distributed in the hope that it will be useful, 13*0a9064fbSMasahiro Yamada * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*0a9064fbSMasahiro Yamada * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*0a9064fbSMasahiro Yamada * GNU General Public License for more details. 16*0a9064fbSMasahiro Yamada * 17*0a9064fbSMasahiro Yamada * You should have received a copy of the GNU General Public License 18*0a9064fbSMasahiro Yamada * along with this program; if not, write to the Free Software 19*0a9064fbSMasahiro Yamada * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*0a9064fbSMasahiro Yamada */ 21*0a9064fbSMasahiro Yamada 22*0a9064fbSMasahiro Yamada #include "dialog.h" 23*0a9064fbSMasahiro Yamada 24*0a9064fbSMasahiro Yamada char dialog_input_result[MAX_LEN + 1]; 25*0a9064fbSMasahiro Yamada 26*0a9064fbSMasahiro Yamada /* 27*0a9064fbSMasahiro Yamada * Print the termination buttons 28*0a9064fbSMasahiro Yamada */ 29*0a9064fbSMasahiro Yamada static void print_buttons(WINDOW * dialog, int height, int width, int selected) 30*0a9064fbSMasahiro Yamada { 31*0a9064fbSMasahiro Yamada int x = width / 2 - 11; 32*0a9064fbSMasahiro Yamada int y = height - 2; 33*0a9064fbSMasahiro Yamada 34*0a9064fbSMasahiro Yamada print_button(dialog, gettext(" Ok "), y, x, selected == 0); 35*0a9064fbSMasahiro Yamada print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); 36*0a9064fbSMasahiro Yamada 37*0a9064fbSMasahiro Yamada wmove(dialog, y, x + 1 + 14 * selected); 38*0a9064fbSMasahiro Yamada wrefresh(dialog); 39*0a9064fbSMasahiro Yamada } 40*0a9064fbSMasahiro Yamada 41*0a9064fbSMasahiro Yamada /* 42*0a9064fbSMasahiro Yamada * Display a dialog box for inputing a string 43*0a9064fbSMasahiro Yamada */ 44*0a9064fbSMasahiro Yamada int dialog_inputbox(const char *title, const char *prompt, int height, int width, 45*0a9064fbSMasahiro Yamada const char *init) 46*0a9064fbSMasahiro Yamada { 47*0a9064fbSMasahiro Yamada int i, x, y, box_y, box_x, box_width; 48*0a9064fbSMasahiro Yamada int input_x = 0, key = 0, button = -1; 49*0a9064fbSMasahiro Yamada int show_x, len, pos; 50*0a9064fbSMasahiro Yamada char *instr = dialog_input_result; 51*0a9064fbSMasahiro Yamada WINDOW *dialog; 52*0a9064fbSMasahiro Yamada 53*0a9064fbSMasahiro Yamada if (!init) 54*0a9064fbSMasahiro Yamada instr[0] = '\0'; 55*0a9064fbSMasahiro Yamada else 56*0a9064fbSMasahiro Yamada strcpy(instr, init); 57*0a9064fbSMasahiro Yamada 58*0a9064fbSMasahiro Yamada do_resize: 59*0a9064fbSMasahiro Yamada if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN)) 60*0a9064fbSMasahiro Yamada return -ERRDISPLAYTOOSMALL; 61*0a9064fbSMasahiro Yamada if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN)) 62*0a9064fbSMasahiro Yamada return -ERRDISPLAYTOOSMALL; 63*0a9064fbSMasahiro Yamada 64*0a9064fbSMasahiro Yamada /* center dialog box on screen */ 65*0a9064fbSMasahiro Yamada x = (getmaxx(stdscr) - width) / 2; 66*0a9064fbSMasahiro Yamada y = (getmaxy(stdscr) - height) / 2; 67*0a9064fbSMasahiro Yamada 68*0a9064fbSMasahiro Yamada draw_shadow(stdscr, y, x, height, width); 69*0a9064fbSMasahiro Yamada 70*0a9064fbSMasahiro Yamada dialog = newwin(height, width, y, x); 71*0a9064fbSMasahiro Yamada keypad(dialog, TRUE); 72*0a9064fbSMasahiro Yamada 73*0a9064fbSMasahiro Yamada draw_box(dialog, 0, 0, height, width, 74*0a9064fbSMasahiro Yamada dlg.dialog.atr, dlg.border.atr); 75*0a9064fbSMasahiro Yamada wattrset(dialog, dlg.border.atr); 76*0a9064fbSMasahiro Yamada mvwaddch(dialog, height - 3, 0, ACS_LTEE); 77*0a9064fbSMasahiro Yamada for (i = 0; i < width - 2; i++) 78*0a9064fbSMasahiro Yamada waddch(dialog, ACS_HLINE); 79*0a9064fbSMasahiro Yamada wattrset(dialog, dlg.dialog.atr); 80*0a9064fbSMasahiro Yamada waddch(dialog, ACS_RTEE); 81*0a9064fbSMasahiro Yamada 82*0a9064fbSMasahiro Yamada print_title(dialog, title, width); 83*0a9064fbSMasahiro Yamada 84*0a9064fbSMasahiro Yamada wattrset(dialog, dlg.dialog.atr); 85*0a9064fbSMasahiro Yamada print_autowrap(dialog, prompt, width - 2, 1, 3); 86*0a9064fbSMasahiro Yamada 87*0a9064fbSMasahiro Yamada /* Draw the input field box */ 88*0a9064fbSMasahiro Yamada box_width = width - 6; 89*0a9064fbSMasahiro Yamada getyx(dialog, y, x); 90*0a9064fbSMasahiro Yamada box_y = y + 2; 91*0a9064fbSMasahiro Yamada box_x = (width - box_width) / 2; 92*0a9064fbSMasahiro Yamada draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, 93*0a9064fbSMasahiro Yamada dlg.dialog.atr, dlg.border.atr); 94*0a9064fbSMasahiro Yamada 95*0a9064fbSMasahiro Yamada print_buttons(dialog, height, width, 0); 96*0a9064fbSMasahiro Yamada 97*0a9064fbSMasahiro Yamada /* Set up the initial value */ 98*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x); 99*0a9064fbSMasahiro Yamada wattrset(dialog, dlg.inputbox.atr); 100*0a9064fbSMasahiro Yamada 101*0a9064fbSMasahiro Yamada len = strlen(instr); 102*0a9064fbSMasahiro Yamada pos = len; 103*0a9064fbSMasahiro Yamada 104*0a9064fbSMasahiro Yamada if (len >= box_width) { 105*0a9064fbSMasahiro Yamada show_x = len - box_width + 1; 106*0a9064fbSMasahiro Yamada input_x = box_width - 1; 107*0a9064fbSMasahiro Yamada for (i = 0; i < box_width - 1; i++) 108*0a9064fbSMasahiro Yamada waddch(dialog, instr[show_x + i]); 109*0a9064fbSMasahiro Yamada } else { 110*0a9064fbSMasahiro Yamada show_x = 0; 111*0a9064fbSMasahiro Yamada input_x = len; 112*0a9064fbSMasahiro Yamada waddstr(dialog, instr); 113*0a9064fbSMasahiro Yamada } 114*0a9064fbSMasahiro Yamada 115*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x + input_x); 116*0a9064fbSMasahiro Yamada 117*0a9064fbSMasahiro Yamada wrefresh(dialog); 118*0a9064fbSMasahiro Yamada 119*0a9064fbSMasahiro Yamada while (key != KEY_ESC) { 120*0a9064fbSMasahiro Yamada key = wgetch(dialog); 121*0a9064fbSMasahiro Yamada 122*0a9064fbSMasahiro Yamada if (button == -1) { /* Input box selected */ 123*0a9064fbSMasahiro Yamada switch (key) { 124*0a9064fbSMasahiro Yamada case TAB: 125*0a9064fbSMasahiro Yamada case KEY_UP: 126*0a9064fbSMasahiro Yamada case KEY_DOWN: 127*0a9064fbSMasahiro Yamada break; 128*0a9064fbSMasahiro Yamada case KEY_BACKSPACE: 129*0a9064fbSMasahiro Yamada case 127: 130*0a9064fbSMasahiro Yamada if (pos) { 131*0a9064fbSMasahiro Yamada wattrset(dialog, dlg.inputbox.atr); 132*0a9064fbSMasahiro Yamada if (input_x == 0) { 133*0a9064fbSMasahiro Yamada show_x--; 134*0a9064fbSMasahiro Yamada } else 135*0a9064fbSMasahiro Yamada input_x--; 136*0a9064fbSMasahiro Yamada 137*0a9064fbSMasahiro Yamada if (pos < len) { 138*0a9064fbSMasahiro Yamada for (i = pos - 1; i < len; i++) { 139*0a9064fbSMasahiro Yamada instr[i] = instr[i+1]; 140*0a9064fbSMasahiro Yamada } 141*0a9064fbSMasahiro Yamada } 142*0a9064fbSMasahiro Yamada 143*0a9064fbSMasahiro Yamada pos--; 144*0a9064fbSMasahiro Yamada len--; 145*0a9064fbSMasahiro Yamada instr[len] = '\0'; 146*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x); 147*0a9064fbSMasahiro Yamada for (i = 0; i < box_width; i++) { 148*0a9064fbSMasahiro Yamada if (!instr[show_x + i]) { 149*0a9064fbSMasahiro Yamada waddch(dialog, ' '); 150*0a9064fbSMasahiro Yamada break; 151*0a9064fbSMasahiro Yamada } 152*0a9064fbSMasahiro Yamada waddch(dialog, instr[show_x + i]); 153*0a9064fbSMasahiro Yamada } 154*0a9064fbSMasahiro Yamada wmove(dialog, box_y, input_x + box_x); 155*0a9064fbSMasahiro Yamada wrefresh(dialog); 156*0a9064fbSMasahiro Yamada } 157*0a9064fbSMasahiro Yamada continue; 158*0a9064fbSMasahiro Yamada case KEY_LEFT: 159*0a9064fbSMasahiro Yamada if (pos > 0) { 160*0a9064fbSMasahiro Yamada if (input_x > 0) { 161*0a9064fbSMasahiro Yamada wmove(dialog, box_y, --input_x + box_x); 162*0a9064fbSMasahiro Yamada } else if (input_x == 0) { 163*0a9064fbSMasahiro Yamada show_x--; 164*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x); 165*0a9064fbSMasahiro Yamada for (i = 0; i < box_width; i++) { 166*0a9064fbSMasahiro Yamada if (!instr[show_x + i]) { 167*0a9064fbSMasahiro Yamada waddch(dialog, ' '); 168*0a9064fbSMasahiro Yamada break; 169*0a9064fbSMasahiro Yamada } 170*0a9064fbSMasahiro Yamada waddch(dialog, instr[show_x + i]); 171*0a9064fbSMasahiro Yamada } 172*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x); 173*0a9064fbSMasahiro Yamada } 174*0a9064fbSMasahiro Yamada pos--; 175*0a9064fbSMasahiro Yamada } 176*0a9064fbSMasahiro Yamada continue; 177*0a9064fbSMasahiro Yamada case KEY_RIGHT: 178*0a9064fbSMasahiro Yamada if (pos < len) { 179*0a9064fbSMasahiro Yamada if (input_x < box_width - 1) { 180*0a9064fbSMasahiro Yamada wmove(dialog, box_y, ++input_x + box_x); 181*0a9064fbSMasahiro Yamada } else if (input_x == box_width - 1) { 182*0a9064fbSMasahiro Yamada show_x++; 183*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x); 184*0a9064fbSMasahiro Yamada for (i = 0; i < box_width; i++) { 185*0a9064fbSMasahiro Yamada if (!instr[show_x + i]) { 186*0a9064fbSMasahiro Yamada waddch(dialog, ' '); 187*0a9064fbSMasahiro Yamada break; 188*0a9064fbSMasahiro Yamada } 189*0a9064fbSMasahiro Yamada waddch(dialog, instr[show_x + i]); 190*0a9064fbSMasahiro Yamada } 191*0a9064fbSMasahiro Yamada wmove(dialog, box_y, input_x + box_x); 192*0a9064fbSMasahiro Yamada } 193*0a9064fbSMasahiro Yamada pos++; 194*0a9064fbSMasahiro Yamada } 195*0a9064fbSMasahiro Yamada continue; 196*0a9064fbSMasahiro Yamada default: 197*0a9064fbSMasahiro Yamada if (key < 0x100 && isprint(key)) { 198*0a9064fbSMasahiro Yamada if (len < MAX_LEN) { 199*0a9064fbSMasahiro Yamada wattrset(dialog, dlg.inputbox.atr); 200*0a9064fbSMasahiro Yamada if (pos < len) { 201*0a9064fbSMasahiro Yamada for (i = len; i > pos; i--) 202*0a9064fbSMasahiro Yamada instr[i] = instr[i-1]; 203*0a9064fbSMasahiro Yamada instr[pos] = key; 204*0a9064fbSMasahiro Yamada } else { 205*0a9064fbSMasahiro Yamada instr[len] = key; 206*0a9064fbSMasahiro Yamada } 207*0a9064fbSMasahiro Yamada pos++; 208*0a9064fbSMasahiro Yamada len++; 209*0a9064fbSMasahiro Yamada instr[len] = '\0'; 210*0a9064fbSMasahiro Yamada 211*0a9064fbSMasahiro Yamada if (input_x == box_width - 1) { 212*0a9064fbSMasahiro Yamada show_x++; 213*0a9064fbSMasahiro Yamada } else { 214*0a9064fbSMasahiro Yamada input_x++; 215*0a9064fbSMasahiro Yamada } 216*0a9064fbSMasahiro Yamada 217*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x); 218*0a9064fbSMasahiro Yamada for (i = 0; i < box_width; i++) { 219*0a9064fbSMasahiro Yamada if (!instr[show_x + i]) { 220*0a9064fbSMasahiro Yamada waddch(dialog, ' '); 221*0a9064fbSMasahiro Yamada break; 222*0a9064fbSMasahiro Yamada } 223*0a9064fbSMasahiro Yamada waddch(dialog, instr[show_x + i]); 224*0a9064fbSMasahiro Yamada } 225*0a9064fbSMasahiro Yamada wmove(dialog, box_y, input_x + box_x); 226*0a9064fbSMasahiro Yamada wrefresh(dialog); 227*0a9064fbSMasahiro Yamada } else 228*0a9064fbSMasahiro Yamada flash(); /* Alarm user about overflow */ 229*0a9064fbSMasahiro Yamada continue; 230*0a9064fbSMasahiro Yamada } 231*0a9064fbSMasahiro Yamada } 232*0a9064fbSMasahiro Yamada } 233*0a9064fbSMasahiro Yamada switch (key) { 234*0a9064fbSMasahiro Yamada case 'O': 235*0a9064fbSMasahiro Yamada case 'o': 236*0a9064fbSMasahiro Yamada delwin(dialog); 237*0a9064fbSMasahiro Yamada return 0; 238*0a9064fbSMasahiro Yamada case 'H': 239*0a9064fbSMasahiro Yamada case 'h': 240*0a9064fbSMasahiro Yamada delwin(dialog); 241*0a9064fbSMasahiro Yamada return 1; 242*0a9064fbSMasahiro Yamada case KEY_UP: 243*0a9064fbSMasahiro Yamada case KEY_LEFT: 244*0a9064fbSMasahiro Yamada switch (button) { 245*0a9064fbSMasahiro Yamada case -1: 246*0a9064fbSMasahiro Yamada button = 1; /* Indicates "Help" button is selected */ 247*0a9064fbSMasahiro Yamada print_buttons(dialog, height, width, 1); 248*0a9064fbSMasahiro Yamada break; 249*0a9064fbSMasahiro Yamada case 0: 250*0a9064fbSMasahiro Yamada button = -1; /* Indicates input box is selected */ 251*0a9064fbSMasahiro Yamada print_buttons(dialog, height, width, 0); 252*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x + input_x); 253*0a9064fbSMasahiro Yamada wrefresh(dialog); 254*0a9064fbSMasahiro Yamada break; 255*0a9064fbSMasahiro Yamada case 1: 256*0a9064fbSMasahiro Yamada button = 0; /* Indicates "OK" button is selected */ 257*0a9064fbSMasahiro Yamada print_buttons(dialog, height, width, 0); 258*0a9064fbSMasahiro Yamada break; 259*0a9064fbSMasahiro Yamada } 260*0a9064fbSMasahiro Yamada break; 261*0a9064fbSMasahiro Yamada case TAB: 262*0a9064fbSMasahiro Yamada case KEY_DOWN: 263*0a9064fbSMasahiro Yamada case KEY_RIGHT: 264*0a9064fbSMasahiro Yamada switch (button) { 265*0a9064fbSMasahiro Yamada case -1: 266*0a9064fbSMasahiro Yamada button = 0; /* Indicates "OK" button is selected */ 267*0a9064fbSMasahiro Yamada print_buttons(dialog, height, width, 0); 268*0a9064fbSMasahiro Yamada break; 269*0a9064fbSMasahiro Yamada case 0: 270*0a9064fbSMasahiro Yamada button = 1; /* Indicates "Help" button is selected */ 271*0a9064fbSMasahiro Yamada print_buttons(dialog, height, width, 1); 272*0a9064fbSMasahiro Yamada break; 273*0a9064fbSMasahiro Yamada case 1: 274*0a9064fbSMasahiro Yamada button = -1; /* Indicates input box is selected */ 275*0a9064fbSMasahiro Yamada print_buttons(dialog, height, width, 0); 276*0a9064fbSMasahiro Yamada wmove(dialog, box_y, box_x + input_x); 277*0a9064fbSMasahiro Yamada wrefresh(dialog); 278*0a9064fbSMasahiro Yamada break; 279*0a9064fbSMasahiro Yamada } 280*0a9064fbSMasahiro Yamada break; 281*0a9064fbSMasahiro Yamada case ' ': 282*0a9064fbSMasahiro Yamada case '\n': 283*0a9064fbSMasahiro Yamada delwin(dialog); 284*0a9064fbSMasahiro Yamada return (button == -1 ? 0 : button); 285*0a9064fbSMasahiro Yamada case 'X': 286*0a9064fbSMasahiro Yamada case 'x': 287*0a9064fbSMasahiro Yamada key = KEY_ESC; 288*0a9064fbSMasahiro Yamada break; 289*0a9064fbSMasahiro Yamada case KEY_ESC: 290*0a9064fbSMasahiro Yamada key = on_key_esc(dialog); 291*0a9064fbSMasahiro Yamada break; 292*0a9064fbSMasahiro Yamada case KEY_RESIZE: 293*0a9064fbSMasahiro Yamada delwin(dialog); 294*0a9064fbSMasahiro Yamada on_key_resize(); 295*0a9064fbSMasahiro Yamada goto do_resize; 296*0a9064fbSMasahiro Yamada } 297*0a9064fbSMasahiro Yamada } 298*0a9064fbSMasahiro Yamada 299*0a9064fbSMasahiro Yamada delwin(dialog); 300*0a9064fbSMasahiro Yamada return KEY_ESC; /* ESC pressed */ 301*0a9064fbSMasahiro Yamada } 302