diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /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.WARNING | 4 | ||||
-rw-r--r-- | scripts/lxdialog/Makefile | 42 | ||||
-rw-r--r-- | scripts/lxdialog/checklist.c | 373 | ||||
-rw-r--r-- | scripts/lxdialog/colors.h | 155 | ||||
-rw-r--r-- | scripts/lxdialog/dialog.h | 187 | ||||
-rw-r--r-- | scripts/lxdialog/inputbox.c | 240 | ||||
-rw-r--r-- | scripts/lxdialog/lxdialog.c | 226 | ||||
-rw-r--r-- | scripts/lxdialog/menubox.c | 445 | ||||
-rw-r--r-- | scripts/lxdialog/msgbox.c | 85 | ||||
-rw-r--r-- | scripts/lxdialog/textbox.c | 556 | ||||
-rw-r--r-- | scripts/lxdialog/util.c | 359 | ||||
-rw-r--r-- | scripts/lxdialog/yesno.c | 118 |
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 @@ | |||
1 | This is NOT the official version of dialog. This version has been | ||
2 | significantly modified from the original. It is for use by the Linux | ||
3 | kernel configuration script. Please do not bother Savio Lam with | ||
4 | questions 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 @@ | |||
1 | HOST_EXTRACFLAGS := -DLOCALE | ||
2 | ifeq ($(shell uname),SunOS) | ||
3 | HOST_LOADLIBES := -lcurses | ||
4 | else | ||
5 | HOST_LOADLIBES := -lncurses | ||
6 | endif | ||
7 | |||
8 | ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) | ||
9 | HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>" | ||
10 | else | ||
11 | ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) | ||
12 | HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>" | ||
13 | else | ||
14 | ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) | ||
15 | HOST_EXTRACFLAGS += -DCURSES_LOC="<ncurses.h>" | ||
16 | else | ||
17 | HOST_EXTRACFLAGS += -DCURSES_LOC="<curses.h>" | ||
18 | endif | ||
19 | endif | ||
20 | endif | ||
21 | |||
22 | hostprogs-y := lxdialog | ||
23 | always := ncurses $(hostprogs-y) | ||
24 | |||
25 | lxdialog-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 | |||
26 | static int list_width, check_x, item_x, checkflag; | ||
27 | |||
28 | /* | ||
29 | * Print list item | ||
30 | */ | ||
31 | static void | ||
32 | print_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 | */ | ||
63 | static void | ||
64 | print_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 | */ | ||
102 | static void | ||
103 | print_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 | */ | ||
119 | int | ||
120 | dialog_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 | |||
155 | extern 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 | */ | ||
130 | extern bool use_colors; | ||
131 | extern bool use_shadow; | ||
132 | |||
133 | extern chtype attributes[]; | ||
134 | |||
135 | extern const char *backtitle; | ||
136 | |||
137 | /* | ||
138 | * Function prototypes | ||
139 | */ | ||
140 | extern void create_rc (const char *filename); | ||
141 | extern int parse_rc (void); | ||
142 | |||
143 | |||
144 | void init_dialog (void); | ||
145 | void end_dialog (void); | ||
146 | void attr_clear (WINDOW * win, int height, int width, chtype attr); | ||
147 | void dialog_clear (void); | ||
148 | void color_setup (void); | ||
149 | void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x); | ||
150 | void print_button (WINDOW * win, const char *label, int y, int x, int selected); | ||
151 | void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box, | ||
152 | chtype border); | ||
153 | void draw_shadow (WINDOW * win, int y, int x, int height, int width); | ||
154 | |||
155 | int first_alpha (const char *string, const char *exempt); | ||
156 | int dialog_yesno (const char *title, const char *prompt, int height, int width); | ||
157 | int dialog_msgbox (const char *title, const char *prompt, int height, | ||
158 | int width, int pause); | ||
159 | int dialog_textbox (const char *title, const char *file, int height, int width); | ||
160 | int 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); | ||
163 | int 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); | ||
166 | extern unsigned char dialog_input_result[]; | ||
167 | int 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 | |||
24 | unsigned char dialog_input_result[MAX_LEN + 1]; | ||
25 | |||
26 | /* | ||
27 | * Print the termination buttons | ||
28 | */ | ||
29 | static void | ||
30 | print_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 | */ | ||
45 | int | ||
46 | dialog_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 | |||
24 | static void Usage (const char *name); | ||
25 | |||
26 | typedef int (jumperFn) (const char *title, int argc, const char * const * argv); | ||
27 | |||
28 | struct Mode { | ||
29 | char *name; | ||
30 | int argmin, argmax, argmod; | ||
31 | jumperFn *jumper; | ||
32 | }; | ||
33 | |||
34 | jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox; | ||
35 | jumperFn j_msgbox, j_infobox; | ||
36 | |||
37 | static 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 | |||
50 | static struct Mode *modePtr; | ||
51 | |||
52 | #ifdef LOCALE | ||
53 | #include <locale.h> | ||
54 | #endif | ||
55 | |||
56 | int | ||
57 | main (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 | */ | ||
142 | static void | ||
143 | Usage (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 | |||
172 | int | ||
173 | j_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 | |||
179 | int | ||
180 | j_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 | |||
186 | int | ||
187 | j_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 | |||
193 | int | ||
194 | j_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 | |||
199 | int | ||
200 | j_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 | |||
205 | int | ||
206 | j_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 | |||
215 | int | ||
216 | j_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 | |||
221 | int | ||
222 | j_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 | |||
61 | static int menu_width, item_x; | ||
62 | |||
63 | /* | ||
64 | * Print menu item | ||
65 | */ | ||
66 | static void | ||
67 | print_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 | */ | ||
103 | static void | ||
104 | print_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 | */ | ||
148 | static void | ||
149 | print_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 | */ | ||
165 | int | ||
166 | dialog_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 | */ | ||
28 | int | ||
29 | dialog_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 | |||
24 | static void back_lines (int n); | ||
25 | static void print_page (WINDOW * win, int height, int width); | ||
26 | static void print_line (WINDOW * win, int row, int width); | ||
27 | static char *get_line (void); | ||
28 | static void print_position (WINDOW * win, int height, int width); | ||
29 | |||
30 | static int hscroll, fd, file_size, bytes_read; | ||
31 | static int begin_reached = 1, end_reached, page_length; | ||
32 | static char *buf, *page; | ||
33 | |||
34 | /* | ||
35 | * Display text from a file in a dialog box. | ||
36 | */ | ||
37 | int | ||
38 | dialog_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 | */ | ||
327 | static void | ||
328 | back_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 | */ | ||
440 | static void | ||
441 | print_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 | */ | ||
459 | static void | ||
460 | print_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 | */ | ||
489 | static char * | ||
490 | get_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 | */ | ||
540 | static void | ||
541 | print_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? */ | ||
26 | bool use_colors = 1; | ||
27 | |||
28 | const char *backtitle = NULL; | ||
29 | |||
30 | const char *dialog_result; | ||
31 | |||
32 | /* | ||
33 | * Attribute values, default is for mono display | ||
34 | */ | ||
35 | chtype 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 | */ | ||
74 | int 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 | */ | ||
111 | void | ||
112 | attr_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 | |||
125 | void 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 | */ | ||
144 | void | ||
145 | init_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 | */ | ||
163 | void | ||
164 | color_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 | */ | ||
184 | void | ||
185 | end_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 | */ | ||
197 | void | ||
198 | print_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 | */ | ||
257 | void | ||
258 | print_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 | */ | ||
285 | void | ||
286 | draw_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 | */ | ||
320 | void | ||
321 | draw_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 | */ | ||
342 | int | ||
343 | first_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 | */ | ||
27 | static void | ||
28 | print_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 | */ | ||
43 | int | ||
44 | dialog_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 | } | ||