aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/lxdialog
diff options
context:
space:
mode:
authorSam Ravnborg <sam@mars.ravnborg.org>2005-12-16 15:35:19 -0500
committerSam Ravnborg <sam@mars.ravnborg.org>2005-12-16 15:35:19 -0500
commit6f6046cff2e8f04d6b916b10ebaa7b40d7e7967a (patch)
tree91a143eb6caba421b3f2f1c26d06bd8716da765e /scripts/kconfig/lxdialog
parente067e1f98d54d62fd598126f95e7684e5b63e67f (diff)
kconfig: move lxdialog to scripts/kconfig/lxdialog
The only lxdialog user i kconfig - for menuconfig. So move it to reflect this. Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts/kconfig/lxdialog')
-rw-r--r--scripts/kconfig/lxdialog/BIG.FAT.WARNING4
-rw-r--r--scripts/kconfig/lxdialog/Makefile42
-rw-r--r--scripts/kconfig/lxdialog/checklist.c353
-rw-r--r--scripts/kconfig/lxdialog/colors.h154
-rw-r--r--scripts/kconfig/lxdialog/dialog.h184
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c224
-rw-r--r--scripts/kconfig/lxdialog/lxdialog.c212
-rw-r--r--scripts/kconfig/lxdialog/menubox.c425
-rw-r--r--scripts/kconfig/lxdialog/msgbox.c71
-rw-r--r--scripts/kconfig/lxdialog/textbox.c533
-rw-r--r--scripts/kconfig/lxdialog/util.c362
-rw-r--r--scripts/kconfig/lxdialog/yesno.c102
12 files changed, 2666 insertions, 0 deletions
diff --git a/scripts/kconfig/lxdialog/BIG.FAT.WARNING b/scripts/kconfig/lxdialog/BIG.FAT.WARNING
new file mode 100644
index 000000000000..a8999d82bdb3
--- /dev/null
+++ b/scripts/kconfig/lxdialog/BIG.FAT.WARNING
@@ -0,0 +1,4 @@
1This is NOT the official version of dialog. This version has been
2significantly modified from the original. It is for use by the Linux
3kernel configuration script. Please do not bother Savio Lam with
4questions about this program.
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
new file mode 100644
index 000000000000..a45a13fb26ed
--- /dev/null
+++ b/scripts/kconfig/lxdialog/Makefile
@@ -0,0 +1,42 @@
1HOST_EXTRACFLAGS := -DLOCALE
2ifeq ($(shell uname),SunOS)
3HOST_LOADLIBES := -lcurses
4else
5HOST_LOADLIBES := -lncurses
6endif
7
8ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
9 HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
10else
11ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
12 HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
13else
14ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
15 HOST_EXTRACFLAGS += -DCURSES_LOC="<ncurses.h>"
16else
17 HOST_EXTRACFLAGS += -DCURSES_LOC="<curses.h>"
18endif
19endif
20endif
21
22hostprogs-y := lxdialog
23always := ncurses $(hostprogs-y)
24
25lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
26 util.o lxdialog.o msgbox.o
27
28.PHONY: $(obj)/ncurses
29$(obj)/ncurses:
30 @echo "main() {}" > lxtemp.c
31 @if $(HOSTCC) lxtemp.c $(HOST_LOADLIBES); then \
32 rm -f lxtemp.c a.out; \
33 else \
34 rm -f lxtemp.c; \
35 echo -e "\007" ;\
36 echo ">> Unable to find the Ncurses libraries." ;\
37 echo ">>" ;\
38 echo ">> You must install ncurses-devel in order" ;\
39 echo ">> to use 'make menuconfig'" ;\
40 echo ;\
41 exit 1 ;\
42 fi
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
new file mode 100644
index 000000000000..3fb681fb9632
--- /dev/null
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -0,0 +1,353 @@
1/*
2 * checklist.c -- implements the checklist box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
6 * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
7 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "dialog.h"
25
26static int list_width, check_x, item_x, checkflag;
27
28/*
29 * Print list item
30 */
31static void print_item(WINDOW * win, const char *item, int status, int choice,
32 int selected)
33{
34 int i;
35
36 /* Clear 'residue' of last item */
37 wattrset(win, menubox_attr);
38 wmove(win, choice, 0);
39 for (i = 0; i < list_width; i++)
40 waddch(win, ' ');
41
42 wmove(win, choice, check_x);
43 wattrset(win, selected ? check_selected_attr : check_attr);
44 if (checkflag == FLAG_CHECK)
45 wprintw(win, "[%c]", status ? 'X' : ' ');
46 else
47 wprintw(win, "(%c)", status ? 'X' : ' ');
48
49 wattrset(win, selected ? tag_selected_attr : tag_attr);
50 mvwaddch(win, choice, item_x, item[0]);
51 wattrset(win, selected ? item_selected_attr : item_attr);
52 waddstr(win, (char *)item + 1);
53 if (selected) {
54 wmove(win, choice, check_x + 1);
55 wrefresh(win);
56 }
57}
58
59/*
60 * Print the scroll indicators.
61 */
62static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
63 int y, int x, int height)
64{
65 wmove(win, y, x);
66
67 if (scroll > 0) {
68 wattrset(win, uarrow_attr);
69 waddch(win, ACS_UARROW);
70 waddstr(win, "(-)");
71 } else {
72 wattrset(win, menubox_attr);
73 waddch(win, ACS_HLINE);
74 waddch(win, ACS_HLINE);
75 waddch(win, ACS_HLINE);
76 waddch(win, ACS_HLINE);
77 }
78
79 y = y + height + 1;
80 wmove(win, y, x);
81
82 if ((height < item_no) && (scroll + choice < item_no - 1)) {
83 wattrset(win, darrow_attr);
84 waddch(win, ACS_DARROW);
85 waddstr(win, "(+)");
86 } else {
87 wattrset(win, menubox_border_attr);
88 waddch(win, ACS_HLINE);
89 waddch(win, ACS_HLINE);
90 waddch(win, ACS_HLINE);
91 waddch(win, ACS_HLINE);
92 }
93}
94
95/*
96 * Display the termination buttons
97 */
98static void print_buttons(WINDOW * dialog, int height, int width, int selected)
99{
100 int x = width / 2 - 11;
101 int y = height - 2;
102
103 print_button(dialog, "Select", y, x, selected == 0);
104 print_button(dialog, " Help ", y, x + 14, selected == 1);
105
106 wmove(dialog, y, x + 1 + 14 * selected);
107 wrefresh(dialog);
108}
109
110/*
111 * Display a dialog box with a list of options that can be turned on or off
112 * The `flag' parameter is used to select between radiolist and checklist.
113 */
114int dialog_checklist(const char *title, const char *prompt, int height,
115 int width, int list_height, int item_no,
116 const char *const *items, int flag)
117{
118 int i, x, y, box_x, box_y;
119 int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
120 WINDOW *dialog, *list;
121
122 checkflag = flag;
123
124 /* Allocate space for storing item on/off status */
125 if ((status = malloc(sizeof(int) * item_no)) == NULL) {
126 endwin();
127 fprintf(stderr,
128 "\nCan't allocate memory in dialog_checklist().\n");
129 exit(-1);
130 }
131
132 /* Initializes status */
133 for (i = 0; i < item_no; i++) {
134 status[i] = !strcasecmp(items[i * 3 + 2], "on");
135 if ((!choice && status[i])
136 || !strcasecmp(items[i * 3 + 2], "selected"))
137 choice = i + 1;
138 }
139 if (choice)
140 choice--;
141
142 max_choice = MIN(list_height, item_no);
143
144 /* center dialog box on screen */
145 x = (COLS - width) / 2;
146 y = (LINES - height) / 2;
147
148 draw_shadow(stdscr, y, x, height, width);
149
150 dialog = newwin(height, width, y, x);
151 keypad(dialog, TRUE);
152
153 draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
154 wattrset(dialog, border_attr);
155 mvwaddch(dialog, height - 3, 0, ACS_LTEE);
156 for (i = 0; i < width - 2; i++)
157 waddch(dialog, ACS_HLINE);
158 wattrset(dialog, dialog_attr);
159 waddch(dialog, ACS_RTEE);
160
161 print_title(dialog, title, width);
162
163 wattrset(dialog, dialog_attr);
164 print_autowrap(dialog, prompt, width - 2, 1, 3);
165
166 list_width = width - 6;
167 box_y = height - list_height - 5;
168 box_x = (width - list_width) / 2 - 1;
169
170 /* create new window for the list */
171 list = subwin(dialog, list_height, list_width, y + box_y + 1,
172 x + box_x + 1);
173
174 keypad(list, TRUE);
175
176 /* draw a box around the list items */
177 draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
178 menubox_border_attr, menubox_attr);
179
180 /* Find length of longest item in order to center checklist */
181 check_x = 0;
182 for (i = 0; i < item_no; i++)
183 check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
184
185 check_x = (list_width - check_x) / 2;
186 item_x = check_x + 4;
187
188 if (choice >= list_height) {
189 scroll = choice - list_height + 1;
190 choice -= scroll;
191 }
192
193 /* Print the list */
194 for (i = 0; i < max_choice; i++) {
195 print_item(list, items[(scroll + i) * 3 + 1],
196 status[i + scroll], i, i == choice);
197 }
198
199 print_arrows(dialog, choice, item_no, scroll,
200 box_y, box_x + check_x + 5, list_height);
201
202 print_buttons(dialog, height, width, 0);
203
204 wnoutrefresh(list);
205 wnoutrefresh(dialog);
206 doupdate();
207
208 while (key != ESC) {
209 key = wgetch(dialog);
210
211 for (i = 0; i < max_choice; i++)
212 if (toupper(key) ==
213 toupper(items[(scroll + i) * 3 + 1][0]))
214 break;
215
216 if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
217 key == '+' || key == '-') {
218 if (key == KEY_UP || key == '-') {
219 if (!choice) {
220 if (!scroll)
221 continue;
222 /* Scroll list down */
223 if (list_height > 1) {
224 /* De-highlight current first item */
225 print_item(list, items[scroll * 3 + 1],
226 status[scroll], 0, FALSE);
227 scrollok(list, TRUE);
228 wscrl(list, -1);
229 scrollok(list, FALSE);
230 }
231 scroll--;
232 print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
233 wnoutrefresh(list);
234
235 print_arrows(dialog, choice, item_no,
236 scroll, box_y, box_x + check_x + 5, list_height);
237
238 wrefresh(dialog);
239
240 continue; /* wait for another key press */
241 } else
242 i = choice - 1;
243 } else if (key == KEY_DOWN || key == '+') {
244 if (choice == max_choice - 1) {
245 if (scroll + choice >= item_no - 1)
246 continue;
247 /* Scroll list up */
248 if (list_height > 1) {
249 /* De-highlight current last item before scrolling up */
250 print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
251 status[scroll + max_choice - 1],
252 max_choice - 1, FALSE);
253 scrollok(list, TRUE);
254 wscrl(list, 1);
255 scrollok(list, FALSE);
256 }
257 scroll++;
258 print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
259 status[scroll + max_choice - 1], max_choice - 1, TRUE);
260 wnoutrefresh(list);
261
262 print_arrows(dialog, choice, item_no,
263 scroll, box_y, box_x + check_x + 5, list_height);
264
265 wrefresh(dialog);
266
267 continue; /* wait for another key press */
268 } else
269 i = choice + 1;
270 }
271 if (i != choice) {
272 /* De-highlight current item */
273 print_item(list, items[(scroll + choice) * 3 + 1],
274 status[scroll + choice], choice, FALSE);
275 /* Highlight new item */
276 choice = i;
277 print_item(list, items[(scroll + choice) * 3 + 1],
278 status[scroll + choice], choice, TRUE);
279 wnoutrefresh(list);
280 wrefresh(dialog);
281 }
282 continue; /* wait for another key press */
283 }
284 switch (key) {
285 case 'H':
286 case 'h':
287 case '?':
288 fprintf(stderr, "%s", items[(scroll + choice) * 3]);
289 delwin(dialog);
290 free(status);
291 return 1;
292 case TAB:
293 case KEY_LEFT:
294 case KEY_RIGHT:
295 button = ((key == KEY_LEFT ? --button : ++button) < 0)
296 ? 1 : (button > 1 ? 0 : button);
297
298 print_buttons(dialog, height, width, button);
299 wrefresh(dialog);
300 break;
301 case 'S':
302 case 's':
303 case ' ':
304 case '\n':
305 if (!button) {
306 if (flag == FLAG_CHECK) {
307 status[scroll + choice] = !status[scroll + choice];
308 wmove(list, choice, check_x);
309 wattrset(list, check_selected_attr);
310 wprintw(list, "[%c]", status[scroll + choice] ? 'X' : ' ');
311 } else {
312 if (!status[scroll + choice]) {
313 for (i = 0; i < item_no; i++)
314 status[i] = 0;
315 status[scroll + choice] = 1;
316 for (i = 0; i < max_choice; i++)
317 print_item(list, items[(scroll + i) * 3 + 1],
318 status[scroll + i], i, i == choice);
319 }
320 }
321 wnoutrefresh(list);
322 wrefresh(dialog);
323
324 for (i = 0; i < item_no; i++) {
325 if (status[i]) {
326 if (flag == FLAG_CHECK) {
327 fprintf(stderr, "\"%s\" ", items[i * 3]);
328 } else {
329 fprintf(stderr, "%s", items[i * 3]);
330 }
331
332 }
333 }
334 } else
335 fprintf(stderr, "%s", items[(scroll + choice) * 3]);
336 delwin(dialog);
337 free(status);
338 return button;
339 case 'X':
340 case 'x':
341 key = ESC;
342 case ESC:
343 break;
344 }
345
346 /* Now, update everything... */
347 doupdate();
348 }
349
350 delwin(dialog);
351 free(status);
352 return -1; /* ESC pressed */
353}
diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h
new file mode 100644
index 000000000000..db071df12bbb
--- /dev/null
+++ b/scripts/kconfig/lxdialog/colors.h
@@ -0,0 +1,154 @@
1/*
2 * colors.h -- color attribute definitions
3 *
4 * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21/*
22 * Default color definitions
23 *
24 * *_FG = foreground
25 * *_BG = background
26 * *_HL = highlight?
27 */
28#define SCREEN_FG COLOR_CYAN
29#define SCREEN_BG COLOR_BLUE
30#define SCREEN_HL TRUE
31
32#define SHADOW_FG COLOR_BLACK
33#define SHADOW_BG COLOR_BLACK
34#define SHADOW_HL TRUE
35
36#define DIALOG_FG COLOR_BLACK
37#define DIALOG_BG COLOR_WHITE
38#define DIALOG_HL FALSE
39
40#define TITLE_FG COLOR_YELLOW
41#define TITLE_BG COLOR_WHITE
42#define TITLE_HL TRUE
43
44#define BORDER_FG COLOR_WHITE
45#define BORDER_BG COLOR_WHITE
46#define BORDER_HL TRUE
47
48#define BUTTON_ACTIVE_FG COLOR_WHITE
49#define BUTTON_ACTIVE_BG COLOR_BLUE
50#define BUTTON_ACTIVE_HL TRUE
51
52#define BUTTON_INACTIVE_FG COLOR_BLACK
53#define BUTTON_INACTIVE_BG COLOR_WHITE
54#define BUTTON_INACTIVE_HL FALSE
55
56#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
57#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
58#define BUTTON_KEY_ACTIVE_HL TRUE
59
60#define BUTTON_KEY_INACTIVE_FG COLOR_RED
61#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
62#define BUTTON_KEY_INACTIVE_HL FALSE
63
64#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
65#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
66#define BUTTON_LABEL_ACTIVE_HL TRUE
67
68#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
69#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
70#define BUTTON_LABEL_INACTIVE_HL TRUE
71
72#define INPUTBOX_FG COLOR_BLACK
73#define INPUTBOX_BG COLOR_WHITE
74#define INPUTBOX_HL FALSE
75
76#define INPUTBOX_BORDER_FG COLOR_BLACK
77#define INPUTBOX_BORDER_BG COLOR_WHITE
78#define INPUTBOX_BORDER_HL FALSE
79
80#define SEARCHBOX_FG COLOR_BLACK
81#define SEARCHBOX_BG COLOR_WHITE
82#define SEARCHBOX_HL FALSE
83
84#define SEARCHBOX_TITLE_FG COLOR_YELLOW
85#define SEARCHBOX_TITLE_BG COLOR_WHITE
86#define SEARCHBOX_TITLE_HL TRUE
87
88#define SEARCHBOX_BORDER_FG COLOR_WHITE
89#define SEARCHBOX_BORDER_BG COLOR_WHITE
90#define SEARCHBOX_BORDER_HL TRUE
91
92#define POSITION_INDICATOR_FG COLOR_YELLOW
93#define POSITION_INDICATOR_BG COLOR_WHITE
94#define POSITION_INDICATOR_HL TRUE
95
96#define MENUBOX_FG COLOR_BLACK
97#define MENUBOX_BG COLOR_WHITE
98#define MENUBOX_HL FALSE
99
100#define MENUBOX_BORDER_FG COLOR_WHITE
101#define MENUBOX_BORDER_BG COLOR_WHITE
102#define MENUBOX_BORDER_HL TRUE
103
104#define ITEM_FG COLOR_BLACK
105#define ITEM_BG COLOR_WHITE
106#define ITEM_HL FALSE
107
108#define ITEM_SELECTED_FG COLOR_WHITE
109#define ITEM_SELECTED_BG COLOR_BLUE
110#define ITEM_SELECTED_HL TRUE
111
112#define TAG_FG COLOR_YELLOW
113#define TAG_BG COLOR_WHITE
114#define TAG_HL TRUE
115
116#define TAG_SELECTED_FG COLOR_YELLOW
117#define TAG_SELECTED_BG COLOR_BLUE
118#define TAG_SELECTED_HL TRUE
119
120#define TAG_KEY_FG COLOR_YELLOW
121#define TAG_KEY_BG COLOR_WHITE
122#define TAG_KEY_HL TRUE
123
124#define TAG_KEY_SELECTED_FG COLOR_YELLOW
125#define TAG_KEY_SELECTED_BG COLOR_BLUE
126#define TAG_KEY_SELECTED_HL TRUE
127
128#define CHECK_FG COLOR_BLACK
129#define CHECK_BG COLOR_WHITE
130#define CHECK_HL FALSE
131
132#define CHECK_SELECTED_FG COLOR_WHITE
133#define CHECK_SELECTED_BG COLOR_BLUE
134#define CHECK_SELECTED_HL TRUE
135
136#define UARROW_FG COLOR_GREEN
137#define UARROW_BG COLOR_WHITE
138#define UARROW_HL TRUE
139
140#define DARROW_FG COLOR_GREEN
141#define DARROW_BG COLOR_WHITE
142#define DARROW_HL TRUE
143
144/* End of default color definitions */
145
146#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
147#define COLOR_NAME_LEN 10
148#define COLOR_COUNT 8
149
150/*
151 * Global variables
152 */
153
154extern int color_table[][3];
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
new file mode 100644
index 000000000000..f882204cb3c2
--- /dev/null
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -0,0 +1,184 @@
1/*
2 * dialog.h -- common declarations for all dialog modules
3 *
4 * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <sys/types.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <ctype.h>
25#include <stdlib.h>
26#include <string.h>
27
28#ifdef __sun__
29#define CURS_MACROS
30#endif
31#include CURSES_LOC
32
33/*
34 * Colors in ncurses 1.9.9e do not work properly since foreground and
35 * background colors are OR'd rather than separately masked. This version
36 * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
37 * with standard curses. The simplest fix (to make this work with standard
38 * curses) uses the wbkgdset() function, not used in the original hack.
39 * Turn it off if we're building with 1.9.9e, since it just confuses things.
40 */
41#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
42#define OLD_NCURSES 1
43#undef wbkgdset
44#define wbkgdset(w,p) /*nothing */
45#else
46#define OLD_NCURSES 0
47#endif
48
49#define TR(params) _tracef params
50
51#define ESC 27
52#define TAB 9
53#define MAX_LEN 2048
54#define BUF_SIZE (10*1024)
55#define MIN(x,y) (x < y ? x : y)
56#define MAX(x,y) (x > y ? x : y)
57
58#ifndef ACS_ULCORNER
59#define ACS_ULCORNER '+'
60#endif
61#ifndef ACS_LLCORNER
62#define ACS_LLCORNER '+'
63#endif
64#ifndef ACS_URCORNER
65#define ACS_URCORNER '+'
66#endif
67#ifndef ACS_LRCORNER
68#define ACS_LRCORNER '+'
69#endif
70#ifndef ACS_HLINE
71#define ACS_HLINE '-'
72#endif
73#ifndef ACS_VLINE
74#define ACS_VLINE '|'
75#endif
76#ifndef ACS_LTEE
77#define ACS_LTEE '+'
78#endif
79#ifndef ACS_RTEE
80#define ACS_RTEE '+'
81#endif
82#ifndef ACS_UARROW
83#define ACS_UARROW '^'
84#endif
85#ifndef ACS_DARROW
86#define ACS_DARROW 'v'
87#endif
88
89/*
90 * Attribute names
91 */
92#define screen_attr attributes[0]
93#define shadow_attr attributes[1]
94#define dialog_attr attributes[2]
95#define title_attr attributes[3]
96#define border_attr attributes[4]
97#define button_active_attr attributes[5]
98#define button_inactive_attr attributes[6]
99#define button_key_active_attr attributes[7]
100#define button_key_inactive_attr attributes[8]
101#define button_label_active_attr attributes[9]
102#define button_label_inactive_attr attributes[10]
103#define inputbox_attr attributes[11]
104#define inputbox_border_attr attributes[12]
105#define searchbox_attr attributes[13]
106#define searchbox_title_attr attributes[14]
107#define searchbox_border_attr attributes[15]
108#define position_indicator_attr attributes[16]
109#define menubox_attr attributes[17]
110#define menubox_border_attr attributes[18]
111#define item_attr attributes[19]
112#define item_selected_attr attributes[20]
113#define tag_attr attributes[21]
114#define tag_selected_attr attributes[22]
115#define tag_key_attr attributes[23]
116#define tag_key_selected_attr attributes[24]
117#define check_attr attributes[25]
118#define check_selected_attr attributes[26]
119#define uarrow_attr attributes[27]
120#define darrow_attr attributes[28]
121
122/* number of attributes */
123#define ATTRIBUTE_COUNT 29
124
125/*
126 * Global variables
127 */
128extern bool use_colors;
129extern bool use_shadow;
130
131extern chtype attributes[];
132
133extern const char *backtitle;
134
135/*
136 * Function prototypes
137 */
138extern void create_rc(const char *filename);
139extern int parse_rc(void);
140
141void init_dialog(void);
142void end_dialog(void);
143void attr_clear(WINDOW * win, int height, int width, chtype attr);
144void dialog_clear(void);
145void color_setup(void);
146void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
147void print_button(WINDOW * win, const char *label, int y, int x, int selected);
148void print_title(WINDOW *dialog, const char *title, int width);
149void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box,
150 chtype border);
151void draw_shadow(WINDOW * win, int y, int x, int height, int width);
152
153int first_alpha(const char *string, const char *exempt);
154int dialog_yesno(const char *title, const char *prompt, int height, int width);
155int dialog_msgbox(const char *title, const char *prompt, int height,
156 int width, int pause);
157int dialog_textbox(const char *title, const char *file, int height, int width);
158int dialog_menu(const char *title, const char *prompt, int height, int width,
159 int menu_height, const char *choice, int item_no,
160 const char *const *items);
161int dialog_checklist(const char *title, const char *prompt, int height,
162 int width, int list_height, int item_no,
163 const char *const *items, int flag);
164extern char dialog_input_result[];
165int dialog_inputbox(const char *title, const char *prompt, int height,
166 int width, const char *init);
167
168/*
169 * This is the base for fictitious keys, which activate
170 * the buttons.
171 *
172 * Mouse-generated keys are the following:
173 * -- the first 32 are used as numbers, in addition to '0'-'9'
174 * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
175 * -- uppercase chars are used to invoke the button (M_EVENT + 'O')
176 */
177#define M_EVENT (KEY_MAX+1)
178
179/*
180 * The `flag' parameter in checklist is used to select between
181 * radiolist and checklist
182 */
183#define FLAG_CHECK 1
184#define FLAG_RADIO 0
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
new file mode 100644
index 000000000000..779503726b0a
--- /dev/null
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -0,0 +1,224 @@
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
24char dialog_input_result[MAX_LEN + 1];
25
26/*
27 * Print the termination buttons
28 */
29static 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 */
44int 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, scroll = 0, key = 0, button = -1;
49 char *instr = dialog_input_result;
50 WINDOW *dialog;
51
52 /* center dialog box on screen */
53 x = (COLS - width) / 2;
54 y = (LINES - height) / 2;
55
56 draw_shadow(stdscr, y, x, height, width);
57
58 dialog = newwin(height, width, y, x);
59 keypad(dialog, TRUE);
60
61 draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
62 wattrset(dialog, border_attr);
63 mvwaddch(dialog, height - 3, 0, ACS_LTEE);
64 for (i = 0; i < width - 2; i++)
65 waddch(dialog, ACS_HLINE);
66 wattrset(dialog, dialog_attr);
67 waddch(dialog, ACS_RTEE);
68
69 print_title(dialog, title, width);
70
71 wattrset(dialog, dialog_attr);
72 print_autowrap(dialog, prompt, width - 2, 1, 3);
73
74 /* Draw the input field box */
75 box_width = width - 6;
76 getyx(dialog, y, x);
77 box_y = y + 2;
78 box_x = (width - box_width) / 2;
79 draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
80
81 print_buttons(dialog, height, width, 0);
82
83 /* Set up the initial value */
84 wmove(dialog, box_y, box_x);
85 wattrset(dialog, inputbox_attr);
86
87 if (!init)
88 instr[0] = '\0';
89 else
90 strcpy(instr, init);
91
92 input_x = strlen(instr);
93
94 if (input_x >= box_width) {
95 scroll = input_x - box_width + 1;
96 input_x = box_width - 1;
97 for (i = 0; i < box_width - 1; i++)
98 waddch(dialog, instr[scroll + i]);
99 } else {
100 waddstr(dialog, instr);
101 }
102
103 wmove(dialog, box_y, box_x + input_x);
104
105 wrefresh(dialog);
106
107 while (key != ESC) {
108 key = wgetch(dialog);
109
110 if (button == -1) { /* Input box selected */
111 switch (key) {
112 case TAB:
113 case KEY_UP:
114 case KEY_DOWN:
115 break;
116 case KEY_LEFT:
117 continue;
118 case KEY_RIGHT:
119 continue;
120 case KEY_BACKSPACE:
121 case 127:
122 if (input_x || scroll) {
123 wattrset(dialog, inputbox_attr);
124 if (!input_x) {
125 scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
126 wmove(dialog, box_y, box_x);
127 for (i = 0; i < box_width; i++)
128 waddch(dialog,
129 instr[scroll + input_x + i] ?
130 instr[scroll + input_x + i] : ' ');
131 input_x = strlen(instr) - scroll;
132 } else
133 input_x--;
134 instr[scroll + input_x] = '\0';
135 mvwaddch(dialog, box_y, input_x + box_x, ' ');
136 wmove(dialog, box_y, input_x + box_x);
137 wrefresh(dialog);
138 }
139 continue;
140 default:
141 if (key < 0x100 && isprint(key)) {
142 if (scroll + input_x < MAX_LEN) {
143 wattrset(dialog, inputbox_attr);
144 instr[scroll + input_x] = key;
145 instr[scroll + input_x + 1] = '\0';
146 if (input_x == box_width - 1) {
147 scroll++;
148 wmove(dialog, box_y, box_x);
149 for (i = 0; i < box_width - 1; i++)
150 waddch(dialog, instr [scroll + i]);
151 } else {
152 wmove(dialog, box_y, input_x++ + box_x);
153 waddch(dialog, key);
154 }
155 wrefresh(dialog);
156 } else
157 flash(); /* Alarm user about overflow */
158 continue;
159 }
160 }
161 }
162 switch (key) {
163 case 'O':
164 case 'o':
165 delwin(dialog);
166 return 0;
167 case 'H':
168 case 'h':
169 delwin(dialog);
170 return 1;
171 case KEY_UP:
172 case KEY_LEFT:
173 switch (button) {
174 case -1:
175 button = 1; /* Indicates "Cancel" button is selected */
176 print_buttons(dialog, height, width, 1);
177 break;
178 case 0:
179 button = -1; /* Indicates input box is selected */
180 print_buttons(dialog, height, width, 0);
181 wmove(dialog, box_y, box_x + input_x);
182 wrefresh(dialog);
183 break;
184 case 1:
185 button = 0; /* Indicates "OK" button is selected */
186 print_buttons(dialog, height, width, 0);
187 break;
188 }
189 break;
190 case TAB:
191 case KEY_DOWN:
192 case KEY_RIGHT:
193 switch (button) {
194 case -1:
195 button = 0; /* Indicates "OK" button is selected */
196 print_buttons(dialog, height, width, 0);
197 break;
198 case 0:
199 button = 1; /* Indicates "Cancel" button is selected */
200 print_buttons(dialog, height, width, 1);
201 break;
202 case 1:
203 button = -1; /* Indicates input box is selected */
204 print_buttons(dialog, height, width, 0);
205 wmove(dialog, box_y, box_x + input_x);
206 wrefresh(dialog);
207 break;
208 }
209 break;
210 case ' ':
211 case '\n':
212 delwin(dialog);
213 return (button == -1 ? 0 : button);
214 case 'X':
215 case 'x':
216 key = ESC;
217 case ESC:
218 break;
219 }
220 }
221
222 delwin(dialog);
223 return -1; /* ESC pressed */
224}
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c
new file mode 100644
index 000000000000..2c34ea1e0a41
--- /dev/null
+++ b/scripts/kconfig/lxdialog/lxdialog.c
@@ -0,0 +1,212 @@
1/*
2 * dialog - Display simple dialog boxes from shell scripts
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
24static void Usage(const char *name);
25
26typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
27
28struct Mode {
29 char *name;
30 int argmin, argmax, argmod;
31 jumperFn *jumper;
32};
33
34jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
35jumperFn j_msgbox, j_infobox;
36
37static struct Mode modes[] = {
38 {"--menu", 9, 0, 3, j_menu},
39 {"--checklist", 9, 0, 3, j_checklist},
40 {"--radiolist", 9, 0, 3, j_radiolist},
41 {"--yesno", 5, 5, 1, j_yesno},
42 {"--textbox", 5, 5, 1, j_textbox},
43 {"--inputbox", 5, 6, 1, j_inputbox},
44 {"--msgbox", 5, 5, 1, j_msgbox},
45 {"--infobox", 5, 5, 1, j_infobox},
46 {NULL, 0, 0, 0, NULL}
47};
48
49static struct Mode *modePtr;
50
51#ifdef LOCALE
52#include <locale.h>
53#endif
54
55int main(int argc, const char *const *argv)
56{
57 int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
58 const char *title = NULL;
59
60#ifdef LOCALE
61 (void)setlocale(LC_ALL, "");
62#endif
63
64#ifdef TRACE
65 trace(TRACE_CALLS | TRACE_UPDATE);
66#endif
67 if (argc < 2) {
68 Usage(argv[0]);
69 exit(-1);
70 }
71
72 while (offset < argc - 1 && !end_common_opts) { /* Common options */
73 if (!strcmp(argv[offset + 1], "--title")) {
74 if (argc - offset < 3 || title != NULL) {
75 Usage(argv[0]);
76 exit(-1);
77 } else {
78 title = argv[offset + 2];
79 offset += 2;
80 }
81 } else if (!strcmp(argv[offset + 1], "--backtitle")) {
82 if (backtitle != NULL) {
83 Usage(argv[0]);
84 exit(-1);
85 } else {
86 backtitle = argv[offset + 2];
87 offset += 2;
88 }
89 } else if (!strcmp(argv[offset + 1], "--clear")) {
90 if (opt_clear) { /* Hey, "--clear" can't appear twice! */
91 Usage(argv[0]);
92 exit(-1);
93 } else if (argc == 2) { /* we only want to clear the screen */
94 init_dialog();
95 refresh(); /* init_dialog() will clear the screen for us */
96 end_dialog();
97 return 0;
98 } else {
99 opt_clear = 1;
100 offset++;
101 }
102 } else /* no more common options */
103 end_common_opts = 1;
104 }
105
106 if (argc - 1 == offset) { /* no more options */
107 Usage(argv[0]);
108 exit(-1);
109 }
110 /* use a table to look for the requested mode, to avoid code duplication */
111
112 for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
113 if (!strcmp(argv[offset + 1], modePtr->name))
114 break;
115
116 if (!modePtr->name)
117 Usage(argv[0]);
118 if (argc - offset < modePtr->argmin)
119 Usage(argv[0]);
120 if (modePtr->argmax && argc - offset > modePtr->argmax)
121 Usage(argv[0]);
122
123 init_dialog();
124 retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
125
126 if (opt_clear) { /* clear screen before exit */
127 attr_clear(stdscr, LINES, COLS, screen_attr);
128 refresh();
129 }
130 end_dialog();
131
132 exit(retval);
133}
134
135/*
136 * Print program usage
137 */
138static void Usage(const char *name)
139{
140 fprintf(stderr, "\
141\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
142\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
143\n modified/gutted for use as a Linux kernel config tool by \
144\n William Roadcap (roadcapw@cfw.com)\
145\n\
146\n* Display dialog boxes from shell scripts *\
147\n\
148\nUsage: %s --clear\
149\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
150\n\
151\nBox options:\
152\n\
153\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
154\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
155\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
156\n --textbox <file> <height> <width>\
157\n --inputbox <text> <height> <width> [<init>]\
158\n --yesno <text> <height> <width>\
159\n", name, name);
160 exit(-1);
161}
162
163/*
164 * These are the program jumpers
165 */
166
167int j_menu(const char *t, int ac, const char *const *av)
168{
169 return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
170 atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
171}
172
173int j_checklist(const char *t, int ac, const char *const *av)
174{
175 return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
176 atoi(av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
177}
178
179int j_radiolist(const char *t, int ac, const char *const *av)
180{
181 return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
182 atoi(av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
183}
184
185int j_textbox(const char *t, int ac, const char *const *av)
186{
187 return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
188}
189
190int j_yesno(const char *t, int ac, const char *const *av)
191{
192 return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
193}
194
195int j_inputbox(const char *t, int ac, const char *const *av)
196{
197 int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
198 ac == 6 ? av[5] : (char *)NULL);
199 if (ret == 0)
200 fprintf(stderr, dialog_input_result);
201 return ret;
202}
203
204int j_msgbox(const char *t, int ac, const char *const *av)
205{
206 return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
207}
208
209int j_infobox(const char *t, int ac, const char *const *av)
210{
211 return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
212}
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
new file mode 100644
index 000000000000..09512b544375
--- /dev/null
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -0,0 +1,425 @@
1/*
2 * menubox.c -- implements the menu box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@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/*
23 * Changes by Clifford Wolf (god@clifford.at)
24 *
25 * [ 1998-06-13 ]
26 *
27 * *) A bugfix for the Page-Down problem
28 *
29 * *) Formerly when I used Page Down and Page Up, the cursor would be set
30 * to the first position in the menu box. Now lxdialog is a bit
31 * smarter and works more like other menu systems (just have a look at
32 * it).
33 *
34 * *) Formerly if I selected something my scrolling would be broken because
35 * lxdialog is re-invoked by the Menuconfig shell script, can't
36 * remember the last scrolling position, and just sets it so that the
37 * cursor is at the bottom of the box. Now it writes the temporary file
38 * lxdialog.scrltmp which contains this information. The file is
39 * deleted by lxdialog if the user leaves a submenu or enters a new
40 * one, but it would be nice if Menuconfig could make another "rm -f"
41 * just to be sure. Just try it out - you will recognise a difference!
42 *
43 * [ 1998-06-14 ]
44 *
45 * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
46 * and menus change their size on the fly.
47 *
48 * *) If for some reason the last scrolling position is not saved by
49 * lxdialog, it sets the scrolling so that the selected item is in the
50 * middle of the menu box, not at the bottom.
51 *
52 * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
53 * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
54 * This fixes a bug in Menuconfig where using ' ' to descend into menus
55 * would leave mis-synchronized lxdialog.scrltmp files lying around,
56 * fscanf would read in 'scroll', and eventually that value would get used.
57 */
58
59#include "dialog.h"
60
61#define ITEM_IDENT 1 /* Indent of menu entries. Fixed for all menus */
62static int menu_width;
63
64/*
65 * Print menu item
66 */
67static void do_print_item(WINDOW * win, const char *item, int choice,
68 int selected, int hotkey)
69{
70 int j;
71 char *menu_item = malloc(menu_width + 1);
72
73 strncpy(menu_item, item, menu_width - ITEM_IDENT);
74 menu_item[menu_width] = 0;
75 j = first_alpha(menu_item, "YyNnMmHh");
76
77 /* Clear 'residue' of last item */
78 wattrset(win, menubox_attr);
79 wmove(win, choice, 0);
80#if OLD_NCURSES
81 {
82 int i;
83 for (i = 0; i < menu_width; i++)
84 waddch(win, ' ');
85 }
86#else
87 wclrtoeol(win);
88#endif
89 wattrset(win, selected ? item_selected_attr : item_attr);
90 mvwaddstr(win, choice, ITEM_IDENT, menu_item);
91 if (hotkey) {
92 wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
93 mvwaddch(win, choice, ITEM_IDENT + j, menu_item[j]);
94 }
95 if (selected) {
96 wmove(win, choice, ITEM_IDENT + 1);
97 }
98 free(menu_item);
99 wrefresh(win);
100}
101
102#define print_item(index, choice, selected) \
103do {\
104 int hotkey = (items[(index) * 2][0] != ':'); \
105 do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
106} while (0)
107
108/*
109 * Print the scroll indicators.
110 */
111static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
112 int height)
113{
114 int cur_y, cur_x;
115
116 getyx(win, cur_y, cur_x);
117
118 wmove(win, y, x);
119
120 if (scroll > 0) {
121 wattrset(win, uarrow_attr);
122 waddch(win, ACS_UARROW);
123 waddstr(win, "(-)");
124 } else {
125 wattrset(win, menubox_attr);
126 waddch(win, ACS_HLINE);
127 waddch(win, ACS_HLINE);
128 waddch(win, ACS_HLINE);
129 waddch(win, ACS_HLINE);
130 }
131
132 y = y + height + 1;
133 wmove(win, y, x);
134 wrefresh(win);
135
136 if ((height < item_no) && (scroll + height < item_no)) {
137 wattrset(win, darrow_attr);
138 waddch(win, ACS_DARROW);
139 waddstr(win, "(+)");
140 } else {
141 wattrset(win, menubox_border_attr);
142 waddch(win, ACS_HLINE);
143 waddch(win, ACS_HLINE);
144 waddch(win, ACS_HLINE);
145 waddch(win, ACS_HLINE);
146 }
147
148 wmove(win, cur_y, cur_x);
149 wrefresh(win);
150}
151
152/*
153 * Display the termination buttons.
154 */
155static void print_buttons(WINDOW * win, int height, int width, int selected)
156{
157 int x = width / 2 - 16;
158 int y = height - 2;
159
160 print_button(win, "Select", y, x, selected == 0);
161 print_button(win, " Exit ", y, x + 12, selected == 1);
162 print_button(win, " Help ", y, x + 24, selected == 2);
163
164 wmove(win, y, x + 1 + 12 * selected);
165 wrefresh(win);
166}
167
168/* scroll up n lines (n may be negative) */
169static void do_scroll(WINDOW *win, int *scroll, int n)
170{
171 /* Scroll menu up */
172 scrollok(win, TRUE);
173 wscrl(win, n);
174 scrollok(win, FALSE);
175 *scroll = *scroll + n;
176 wrefresh(win);
177}
178
179/*
180 * Display a menu for choosing among a number of options
181 */
182int dialog_menu(const char *title, const char *prompt, int height, int width,
183 int menu_height, const char *current, int item_no,
184 const char *const *items)
185{
186 int i, j, x, y, box_x, box_y;
187 int key = 0, button = 0, scroll = 0, choice = 0;
188 int first_item = 0, max_choice;
189 WINDOW *dialog, *menu;
190 FILE *f;
191
192 max_choice = MIN(menu_height, item_no);
193
194 /* center dialog box on screen */
195 x = (COLS - width) / 2;
196 y = (LINES - height) / 2;
197
198 draw_shadow(stdscr, y, x, height, width);
199
200 dialog = newwin(height, width, y, x);
201 keypad(dialog, TRUE);
202
203 draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
204 wattrset(dialog, border_attr);
205 mvwaddch(dialog, height - 3, 0, ACS_LTEE);
206 for (i = 0; i < width - 2; i++)
207 waddch(dialog, ACS_HLINE);
208 wattrset(dialog, dialog_attr);
209 wbkgdset(dialog, dialog_attr & A_COLOR);
210 waddch(dialog, ACS_RTEE);
211
212 print_title(dialog, title, width);
213
214 wattrset(dialog, dialog_attr);
215 print_autowrap(dialog, prompt, width - 2, 1, 3);
216
217 menu_width = width - 6;
218 box_y = height - menu_height - 5;
219 box_x = (width - menu_width) / 2 - 1;
220
221 /* create new window for the menu */
222 menu = subwin(dialog, menu_height, menu_width,
223 y + box_y + 1, x + box_x + 1);
224 keypad(menu, TRUE);
225
226 /* draw a box around the menu items */
227 draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
228 menubox_border_attr, menubox_attr);
229
230 /* Set choice to default item */
231 for (i = 0; i < item_no; i++)
232 if (strcmp(current, items[i * 2]) == 0)
233 choice = i;
234
235 /* get the scroll info from the temp file */
236 if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) {
237 if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) &&
238 (scroll + max_choice > choice) && (scroll >= 0) &&
239 (scroll + max_choice <= item_no)) {
240 first_item = scroll;
241 choice = choice - scroll;
242 fclose(f);
243 } else {
244 scroll = 0;
245 remove("lxdialog.scrltmp");
246 fclose(f);
247 f = NULL;
248 }
249 }
250 if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
251 if (choice >= item_no - max_choice / 2)
252 scroll = first_item = item_no - max_choice;
253 else
254 scroll = first_item = choice - max_choice / 2;
255 choice = choice - scroll;
256 }
257
258 /* Print the menu */
259 for (i = 0; i < max_choice; i++) {
260 print_item(first_item + i, i, i == choice);
261 }
262
263 wnoutrefresh(menu);
264
265 print_arrows(dialog, item_no, scroll,
266 box_y, box_x + ITEM_IDENT + 1, menu_height);
267
268 print_buttons(dialog, height, width, 0);
269 wmove(menu, choice, ITEM_IDENT + 1);
270 wrefresh(menu);
271
272 while (key != ESC) {
273 key = wgetch(menu);
274
275 if (key < 256 && isalpha(key))
276 key = tolower(key);
277
278 if (strchr("ynmh", key))
279 i = max_choice;
280 else {
281 for (i = choice + 1; i < max_choice; i++) {
282 j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
283 if (key == tolower(items[(scroll + i) * 2 + 1][j]))
284 break;
285 }
286 if (i == max_choice)
287 for (i = 0; i < max_choice; i++) {
288 j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
289 if (key == tolower(items[(scroll + i) * 2 + 1][j]))
290 break;
291 }
292 }
293
294 if (i < max_choice ||
295 key == KEY_UP || key == KEY_DOWN ||
296 key == '-' || key == '+' ||
297 key == KEY_PPAGE || key == KEY_NPAGE) {
298 /* Remove highligt of current item */
299 print_item(scroll + choice, choice, FALSE);
300
301 if (key == KEY_UP || key == '-') {
302 if (choice < 2 && scroll) {
303 /* Scroll menu down */
304 do_scroll(menu, &scroll, -1);
305
306 print_item(scroll, 0, FALSE);
307 } else
308 choice = MAX(choice - 1, 0);
309
310 } else if (key == KEY_DOWN || key == '+') {
311 print_item(scroll+choice, choice, FALSE);
312
313 if ((choice > max_choice - 3) &&
314 (scroll + max_choice < item_no)) {
315 /* Scroll menu up */
316 do_scroll(menu, &scroll, 1);
317
318 print_item(scroll+max_choice - 1,
319 max_choice - 1, FALSE);
320 } else
321 choice = MIN(choice + 1, max_choice - 1);
322
323 } else if (key == KEY_PPAGE) {
324 scrollok(menu, TRUE);
325 for (i = 0; (i < max_choice); i++) {
326 if (scroll > 0) {
327 do_scroll(menu, &scroll, -1);
328 print_item(scroll, 0, FALSE);
329 } else {
330 if (choice > 0)
331 choice--;
332 }
333 }
334
335 } else if (key == KEY_NPAGE) {
336 for (i = 0; (i < max_choice); i++) {
337 if (scroll + max_choice < item_no) {
338 do_scroll(menu, &scroll, 1);
339 print_item(scroll+max_choice-1,
340 max_choice - 1, FALSE);
341 } else {
342 if (choice + 1 < max_choice)
343 choice++;
344 }
345 }
346 } else
347 choice = i;
348
349 print_item(scroll + choice, choice, TRUE);
350
351 print_arrows(dialog, item_no, scroll,
352 box_y, box_x + ITEM_IDENT + 1, menu_height);
353
354 wnoutrefresh(dialog);
355 wrefresh(menu);
356
357 continue; /* wait for another key press */
358 }
359
360 switch (key) {
361 case KEY_LEFT:
362 case TAB:
363 case KEY_RIGHT:
364 button = ((key == KEY_LEFT ? --button : ++button) < 0)
365 ? 2 : (button > 2 ? 0 : button);
366
367 print_buttons(dialog, height, width, button);
368 wrefresh(menu);
369 break;
370 case ' ':
371 case 's':
372 case 'y':
373 case 'n':
374 case 'm':
375 case '/':
376 /* save scroll info */
377 if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
378 fprintf(f, "%d\n", scroll);
379 fclose(f);
380 }
381 delwin(dialog);
382 fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
383 switch (key) {
384 case 's':
385 return 3;
386 case 'y':
387 return 3;
388 case 'n':
389 return 4;
390 case 'm':
391 return 5;
392 case ' ':
393 return 6;
394 case '/':
395 return 7;
396 }
397 return 0;
398 case 'h':
399 case '?':
400 button = 2;
401 case '\n':
402 delwin(dialog);
403 if (button == 2)
404 fprintf(stderr, "%s \"%s\"\n",
405 items[(scroll + choice) * 2],
406 items[(scroll + choice) * 2 + 1] +
407 first_alpha(items [(scroll + choice) * 2 + 1], ""));
408 else
409 fprintf(stderr, "%s\n",
410 items[(scroll + choice) * 2]);
411
412 remove("lxdialog.scrltmp");
413 return button;
414 case 'e':
415 case 'x':
416 key = ESC;
417 case ESC:
418 break;
419 }
420 }
421
422 delwin(dialog);
423 remove("lxdialog.scrltmp");
424 return -1; /* ESC pressed */
425}
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
new file mode 100644
index 000000000000..7323f5471f69
--- /dev/null
+++ b/scripts/kconfig/lxdialog/msgbox.c
@@ -0,0 +1,71 @@
1/*
2 * msgbox.c -- implements the message box and info box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@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/*
25 * Display a message box. Program will pause and display an "OK" button
26 * if the parameter 'pause' is non-zero.
27 */
28int dialog_msgbox(const char *title, const char *prompt, int height, int width,
29 int pause)
30{
31 int i, x, y, key = 0;
32 WINDOW *dialog;
33
34 /* center dialog box on screen */
35 x = (COLS - width) / 2;
36 y = (LINES - height) / 2;
37
38 draw_shadow(stdscr, y, x, height, width);
39
40 dialog = newwin(height, width, y, x);
41 keypad(dialog, TRUE);
42
43 draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
44
45 print_title(dialog, title, width);
46
47 wattrset(dialog, dialog_attr);
48 print_autowrap(dialog, prompt, width - 2, 1, 2);
49
50 if (pause) {
51 wattrset(dialog, border_attr);
52 mvwaddch(dialog, height - 3, 0, ACS_LTEE);
53 for (i = 0; i < width - 2; i++)
54 waddch(dialog, ACS_HLINE);
55 wattrset(dialog, dialog_attr);
56 waddch(dialog, ACS_RTEE);
57
58 print_button(dialog, " Ok ", height - 2, width / 2 - 4, TRUE);
59
60 wrefresh(dialog);
61 while (key != ESC && key != '\n' && key != ' ' &&
62 key != 'O' && key != 'o' && key != 'X' && key != 'x')
63 key = wgetch(dialog);
64 } else {
65 key = '\n';
66 wrefresh(dialog);
67 }
68
69 delwin(dialog);
70 return key == ESC ? -1 : 0;
71}
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
new file mode 100644
index 000000000000..77848bb8e07f
--- /dev/null
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -0,0 +1,533 @@
1/*
2 * textbox.c -- implements the text 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
24static void back_lines(int n);
25static void print_page(WINDOW * win, int height, int width);
26static void print_line(WINDOW * win, int row, int width);
27static char *get_line(void);
28static void print_position(WINDOW * win, int height, int width);
29
30static int hscroll, fd, file_size, bytes_read;
31static int begin_reached = 1, end_reached, page_length;
32static char *buf, *page;
33
34/*
35 * Display text from a file in a dialog box.
36 */
37int dialog_textbox(const char *title, const char *file, int height, int width)
38{
39 int i, x, y, cur_x, cur_y, fpos, key = 0;
40 int passed_end;
41 char search_term[MAX_LEN + 1];
42 WINDOW *dialog, *text;
43
44 search_term[0] = '\0'; /* no search term entered yet */
45
46 /* Open input file for reading */
47 if ((fd = open(file, O_RDONLY)) == -1) {
48 endwin();
49 fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
50 exit(-1);
51 }
52 /* Get file size. Actually, 'file_size' is the real file size - 1,
53 since it's only the last byte offset from the beginning */
54 if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
55 endwin();
56 fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
57 exit(-1);
58 }
59 /* Restore file pointer to beginning of file after getting file size */
60 if (lseek(fd, 0, SEEK_SET) == -1) {
61 endwin();
62 fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
63 exit(-1);
64 }
65 /* Allocate space for read buffer */
66 if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
67 endwin();
68 fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
69 exit(-1);
70 }
71 if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
72 endwin();
73 fprintf(stderr, "\nError reading file in dialog_textbox().\n");
74 exit(-1);
75 }
76 buf[bytes_read] = '\0'; /* mark end of valid data */
77 page = buf; /* page is pointer to start of page to be displayed */
78
79 /* center dialog box on screen */
80 x = (COLS - width) / 2;
81 y = (LINES - height) / 2;
82
83 draw_shadow(stdscr, y, x, height, width);
84
85 dialog = newwin(height, width, y, x);
86 keypad(dialog, TRUE);
87
88 /* Create window for text region, used for scrolling text */
89 text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
90 wattrset(text, dialog_attr);
91 wbkgdset(text, dialog_attr & A_COLOR);
92
93 keypad(text, TRUE);
94
95 /* register the new window, along with its borders */
96 draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
97
98 wattrset(dialog, border_attr);
99 mvwaddch(dialog, height - 3, 0, ACS_LTEE);
100 for (i = 0; i < width - 2; i++)
101 waddch(dialog, ACS_HLINE);
102 wattrset(dialog, dialog_attr);
103 wbkgdset(dialog, dialog_attr & A_COLOR);
104 waddch(dialog, ACS_RTEE);
105
106 print_title(dialog, title, width);
107
108 print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
109 wnoutrefresh(dialog);
110 getyx(dialog, cur_y, cur_x); /* Save cursor position */
111
112 /* Print first page of text */
113 attr_clear(text, height - 4, width - 2, dialog_attr);
114 print_page(text, height - 4, width - 2);
115 print_position(dialog, height, width);
116 wmove(dialog, cur_y, cur_x); /* Restore cursor position */
117 wrefresh(dialog);
118
119 while ((key != ESC) && (key != '\n')) {
120 key = wgetch(dialog);
121 switch (key) {
122 case 'E': /* Exit */
123 case 'e':
124 case 'X':
125 case 'x':
126 delwin(dialog);
127 free(buf);
128 close(fd);
129 return 0;
130 case 'g': /* First page */
131 case KEY_HOME:
132 if (!begin_reached) {
133 begin_reached = 1;
134 /* First page not in buffer? */
135 if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
136 endwin();
137 fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
138 exit(-1);
139 }
140 if (fpos > bytes_read) { /* Yes, we have to read it in */
141 if (lseek(fd, 0, SEEK_SET) == -1) {
142 endwin();
143 fprintf(stderr, "\nError moving file pointer in "
144 "dialog_textbox().\n");
145 exit(-1);
146 }
147 if ((bytes_read =
148 read(fd, buf, BUF_SIZE)) == -1) {
149 endwin();
150 fprintf(stderr, "\nError reading file in dialog_textbox().\n");
151 exit(-1);
152 }
153 buf[bytes_read] = '\0';
154 }
155 page = buf;
156 print_page(text, height - 4, width - 2);
157 print_position(dialog, height, width);
158 wmove(dialog, cur_y, cur_x); /* Restore cursor position */
159 wrefresh(dialog);
160 }
161 break;
162 case 'G': /* Last page */
163 case KEY_END:
164
165 end_reached = 1;
166 /* Last page not in buffer? */
167 if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
168 endwin();
169 fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
170 exit(-1);
171 }
172 if (fpos < file_size) { /* Yes, we have to read it in */
173 if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
174 endwin();
175 fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
176 exit(-1);
177 }
178 if ((bytes_read =
179 read(fd, buf, BUF_SIZE)) == -1) {
180 endwin();
181 fprintf(stderr, "\nError reading file in dialog_textbox().\n");
182 exit(-1);
183 }
184 buf[bytes_read] = '\0';
185 }
186 page = buf + bytes_read;
187 back_lines(height - 4);
188 print_page(text, height - 4, width - 2);
189 print_position(dialog, height, width);
190 wmove(dialog, cur_y, cur_x); /* Restore cursor position */
191 wrefresh(dialog);
192 break;
193 case 'K': /* Previous line */
194 case 'k':
195 case KEY_UP:
196 if (!begin_reached) {
197 back_lines(page_length + 1);
198
199 /* We don't call print_page() here but use scrolling to ensure
200 faster screen update. However, 'end_reached' and
201 'page_length' should still be updated, and 'page' should
202 point to start of next page. This is done by calling
203 get_line() in the following 'for' loop. */
204 scrollok(text, TRUE);
205 wscrl(text, -1); /* Scroll text region down one line */
206 scrollok(text, FALSE);
207 page_length = 0;
208 passed_end = 0;
209 for (i = 0; i < height - 4; i++) {
210 if (!i) {
211 /* print first line of page */
212 print_line(text, 0, width - 2);
213 wnoutrefresh(text);
214 } else
215 /* Called to update 'end_reached' and 'page' */
216 get_line();
217 if (!passed_end)
218 page_length++;
219 if (end_reached && !passed_end)
220 passed_end = 1;
221 }
222
223 print_position(dialog, height, width);
224 wmove(dialog, cur_y, cur_x); /* Restore cursor position */
225 wrefresh(dialog);
226 }
227 break;
228 case 'B': /* Previous page */
229 case 'b':
230 case KEY_PPAGE:
231 if (begin_reached)
232 break;
233 back_lines(page_length + height - 4);
234 print_page(text, height - 4, width - 2);
235 print_position(dialog, height, width);
236 wmove(dialog, cur_y, cur_x);
237 wrefresh(dialog);
238 break;
239 case 'J': /* Next line */
240 case 'j':
241 case KEY_DOWN:
242 if (!end_reached) {
243 begin_reached = 0;
244 scrollok(text, TRUE);
245 scroll(text); /* Scroll text region up one line */
246 scrollok(text, FALSE);
247 print_line(text, height - 5, width - 2);
248 wnoutrefresh(text);
249 print_position(dialog, height, width);
250 wmove(dialog, cur_y, cur_x); /* Restore cursor position */
251 wrefresh(dialog);
252 }
253 break;
254 case KEY_NPAGE: /* Next page */
255 case ' ':
256 if (end_reached)
257 break;
258
259 begin_reached = 0;
260 print_page(text, height - 4, width - 2);
261 print_position(dialog, height, width);
262 wmove(dialog, cur_y, cur_x);
263 wrefresh(dialog);
264 break;
265 case '0': /* Beginning of line */
266 case 'H': /* Scroll left */
267 case 'h':
268 case KEY_LEFT:
269 if (hscroll <= 0)
270 break;
271
272 if (key == '0')
273 hscroll = 0;
274 else
275 hscroll--;
276 /* Reprint current page to scroll horizontally */
277 back_lines(page_length);
278 print_page(text, height - 4, width - 2);
279 wmove(dialog, cur_y, cur_x);
280 wrefresh(dialog);
281 break;
282 case 'L': /* Scroll right */
283 case 'l':
284 case KEY_RIGHT:
285 if (hscroll >= MAX_LEN)
286 break;
287 hscroll++;
288 /* Reprint current page to scroll horizontally */
289 back_lines(page_length);
290 print_page(text, height - 4, width - 2);
291 wmove(dialog, cur_y, cur_x);
292 wrefresh(dialog);
293 break;
294 case ESC:
295 break;
296 }
297 }
298
299 delwin(dialog);
300 free(buf);
301 close(fd);
302 return -1; /* ESC pressed */
303}
304
305/*
306 * Go back 'n' lines in text file. Called by dialog_textbox().
307 * 'page' will be updated to point to the desired line in 'buf'.
308 */
309static void back_lines(int n)
310{
311 int i, fpos;
312
313 begin_reached = 0;
314 /* We have to distinguish between end_reached and !end_reached
315 since at end of file, the line is not ended by a '\n'.
316 The code inside 'if' basically does a '--page' to move one
317 character backward so as to skip '\n' of the previous line */
318 if (!end_reached) {
319 /* Either beginning of buffer or beginning of file reached? */
320 if (page == buf) {
321 if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
322 endwin();
323 fprintf(stderr, "\nError moving file pointer in "
324 "back_lines().\n");
325 exit(-1);
326 }
327 if (fpos > bytes_read) { /* Not beginning of file yet */
328 /* We've reached beginning of buffer, but not beginning of
329 file yet, so read previous part of file into buffer.
330 Note that we only move backward for BUF_SIZE/2 bytes,
331 but not BUF_SIZE bytes to avoid re-reading again in
332 print_page() later */
333 /* Really possible to move backward BUF_SIZE/2 bytes? */
334 if (fpos < BUF_SIZE / 2 + bytes_read) {
335 /* No, move less then */
336 if (lseek(fd, 0, SEEK_SET) == -1) {
337 endwin();
338 fprintf(stderr, "\nError moving file pointer in "
339 "back_lines().\n");
340 exit(-1);
341 }
342 page = buf + fpos - bytes_read;
343 } else { /* Move backward BUF_SIZE/2 bytes */
344 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
345 endwin();
346 fprintf(stderr, "\nError moving file pointer "
347 "in back_lines().\n");
348 exit(-1);
349 }
350 page = buf + BUF_SIZE / 2;
351 }
352 if ((bytes_read =
353 read(fd, buf, BUF_SIZE)) == -1) {
354 endwin();
355 fprintf(stderr, "\nError reading file in back_lines().\n");
356 exit(-1);
357 }
358 buf[bytes_read] = '\0';
359 } else { /* Beginning of file reached */
360 begin_reached = 1;
361 return;
362 }
363 }
364 if (*(--page) != '\n') { /* '--page' here */
365 /* Something's wrong... */
366 endwin();
367 fprintf(stderr, "\nInternal error in back_lines().\n");
368 exit(-1);
369 }
370 }
371 /* Go back 'n' lines */
372 for (i = 0; i < n; i++)
373 do {
374 if (page == buf) {
375 if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
376 endwin();
377 fprintf(stderr, "\nError moving file pointer in back_lines().\n");
378 exit(-1);
379 }
380 if (fpos > bytes_read) {
381 /* Really possible to move backward BUF_SIZE/2 bytes? */
382 if (fpos < BUF_SIZE / 2 + bytes_read) {
383 /* No, move less then */
384 if (lseek(fd, 0, SEEK_SET) == -1) {
385 endwin();
386 fprintf(stderr, "\nError moving file pointer "
387 "in back_lines().\n");
388 exit(-1);
389 }
390 page = buf + fpos - bytes_read;
391 } else { /* Move backward BUF_SIZE/2 bytes */
392 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
393 endwin();
394 fprintf(stderr, "\nError moving file pointer"
395 " in back_lines().\n");
396 exit(-1);
397 }
398 page = buf + BUF_SIZE / 2;
399 }
400 if ((bytes_read =
401 read(fd, buf, BUF_SIZE)) == -1) {
402 endwin();
403 fprintf(stderr, "\nError reading file in "
404 "back_lines().\n");
405 exit(-1);
406 }
407 buf[bytes_read] = '\0';
408 } else { /* Beginning of file reached */
409 begin_reached = 1;
410 return;
411 }
412 }
413 } while (*(--page) != '\n');
414 page++;
415}
416
417/*
418 * Print a new page of text. Called by dialog_textbox().
419 */
420static void print_page(WINDOW * win, int height, int width)
421{
422 int i, passed_end = 0;
423
424 page_length = 0;
425 for (i = 0; i < height; i++) {
426 print_line(win, i, width);
427 if (!passed_end)
428 page_length++;
429 if (end_reached && !passed_end)
430 passed_end = 1;
431 }
432 wnoutrefresh(win);
433}
434
435/*
436 * Print a new line of text. Called by dialog_textbox() and print_page().
437 */
438static void print_line(WINDOW * win, int row, int width)
439{
440 int y, x;
441 char *line;
442
443 line = get_line();
444 line += MIN(strlen(line), hscroll); /* Scroll horizontally */
445 wmove(win, row, 0); /* move cursor to correct line */
446 waddch(win, ' ');
447 waddnstr(win, line, MIN(strlen(line), width - 2));
448
449 getyx(win, y, x);
450 /* Clear 'residue' of previous line */
451#if OLD_NCURSES
452 {
453 int i;
454 for (i = 0; i < width - x; i++)
455 waddch(win, ' ');
456 }
457#else
458 wclrtoeol(win);
459#endif
460}
461
462/*
463 * Return current line of text. Called by dialog_textbox() and print_line().
464 * 'page' should point to start of current line before calling, and will be
465 * updated to point to start of next line.
466 */
467static char *get_line(void)
468{
469 int i = 0, fpos;
470 static char line[MAX_LEN + 1];
471
472 end_reached = 0;
473 while (*page != '\n') {
474 if (*page == '\0') {
475 /* Either end of file or end of buffer reached */
476 if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
477 endwin();
478 fprintf(stderr, "\nError moving file pointer in "
479 "get_line().\n");
480 exit(-1);
481 }
482 if (fpos < file_size) { /* Not end of file yet */
483 /* We've reached end of buffer, but not end of file yet,
484 so read next part of file into buffer */
485 if ((bytes_read =
486 read(fd, buf, BUF_SIZE)) == -1) {
487 endwin();
488 fprintf(stderr, "\nError reading file in get_line().\n");
489 exit(-1);
490 }
491 buf[bytes_read] = '\0';
492 page = buf;
493 } else {
494 if (!end_reached)
495 end_reached = 1;
496 break;
497 }
498 } else if (i < MAX_LEN)
499 line[i++] = *(page++);
500 else {
501 /* Truncate lines longer than MAX_LEN characters */
502 if (i == MAX_LEN)
503 line[i++] = '\0';
504 page++;
505 }
506 }
507 if (i <= MAX_LEN)
508 line[i] = '\0';
509 if (!end_reached)
510 page++; /* move pass '\n' */
511
512 return line;
513}
514
515/*
516 * Print current position
517 */
518static void print_position(WINDOW * win, int height, int width)
519{
520 int fpos, percent;
521
522 if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
523 endwin();
524 fprintf(stderr, "\nError moving file pointer in print_position().\n");
525 exit(-1);
526 }
527 wattrset(win, position_indicator_attr);
528 wbkgdset(win, position_indicator_attr & A_COLOR);
529 percent = !file_size ?
530 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
531 wmove(win, height - 3, width - 9);
532 wprintw(win, "(%3d%%)", percent);
533}
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
new file mode 100644
index 000000000000..f82cebb9ff06
--- /dev/null
+++ b/scripts/kconfig/lxdialog/util.c
@@ -0,0 +1,362 @@
1/*
2 * util.c
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/* use colors by default? */
25bool use_colors = 1;
26
27const char *backtitle = NULL;
28
29/*
30 * Attribute values, default is for mono display
31 */
32chtype attributes[] = {
33 A_NORMAL, /* screen_attr */
34 A_NORMAL, /* shadow_attr */
35 A_NORMAL, /* dialog_attr */
36 A_BOLD, /* title_attr */
37 A_NORMAL, /* border_attr */
38 A_REVERSE, /* button_active_attr */
39 A_DIM, /* button_inactive_attr */
40 A_REVERSE, /* button_key_active_attr */
41 A_BOLD, /* button_key_inactive_attr */
42 A_REVERSE, /* button_label_active_attr */
43 A_NORMAL, /* button_label_inactive_attr */
44 A_NORMAL, /* inputbox_attr */
45 A_NORMAL, /* inputbox_border_attr */
46 A_NORMAL, /* searchbox_attr */
47 A_BOLD, /* searchbox_title_attr */
48 A_NORMAL, /* searchbox_border_attr */
49 A_BOLD, /* position_indicator_attr */
50 A_NORMAL, /* menubox_attr */
51 A_NORMAL, /* menubox_border_attr */
52 A_NORMAL, /* item_attr */
53 A_REVERSE, /* item_selected_attr */
54 A_BOLD, /* tag_attr */
55 A_REVERSE, /* tag_selected_attr */
56 A_BOLD, /* tag_key_attr */
57 A_REVERSE, /* tag_key_selected_attr */
58 A_BOLD, /* check_attr */
59 A_REVERSE, /* check_selected_attr */
60 A_BOLD, /* uarrow_attr */
61 A_BOLD /* darrow_attr */
62};
63
64#include "colors.h"
65
66/*
67 * Table of color values
68 */
69int color_table[][3] = {
70 {SCREEN_FG, SCREEN_BG, SCREEN_HL},
71 {SHADOW_FG, SHADOW_BG, SHADOW_HL},
72 {DIALOG_FG, DIALOG_BG, DIALOG_HL},
73 {TITLE_FG, TITLE_BG, TITLE_HL},
74 {BORDER_FG, BORDER_BG, BORDER_HL},
75 {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
76 {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
77 {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
78 {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG,
79 BUTTON_KEY_INACTIVE_HL},
80 {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG,
81 BUTTON_LABEL_ACTIVE_HL},
82 {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
83 BUTTON_LABEL_INACTIVE_HL},
84 {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
85 {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
86 {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
87 {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
88 {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
89 {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
90 {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
91 {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
92 {ITEM_FG, ITEM_BG, ITEM_HL},
93 {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
94 {TAG_FG, TAG_BG, TAG_HL},
95 {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
96 {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
97 {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
98 {CHECK_FG, CHECK_BG, CHECK_HL},
99 {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
100 {UARROW_FG, UARROW_BG, UARROW_HL},
101 {DARROW_FG, DARROW_BG, DARROW_HL},
102}; /* color_table */
103
104/*
105 * Set window to attribute 'attr'
106 */
107void attr_clear(WINDOW * win, int height, int width, chtype attr)
108{
109 int i, j;
110
111 wattrset(win, attr);
112 for (i = 0; i < height; i++) {
113 wmove(win, i, 0);
114 for (j = 0; j < width; j++)
115 waddch(win, ' ');
116 }
117 touchwin(win);
118}
119
120void dialog_clear(void)
121{
122 attr_clear(stdscr, LINES, COLS, screen_attr);
123 /* Display background title if it exists ... - SLH */
124 if (backtitle != NULL) {
125 int i;
126
127 wattrset(stdscr, screen_attr);
128 mvwaddstr(stdscr, 0, 1, (char *)backtitle);
129 wmove(stdscr, 1, 1);
130 for (i = 1; i < COLS - 1; i++)
131 waddch(stdscr, ACS_HLINE);
132 }
133 wnoutrefresh(stdscr);
134}
135
136/*
137 * Do some initialization for dialog
138 */
139void init_dialog(void)
140{
141 initscr(); /* Init curses */
142 keypad(stdscr, TRUE);
143 cbreak();
144 noecho();
145
146 if (use_colors) /* Set up colors */
147 color_setup();
148
149 dialog_clear();
150}
151
152/*
153 * Setup for color display
154 */
155void color_setup(void)
156{
157 int i;
158
159 if (has_colors()) { /* Terminal supports color? */
160 start_color();
161
162 /* Initialize color pairs */
163 for (i = 0; i < ATTRIBUTE_COUNT; i++)
164 init_pair(i + 1, color_table[i][0], color_table[i][1]);
165
166 /* Setup color attributes */
167 for (i = 0; i < ATTRIBUTE_COUNT; i++)
168 attributes[i] = C_ATTR(color_table[i][2], i + 1);
169 }
170}
171
172/*
173 * End using dialog functions.
174 */
175void end_dialog(void)
176{
177 endwin();
178}
179
180/* Print the title of the dialog. Center the title and truncate
181 * tile if wider than dialog (- 2 chars).
182 **/
183void print_title(WINDOW *dialog, const char *title, int width)
184{
185 if (title) {
186 int tlen = MIN(width - 2, strlen(title));
187 wattrset(dialog, title_attr);
188 mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
189 mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
190 waddch(dialog, ' ');
191 }
192}
193
194/*
195 * Print a string of text in a window, automatically wrap around to the
196 * next line if the string is too long to fit on one line. Newline
197 * characters '\n' are replaced by spaces. We start on a new line
198 * if there is no room for at least 4 nonblanks following a double-space.
199 */
200void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
201{
202 int newl, cur_x, cur_y;
203 int i, prompt_len, room, wlen;
204 char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
205
206 strcpy(tempstr, prompt);
207
208 prompt_len = strlen(tempstr);
209
210 /*
211 * Remove newlines
212 */
213 for (i = 0; i < prompt_len; i++) {
214 if (tempstr[i] == '\n')
215 tempstr[i] = ' ';
216 }
217
218 if (prompt_len <= width - x * 2) { /* If prompt is short */
219 wmove(win, y, (width - prompt_len) / 2);
220 waddstr(win, tempstr);
221 } else {
222 cur_x = x;
223 cur_y = y;
224 newl = 1;
225 word = tempstr;
226 while (word && *word) {
227 sp = index(word, ' ');
228 if (sp)
229 *sp++ = 0;
230
231 /* Wrap to next line if either the word does not fit,
232 or it is the first word of a new sentence, and it is
233 short, and the next word does not fit. */
234 room = width - cur_x;
235 wlen = strlen(word);
236 if (wlen > room ||
237 (newl && wlen < 4 && sp
238 && wlen + 1 + strlen(sp) > room
239 && (!(sp2 = index(sp, ' '))
240 || wlen + 1 + (sp2 - sp) > room))) {
241 cur_y++;
242 cur_x = x;
243 }
244 wmove(win, cur_y, cur_x);
245 waddstr(win, word);
246 getyx(win, cur_y, cur_x);
247 cur_x++;
248 if (sp && *sp == ' ') {
249 cur_x++; /* double space */
250 while (*++sp == ' ') ;
251 newl = 1;
252 } else
253 newl = 0;
254 word = sp;
255 }
256 }
257}
258
259/*
260 * Print a button
261 */
262void print_button(WINDOW * win, const char *label, int y, int x, int selected)
263{
264 int i, temp;
265
266 wmove(win, y, x);
267 wattrset(win, selected ? button_active_attr : button_inactive_attr);
268 waddstr(win, "<");
269 temp = strspn(label, " ");
270 label += temp;
271 wattrset(win, selected ? button_label_active_attr
272 : button_label_inactive_attr);
273 for (i = 0; i < temp; i++)
274 waddch(win, ' ');
275 wattrset(win, selected ? button_key_active_attr
276 : button_key_inactive_attr);
277 waddch(win, label[0]);
278 wattrset(win, selected ? button_label_active_attr
279 : button_label_inactive_attr);
280 waddstr(win, (char *)label + 1);
281 wattrset(win, selected ? button_active_attr : button_inactive_attr);
282 waddstr(win, ">");
283 wmove(win, y, x + temp + 1);
284}
285
286/*
287 * Draw a rectangular box with line drawing characters
288 */
289void
290draw_box(WINDOW * win, int y, int x, int height, int width,
291 chtype box, chtype border)
292{
293 int i, j;
294
295 wattrset(win, 0);
296 for (i = 0; i < height; i++) {
297 wmove(win, y + i, x);
298 for (j = 0; j < width; j++)
299 if (!i && !j)
300 waddch(win, border | ACS_ULCORNER);
301 else if (i == height - 1 && !j)
302 waddch(win, border | ACS_LLCORNER);
303 else if (!i && j == width - 1)
304 waddch(win, box | ACS_URCORNER);
305 else if (i == height - 1 && j == width - 1)
306 waddch(win, box | ACS_LRCORNER);
307 else if (!i)
308 waddch(win, border | ACS_HLINE);
309 else if (i == height - 1)
310 waddch(win, box | ACS_HLINE);
311 else if (!j)
312 waddch(win, border | ACS_VLINE);
313 else if (j == width - 1)
314 waddch(win, box | ACS_VLINE);
315 else
316 waddch(win, box | ' ');
317 }
318}
319
320/*
321 * Draw shadows along the right and bottom edge to give a more 3D look
322 * to the boxes
323 */
324void draw_shadow(WINDOW * win, int y, int x, int height, int width)
325{
326 int i;
327
328 if (has_colors()) { /* Whether terminal supports color? */
329 wattrset(win, shadow_attr);
330 wmove(win, y + height, x + 2);
331 for (i = 0; i < width; i++)
332 waddch(win, winch(win) & A_CHARTEXT);
333 for (i = y + 1; i < y + height + 1; i++) {
334 wmove(win, i, x + width);
335 waddch(win, winch(win) & A_CHARTEXT);
336 waddch(win, winch(win) & A_CHARTEXT);
337 }
338 wnoutrefresh(win);
339 }
340}
341
342/*
343 * Return the position of the first alphabetic character in a string.
344 */
345int first_alpha(const char *string, const char *exempt)
346{
347 int i, in_paren = 0, c;
348
349 for (i = 0; i < strlen(string); i++) {
350 c = tolower(string[i]);
351
352 if (strchr("<[(", c))
353 ++in_paren;
354 if (strchr(">])", c) && in_paren > 0)
355 --in_paren;
356
357 if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
358 return i;
359 }
360
361 return 0;
362}
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
new file mode 100644
index 000000000000..cb2568aae3ed
--- /dev/null
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -0,0 +1,102 @@
1/*
2 * yesno.c -- implements the yes/no 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/*
25 * Display termination buttons
26 */
27static void print_buttons(WINDOW * dialog, int height, int width, int selected)
28{
29 int x = width / 2 - 10;
30 int y = height - 2;
31
32 print_button(dialog, " Yes ", y, x, selected == 0);
33 print_button(dialog, " No ", y, x + 13, selected == 1);
34
35 wmove(dialog, y, x + 1 + 13 * selected);
36 wrefresh(dialog);
37}
38
39/*
40 * Display a dialog box with two buttons - Yes and No
41 */
42int dialog_yesno(const char *title, const char *prompt, int height, int width)
43{
44 int i, x, y, key = 0, button = 0;
45 WINDOW *dialog;
46
47 /* center dialog box on screen */
48 x = (COLS - width) / 2;
49 y = (LINES - height) / 2;
50
51 draw_shadow(stdscr, y, x, height, width);
52
53 dialog = newwin(height, width, y, x);
54 keypad(dialog, TRUE);
55
56 draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
57 wattrset(dialog, border_attr);
58 mvwaddch(dialog, height - 3, 0, ACS_LTEE);
59 for (i = 0; i < width - 2; i++)
60 waddch(dialog, ACS_HLINE);
61 wattrset(dialog, dialog_attr);
62 waddch(dialog, ACS_RTEE);
63
64 print_title(dialog, title, width);
65
66 wattrset(dialog, dialog_attr);
67 print_autowrap(dialog, prompt, width - 2, 1, 3);
68
69 print_buttons(dialog, height, width, 0);
70
71 while (key != ESC) {
72 key = wgetch(dialog);
73 switch (key) {
74 case 'Y':
75 case 'y':
76 delwin(dialog);
77 return 0;
78 case 'N':
79 case 'n':
80 delwin(dialog);
81 return 1;
82
83 case TAB:
84 case KEY_LEFT:
85 case KEY_RIGHT:
86 button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button);
87
88 print_buttons(dialog, height, width, button);
89 wrefresh(dialog);
90 break;
91 case ' ':
92 case '\n':
93 delwin(dialog);
94 return button;
95 case ESC:
96 break;
97 }
98 }
99
100 delwin(dialog);
101 return -1; /* ESC pressed */
102}