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