Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  *  inputbox.c -- implements the input box
0004  *
0005  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
0006  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
0007  */
0008 
0009 #include "dialog.h"
0010 
0011 char dialog_input_result[MAX_LEN + 1];
0012 
0013 /*
0014  *  Print the termination buttons
0015  */
0016 static void print_buttons(WINDOW * dialog, int height, int width, int selected)
0017 {
0018     int x = width / 2 - 11;
0019     int y = height - 2;
0020 
0021     print_button(dialog, "  Ok  ", y, x, selected == 0);
0022     print_button(dialog, " Help ", y, x + 14, selected == 1);
0023 
0024     wmove(dialog, y, x + 1 + 14 * selected);
0025     wrefresh(dialog);
0026 }
0027 
0028 /*
0029  * Display a dialog box for inputing a string
0030  */
0031 int dialog_inputbox(const char *title, const char *prompt, int height, int width,
0032             const char *init)
0033 {
0034     int i, x, y, box_y, box_x, box_width;
0035     int input_x = 0, key = 0, button = -1;
0036     int show_x, len, pos;
0037     char *instr = dialog_input_result;
0038     WINDOW *dialog;
0039 
0040     if (!init)
0041         instr[0] = '\0';
0042     else
0043         strcpy(instr, init);
0044 
0045 do_resize:
0046     if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN))
0047         return -ERRDISPLAYTOOSMALL;
0048     if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN))
0049         return -ERRDISPLAYTOOSMALL;
0050 
0051     /* center dialog box on screen */
0052     x = (getmaxx(stdscr) - width) / 2;
0053     y = (getmaxy(stdscr) - height) / 2;
0054 
0055     draw_shadow(stdscr, y, x, height, width);
0056 
0057     dialog = newwin(height, width, y, x);
0058     keypad(dialog, TRUE);
0059 
0060     draw_box(dialog, 0, 0, height, width,
0061          dlg.dialog.atr, dlg.border.atr);
0062     wattrset(dialog, dlg.border.atr);
0063     mvwaddch(dialog, height - 3, 0, ACS_LTEE);
0064     for (i = 0; i < width - 2; i++)
0065         waddch(dialog, ACS_HLINE);
0066     wattrset(dialog, dlg.dialog.atr);
0067     waddch(dialog, ACS_RTEE);
0068 
0069     print_title(dialog, title, width);
0070 
0071     wattrset(dialog, dlg.dialog.atr);
0072     print_autowrap(dialog, prompt, width - 2, 1, 3);
0073 
0074     /* Draw the input field box */
0075     box_width = width - 6;
0076     getyx(dialog, y, x);
0077     box_y = y + 2;
0078     box_x = (width - box_width) / 2;
0079     draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
0080          dlg.dialog.atr, dlg.border.atr);
0081 
0082     print_buttons(dialog, height, width, 0);
0083 
0084     /* Set up the initial value */
0085     wmove(dialog, box_y, box_x);
0086     wattrset(dialog, dlg.inputbox.atr);
0087 
0088     len = strlen(instr);
0089     pos = len;
0090 
0091     if (len >= box_width) {
0092         show_x = len - box_width + 1;
0093         input_x = box_width - 1;
0094         for (i = 0; i < box_width - 1; i++)
0095             waddch(dialog, instr[show_x + i]);
0096     } else {
0097         show_x = 0;
0098         input_x = len;
0099         waddstr(dialog, instr);
0100     }
0101 
0102     wmove(dialog, box_y, box_x + input_x);
0103 
0104     wrefresh(dialog);
0105 
0106     while (key != KEY_ESC) {
0107         key = wgetch(dialog);
0108 
0109         if (button == -1) { /* Input box selected */
0110             switch (key) {
0111             case TAB:
0112             case KEY_UP:
0113             case KEY_DOWN:
0114                 break;
0115             case KEY_BACKSPACE:
0116             case 8:   /* ^H */
0117             case 127: /* ^? */
0118                 if (pos) {
0119                     wattrset(dialog, dlg.inputbox.atr);
0120                     if (input_x == 0) {
0121                         show_x--;
0122                     } else
0123                         input_x--;
0124 
0125                     if (pos < len) {
0126                         for (i = pos - 1; i < len; i++) {
0127                             instr[i] = instr[i+1];
0128                         }
0129                     }
0130 
0131                     pos--;
0132                     len--;
0133                     instr[len] = '\0';
0134                     wmove(dialog, box_y, box_x);
0135                     for (i = 0; i < box_width; i++) {
0136                         if (!instr[show_x + i]) {
0137                             waddch(dialog, ' ');
0138                             break;
0139                         }
0140                         waddch(dialog, instr[show_x + i]);
0141                     }
0142                     wmove(dialog, box_y, input_x + box_x);
0143                     wrefresh(dialog);
0144                 }
0145                 continue;
0146             case KEY_LEFT:
0147                 if (pos > 0) {
0148                     if (input_x > 0) {
0149                         wmove(dialog, box_y, --input_x + box_x);
0150                     } else if (input_x == 0) {
0151                         show_x--;
0152                         wmove(dialog, box_y, box_x);
0153                         for (i = 0; i < box_width; i++) {
0154                             if (!instr[show_x + i]) {
0155                                 waddch(dialog, ' ');
0156                                 break;
0157                             }
0158                             waddch(dialog, instr[show_x + i]);
0159                         }
0160                         wmove(dialog, box_y, box_x);
0161                     }
0162                     pos--;
0163                 }
0164                 continue;
0165             case KEY_RIGHT:
0166                 if (pos < len) {
0167                     if (input_x < box_width - 1) {
0168                         wmove(dialog, box_y, ++input_x + box_x);
0169                     } else if (input_x == box_width - 1) {
0170                         show_x++;
0171                         wmove(dialog, box_y, box_x);
0172                         for (i = 0; i < box_width; i++) {
0173                             if (!instr[show_x + i]) {
0174                                 waddch(dialog, ' ');
0175                                 break;
0176                             }
0177                             waddch(dialog, instr[show_x + i]);
0178                         }
0179                         wmove(dialog, box_y, input_x + box_x);
0180                     }
0181                     pos++;
0182                 }
0183                 continue;
0184             default:
0185                 if (key < 0x100 && isprint(key)) {
0186                     if (len < MAX_LEN) {
0187                         wattrset(dialog, dlg.inputbox.atr);
0188                         if (pos < len) {
0189                             for (i = len; i > pos; i--)
0190                                 instr[i] = instr[i-1];
0191                             instr[pos] = key;
0192                         } else {
0193                             instr[len] = key;
0194                         }
0195                         pos++;
0196                         len++;
0197                         instr[len] = '\0';
0198 
0199                         if (input_x == box_width - 1) {
0200                             show_x++;
0201                         } else {
0202                             input_x++;
0203                         }
0204 
0205                         wmove(dialog, box_y, box_x);
0206                         for (i = 0; i < box_width; i++) {
0207                             if (!instr[show_x + i]) {
0208                                 waddch(dialog, ' ');
0209                                 break;
0210                             }
0211                             waddch(dialog, instr[show_x + i]);
0212                         }
0213                         wmove(dialog, box_y, input_x + box_x);
0214                         wrefresh(dialog);
0215                     } else
0216                         flash();    /* Alarm user about overflow */
0217                     continue;
0218                 }
0219             }
0220         }
0221         switch (key) {
0222         case 'O':
0223         case 'o':
0224             delwin(dialog);
0225             return 0;
0226         case 'H':
0227         case 'h':
0228             delwin(dialog);
0229             return 1;
0230         case KEY_UP:
0231         case KEY_LEFT:
0232             switch (button) {
0233             case -1:
0234                 button = 1; /* Indicates "Help" button is selected */
0235                 print_buttons(dialog, height, width, 1);
0236                 break;
0237             case 0:
0238                 button = -1;    /* Indicates input box is selected */
0239                 print_buttons(dialog, height, width, 0);
0240                 wmove(dialog, box_y, box_x + input_x);
0241                 wrefresh(dialog);
0242                 break;
0243             case 1:
0244                 button = 0; /* Indicates "OK" button is selected */
0245                 print_buttons(dialog, height, width, 0);
0246                 break;
0247             }
0248             break;
0249         case TAB:
0250         case KEY_DOWN:
0251         case KEY_RIGHT:
0252             switch (button) {
0253             case -1:
0254                 button = 0; /* Indicates "OK" button is selected */
0255                 print_buttons(dialog, height, width, 0);
0256                 break;
0257             case 0:
0258                 button = 1; /* Indicates "Help" button is selected */
0259                 print_buttons(dialog, height, width, 1);
0260                 break;
0261             case 1:
0262                 button = -1;    /* Indicates input box is selected */
0263                 print_buttons(dialog, height, width, 0);
0264                 wmove(dialog, box_y, box_x + input_x);
0265                 wrefresh(dialog);
0266                 break;
0267             }
0268             break;
0269         case ' ':
0270         case '\n':
0271             delwin(dialog);
0272             return (button == -1 ? 0 : button);
0273         case 'X':
0274         case 'x':
0275             key = KEY_ESC;
0276             break;
0277         case KEY_ESC:
0278             key = on_key_esc(dialog);
0279             break;
0280         case KEY_RESIZE:
0281             delwin(dialog);
0282             on_key_resize();
0283             goto do_resize;
0284         }
0285     }
0286 
0287     delwin(dialog);
0288     return KEY_ESC;     /* ESC pressed */
0289 }