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 24unsigned char dialog_input_result[MAX_LEN + 1]; 25 26/* 27 * Print the termination buttons 28 */ 29static void 30print_buttons(WINDOW *dialog, int height, int width, int selected) 31{ 32 int x = width / 2 - 11; 33 int y = height - 2; 34 35 print_button (dialog, " Ok ", y, x, selected==0); 36 print_button (dialog, " Help ", y, x + 14, selected==1); 37 38 wmove(dialog, y, x+1+14*selected); 39 wrefresh(dialog); 40} 41 42/* 43 * Display a dialog box for inputing a string 44 */ 45int 46dialog_inputbox (const char *title, const char *prompt, int height, int width, 47 const char *init) 48{ 49 int i, x, y, box_y, box_x, box_width; 50 int input_x = 0, scroll = 0, key = 0, button = -1; 51 unsigned char *instr = dialog_input_result; 52 WINDOW *dialog; 53 54 /* center dialog box on screen */ 55 x = (COLS - width) / 2; 56 y = (LINES - height) / 2; 57 58 59 draw_shadow (stdscr, y, x, height, width); 60 61 dialog = newwin (height, width, y, x); 62 keypad (dialog, TRUE); 63 64 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); 65 wattrset (dialog, border_attr); 66 mvwaddch (dialog, height-3, 0, ACS_LTEE); 67 for (i = 0; i < width - 2; i++) 68 waddch (dialog, ACS_HLINE); 69 wattrset (dialog, dialog_attr); 70 waddch (dialog, ACS_RTEE); 71 72 if (title != NULL && strlen(title) >= width-2 ) { 73 /* truncate long title -- mec */ 74 char * title2 = malloc(width-2+1); 75 memcpy( title2, title, width-2 ); 76 title2[width-2] = '\0'; 77 title = title2; 78 } 79 80 if (title != NULL) { 81 wattrset (dialog, title_attr); 82 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); 83 waddstr (dialog, (char *)title); 84 waddch (dialog, ' '); 85 } 86 87 wattrset (dialog, dialog_attr); 88 print_autowrap (dialog, prompt, width - 2, 1, 3); 89 90 /* Draw the input field box */ 91 box_width = width - 6; 92 getyx (dialog, y, x); 93 box_y = y + 2; 94 box_x = (width - box_width) / 2; 95 draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2, 96 border_attr, dialog_attr); 97 98 print_buttons(dialog, height, width, 0); 99 100 /* Set up the initial value */ 101 wmove (dialog, box_y, box_x); 102 wattrset (dialog, inputbox_attr); 103 104 if (!init) 105 instr[0] = '\0'; 106 else 107 strcpy (instr, init); 108 109 input_x = strlen (instr); 110 111 if (input_x >= box_width) { 112 scroll = input_x - box_width + 1; 113 input_x = box_width - 1; 114 for (i = 0; i < box_width - 1; i++) 115 waddch (dialog, instr[scroll + i]); 116 } else 117 waddstr (dialog, instr); 118 119 wmove (dialog, box_y, box_x + input_x); 120 121 wrefresh (dialog); 122 123 while (key != ESC) { 124 key = wgetch (dialog); 125 126 if (button == -1) { /* Input box selected */ 127 switch (key) { 128 case TAB: 129 case KEY_UP: 130 case KEY_DOWN: 131 break; 132 case KEY_LEFT: 133 continue; 134 case KEY_RIGHT: 135 continue; 136 case KEY_BACKSPACE: 137 case 127: 138 if (input_x || scroll) { 139 wattrset (dialog, inputbox_attr); 140 if (!input_x) { 141 scroll = scroll < box_width - 1 ? 142 0 : scroll - (box_width - 1); 143 wmove (dialog, box_y, box_x); 144 for (i = 0; i < box_width; i++) 145 waddch (dialog, instr[scroll + input_x + i] ? 146 instr[scroll + input_x + i] : ' '); 147 input_x = strlen (instr) - scroll; 148 } else 149 input_x--; 150 instr[scroll + input_x] = '\0'; 151 mvwaddch (dialog, box_y, input_x + box_x, ' '); 152 wmove (dialog, box_y, input_x + box_x); 153 wrefresh (dialog); 154 } 155 continue; 156 default: 157 if (key < 0x100 && isprint (key)) { 158 if (scroll + input_x < MAX_LEN) { 159 wattrset (dialog, inputbox_attr); 160 instr[scroll + input_x] = key; 161 instr[scroll + input_x + 1] = '\0'; 162 if (input_x == box_width - 1) { 163 scroll++; 164 wmove (dialog, box_y, box_x); 165 for (i = 0; i < box_width - 1; i++) 166 waddch (dialog, instr[scroll + i]); 167 } else { 168 wmove (dialog, box_y, input_x++ + box_x); 169 waddch (dialog, key); 170 } 171 wrefresh (dialog); 172 } else 173 flash (); /* Alarm user about overflow */ 174 continue; 175 } 176 } 177 } 178 switch (key) { 179 case 'O': 180 case 'o': 181 delwin (dialog); 182 return 0; 183 case 'H': 184 case 'h': 185 delwin (dialog); 186 return 1; 187 case KEY_UP: 188 case KEY_LEFT: 189 switch (button) { 190 case -1: 191 button = 1; /* Indicates "Cancel" button is selected */ 192 print_buttons(dialog, height, width, 1); 193 break; 194 case 0: 195 button = -1; /* Indicates input box is selected */ 196 print_buttons(dialog, height, width, 0); 197 wmove (dialog, box_y, box_x + input_x); 198 wrefresh (dialog); 199 break; 200 case 1: 201 button = 0; /* Indicates "OK" button is selected */ 202 print_buttons(dialog, height, width, 0); 203 break; 204 } 205 break; 206 case TAB: 207 case KEY_DOWN: 208 case KEY_RIGHT: 209 switch (button) { 210 case -1: 211 button = 0; /* Indicates "OK" button is selected */ 212 print_buttons(dialog, height, width, 0); 213 break; 214 case 0: 215 button = 1; /* Indicates "Cancel" button is selected */ 216 print_buttons(dialog, height, width, 1); 217 break; 218 case 1: 219 button = -1; /* Indicates input box is selected */ 220 print_buttons(dialog, height, width, 0); 221 wmove (dialog, box_y, box_x + input_x); 222 wrefresh (dialog); 223 break; 224 } 225 break; 226 case ' ': 227 case '\n': 228 delwin (dialog); 229 return (button == -1 ? 0 : button); 230 case 'X': 231 case 'x': 232 key = ESC; 233 case ESC: 234 break; 235 } 236 } 237 238 delwin (dialog); 239 return -1; /* ESC pressed */ 240} 241