xref: /rk3399_rockchip-uboot/scripts/kconfig/lxdialog/inputbox.c (revision 0a9064fb47bb0a239c04b0b63edebfdd3a201fdc)
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