text: /*
   *  inputbox.c -- implements the input box
   *
   *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
   *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
   *
   *  This program is free software; you can redistribute it and/or
   *  modify it under the terms of the GNU General Public License
   *  as published by the Free Software Foundation; either version 2
   *  of the License, or (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
  
  #include "dialog.h"
  
  char dialog_input_result[MAX_LEN + 1];
  
  /*
   *  Print the termination buttons
   */
  static void print_buttons(WINDOW * dialog, int height, int width, int selected)
  {
  	int x = width / 2 - 11;
  	int y = height - 2;
  
  	print_button(dialog, gettext("  Ok  "), y, x, selected == 0);
  	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
  
  	wmove(dialog, y, x + 1 + 14 * selected);
  	wrefresh(dialog);
  }
  
  /*
   * Display a dialog box for inputing a string
   */
  int dialog_inputbox(const char *title, const char *prompt, int height, int width,
                      const char *init)
  {
  	int i, x, y, box_y, box_x, box_width;
  	int input_x = 0, key = 0, button = -1;
  	int show_x, len, pos;
  	char *instr = dialog_input_result;
  	WINDOW *dialog;
  
  	if (!init)
  		instr[0] = '\0';
  	else
  		strcpy(instr, init);
  
  do_resize:
  	if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN))
  		return -ERRDISPLAYTOOSMALL;
  	if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN))
  		return -ERRDISPLAYTOOSMALL;
  
  	/* center dialog box on screen */
  	x = (getmaxx(stdscr) - width) / 2;
  	y = (getmaxy(stdscr) - height) / 2;
  
  	draw_shadow(stdscr, y, x, height, width);
  
  	dialog = newwin(height, width, y, x);
  	keypad(dialog, TRUE);
  
  	draw_box(dialog, 0, 0, height, width,
  		 dlg.dialog.atr, dlg.border.atr);
  	wattrset(dialog, dlg.border.atr);
  	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
  	for (i = 0; i < width - 2; i++)
  		waddch(dialog, ACS_HLINE);
  	wattrset(dialog, dlg.dialog.atr);
  	waddch(dialog, ACS_RTEE);
  
  	print_title(dialog, title, width);
  
  	wattrset(dialog, dlg.dialog.atr);
  	print_autowrap(dialog, prompt, width - 2, 1, 3);
  
  	/* Draw the input field box */
  	box_width = width - 6;
  	getyx(dialog, y, x);
  	box_y = y + 2;
  	box_x = (width - box_width) / 2;
  	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
  		 dlg.dialog.atr, dlg.border.atr);
  
  	print_buttons(dialog, height, width, 0);
  
  	/* Set up the initial value */
  	wmove(dialog, box_y, box_x);
  	wattrset(dialog, dlg.inputbox.atr);
  
  	len = strlen(instr);
  	pos = len;
  
  	if (len >= box_width) {
  		show_x = len - box_width + 1;
  		input_x = box_width - 1;
  		for (i = 0; i < box_width - 1; i++)
  			waddch(dialog, instr[show_x + i]);
  	} else {
  		show_x = 0;
  		input_x = len;
  		waddstr(dialog, instr);
  	}
  
  	wmove(dialog, box_y, box_x + input_x);
  
  	wrefresh(dialog);
  
  	while (key != KEY_ESC) {
  		key = wgetch(dialog);
  
  		if (button == -1) {	/* Input box selected */
  			switch (key) {
  			case TAB:
  			case KEY_UP:
  			case KEY_DOWN:
  				break;
  			case KEY_BACKSPACE:
  			case 127:
  				if (pos) {
  					wattrset(dialog, dlg.inputbox.atr);
  					if (input_x == 0) {
  						show_x--;
  					} else
  						input_x--;
  
  					if (pos < len) {
  						for (i = pos - 1; i < len; i++) {
  							instr[i] = instr[i+1];
  						}
  					}
  
  					pos--;
  					len--;
  					instr[len] = '\0';
  					wmove(dialog, box_y, box_x);
  					for (i = 0; i < box_width; i++) {
  						if (!instr[show_x + i]) {
  							waddch(dialog, ' ');
  							break;
  						}
  						waddch(dialog, instr[show_x + i]);
  					}
  					wmove(dialog, box_y, input_x + box_x);
  					wrefresh(dialog);
  				}
  				continue;
  			case KEY_LEFT:
  				if (pos > 0) {
  					if (input_x > 0) {
  						wmove(dialog, box_y, --input_x + box_x);
  					} else if (input_x == 0) {
  						show_x--;
  						wmove(dialog, box_y, box_x);
  						for (i = 0; i < box_width; i++) {
  							if (!instr[show_x + i]) {
  								waddch(dialog, ' ');
  								break;
  							}
  							waddch(dialog, instr[show_x + i]);
  						}
  						wmove(dialog, box_y, box_x);
  					}
  					pos--;
  				}
  				continue;
  			case KEY_RIGHT:
  				if (pos < len) {
  					if (input_x < box_width - 1) {
  						wmove(dialog, box_y, ++input_x + box_x);
  					} else if (input_x == box_width - 1) {
  						show_x++;
  						wmove(dialog, box_y, box_x);
  						for (i = 0; i < box_width; i++) {
  							if (!instr[show_x + i]) {
  								waddch(dialog, ' ');
  								break;
  							}
  							waddch(dialog, instr[show_x + i]);
  						}
  						wmove(dialog, box_y, input_x + box_x);
  					}
  					pos++;
  				}
  				continue;
  			default:
  				if (key < 0x100 && isprint(key)) {
  					if (len < MAX_LEN) {
  						wattrset(dialog, dlg.inputbox.atr);
  						if (pos < len) {
  							for (i = len; i > pos; i--)
  								instr[i] = instr[i-1];
  							instr[pos] = key;
  						} else {
  							instr[len] = key;
  						}
  						pos++;
  						len++;
  						instr[len] = '\0';
  
  						if (input_x == box_width - 1) {
  							show_x++;
  						} else {
  							input_x++;
  						}
  
  						wmove(dialog, box_y, box_x);
  						for (i = 0; i < box_width; i++) {
  							if (!instr[show_x + i]) {
  								waddch(dialog, ' ');
  								break;
  							}
  							waddch(dialog, instr[show_x + i]);
  						}
  						wmove(dialog, box_y, input_x + box_x);
  						wrefresh(dialog);
  					} else
  						flash();	/* Alarm user about overflow */
  					continue;
  				}
  			}
  		}
  		switch (key) {
  		case 'O':
  		case 'o':
  			delwin(dialog);
  			return 0;
  		case 'H':
  		case 'h':
  			delwin(dialog);
  			return 1;
  		case KEY_UP:
  		case KEY_LEFT:
  			switch (button) {
  			case -1:
  				button = 1;	/* Indicates "Help" button is selected */
  				print_buttons(dialog, height, width, 1);
  				break;
  			case 0:
  				button = -1;	/* Indicates input box is selected */
  				print_buttons(dialog, height, width, 0);
  				wmove(dialog, box_y, box_x + input_x);
  				wrefresh(dialog);
  				break;
  			case 1:
  				button = 0;	/* Indicates "OK" button is selected */
  				print_buttons(dialog, height, width, 0);
  				break;
  			}
  			break;
  		case TAB:
  		case KEY_DOWN:
  		case KEY_RIGHT:
  			switch (button) {
  			case -1:
  				button = 0;	/* Indicates "OK" button is selected */
  				print_buttons(dialog, height, width, 0);
  				break;
  			case 0:
  				button = 1;	/* Indicates "Help" button is selected */
  				print_buttons(dialog, height, width, 1);
  				break;
  			case 1:
  				button = -1;	/* Indicates input box is selected */
  				print_buttons(dialog, height, width, 0);
  				wmove(dialog, box_y, box_x + input_x);
  				wrefresh(dialog);
  				break;
  			}
  			break;
  		case ' ':
  		case '\n':
  			delwin(dialog);
  			return (button == -1 ? 0 : button);
  		case 'X':
  		case 'x':
  			key = KEY_ESC;
  			break;
  		case KEY_ESC:
  			key = on_key_esc(dialog);
  			break;
  		case KEY_RESIZE:
  			delwin(dialog);
  			on_key_resize();
  			goto do_resize;
  		}
  	}
  
  	delwin(dialog);
  	return KEY_ESC;		/* ESC pressed */
  }
  