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