Root/
Source at commit 1077 created 13 years 1 month ago. By azimutz, Removing this info from DEBUG's realm. This will be enabled by default until i gather enough feedback to decide whether it will stay On or Off by default. This info display, is only available on Gui; ShowInfo=No disables it. For the Gui minimalist, "Boot Banner"=No also disables it. Ok, "house cleaning" is suspended until i figure out what Meklort's cooking over at that new branch... "rewrite" :-o just the name sounds scary :-D | |
---|---|
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 <stdarg.h>␊ |
23 | ␊ |
24 | #include "dialog.h"␊ |
25 | ␊ |
26 | struct dialog_info dlg;␊ |
27 | ␊ |
28 | static void set_mono_theme(void)␊ |
29 | {␊ |
30 | ␉dlg.screen.atr = A_NORMAL;␊ |
31 | ␉dlg.shadow.atr = A_NORMAL;␊ |
32 | ␉dlg.dialog.atr = A_NORMAL;␊ |
33 | ␉dlg.title.atr = A_BOLD;␊ |
34 | ␉dlg.border.atr = A_NORMAL;␊ |
35 | ␉dlg.button_active.atr = A_REVERSE;␊ |
36 | ␉dlg.button_inactive.atr = A_DIM;␊ |
37 | ␉dlg.button_key_active.atr = A_REVERSE;␊ |
38 | ␉dlg.button_key_inactive.atr = A_BOLD;␊ |
39 | ␉dlg.button_label_active.atr = A_REVERSE;␊ |
40 | ␉dlg.button_label_inactive.atr = A_NORMAL;␊ |
41 | ␉dlg.inputbox.atr = A_NORMAL;␊ |
42 | ␉dlg.inputbox_border.atr = A_NORMAL;␊ |
43 | ␉dlg.searchbox.atr = A_NORMAL;␊ |
44 | ␉dlg.searchbox_title.atr = A_BOLD;␊ |
45 | ␉dlg.searchbox_border.atr = A_NORMAL;␊ |
46 | ␉dlg.position_indicator.atr = A_BOLD;␊ |
47 | ␉dlg.menubox.atr = A_NORMAL;␊ |
48 | ␉dlg.menubox_border.atr = A_NORMAL;␊ |
49 | ␉dlg.item.atr = A_NORMAL;␊ |
50 | ␉dlg.item_selected.atr = A_REVERSE;␊ |
51 | ␉dlg.tag.atr = A_BOLD;␊ |
52 | ␉dlg.tag_selected.atr = A_REVERSE;␊ |
53 | ␉dlg.tag_key.atr = A_BOLD;␊ |
54 | ␉dlg.tag_key_selected.atr = A_REVERSE;␊ |
55 | ␉dlg.check.atr = A_BOLD;␊ |
56 | ␉dlg.check_selected.atr = A_REVERSE;␊ |
57 | ␉dlg.uarrow.atr = A_BOLD;␊ |
58 | ␉dlg.darrow.atr = A_BOLD;␊ |
59 | }␊ |
60 | ␊ |
61 | #define DLG_COLOR(dialog, f, b, h) \␊ |
62 | do { \␊ |
63 | ␉dlg.dialog.fg = (f); \␊ |
64 | ␉dlg.dialog.bg = (b); \␊ |
65 | ␉dlg.dialog.hl = (h); \␊ |
66 | } while (0)␊ |
67 | ␊ |
68 | static void set_classic_theme(void)␊ |
69 | {␊ |
70 | ␉DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true);␊ |
71 | ␉DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true);␊ |
72 | ␉DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false);␊ |
73 | ␉DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true);␊ |
74 | ␉DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true);␊ |
75 | ␉DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true);␊ |
76 | ␉DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false);␊ |
77 | ␉DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true);␊ |
78 | ␉DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false);␊ |
79 | ␉DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true);␊ |
80 | ␉DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true);␊ |
81 | ␉DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false);␊ |
82 | ␉DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false);␊ |
83 | ␉DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false);␊ |
84 | ␉DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true);␊ |
85 | ␉DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true);␊ |
86 | ␉DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true);␊ |
87 | ␉DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false);␊ |
88 | ␉DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true);␊ |
89 | ␉DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false);␊ |
90 | ␉DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true);␊ |
91 | ␉DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true);␊ |
92 | ␉DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true);␊ |
93 | ␉DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true);␊ |
94 | ␉DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true);␊ |
95 | ␉DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false);␊ |
96 | ␉DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true);␊ |
97 | ␉DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true);␊ |
98 | ␉DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true);␊ |
99 | }␊ |
100 | ␊ |
101 | static void set_blackbg_theme(void)␊ |
102 | {␊ |
103 | ␉DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true);␊ |
104 | ␉DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);␊ |
105 | ␉DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);␊ |
106 | ␉DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false);␊ |
107 | ␉DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);␊ |
108 | ␊ |
109 | ␉DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false);␊ |
110 | ␉DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false);␊ |
111 | ␉DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true);␊ |
112 | ␉DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false);␊ |
113 | ␉DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false);␊ |
114 | ␉DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true);␊ |
115 | ␊ |
116 | ␉DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false);␊ |
117 | ␉DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false);␊ |
118 | ␊ |
119 | ␉DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false);␊ |
120 | ␉DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true);␊ |
121 | ␉DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true);␊ |
122 | ␊ |
123 | ␉DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false);␊ |
124 | ␊ |
125 | ␉DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false);␊ |
126 | ␉DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true);␊ |
127 | ␊ |
128 | ␉DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false);␊ |
129 | ␉DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false);␊ |
130 | ␊ |
131 | ␉DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false);␊ |
132 | ␉DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true);␊ |
133 | ␉DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false);␊ |
134 | ␉DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true);␊ |
135 | ␊ |
136 | ␉DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false);␊ |
137 | ␉DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true);␊ |
138 | ␊ |
139 | ␉DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);␊ |
140 | ␉DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);␊ |
141 | }␊ |
142 | ␊ |
143 | static void set_bluetitle_theme(void)␊ |
144 | {␊ |
145 | ␉set_classic_theme();␊ |
146 | ␉DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true);␊ |
147 | ␉DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true);␊ |
148 | ␉DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true);␊ |
149 | ␉DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true);␊ |
150 | ␉DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true);␊ |
151 | ␉DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true);␊ |
152 | ␉DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true);␊ |
153 | ␊ |
154 | }␊ |
155 | ␊ |
156 | /*␊ |
157 | * Select color theme␊ |
158 | */␊ |
159 | static int set_theme(const char *theme)␊ |
160 | {␊ |
161 | ␉int use_color = 1;␊ |
162 | ␉if (!theme)␊ |
163 | ␉␉set_bluetitle_theme();␊ |
164 | ␉else if (strcmp(theme, "classic") == 0)␊ |
165 | ␉␉set_classic_theme();␊ |
166 | ␉else if (strcmp(theme, "bluetitle") == 0)␊ |
167 | ␉␉set_bluetitle_theme();␊ |
168 | ␉else if (strcmp(theme, "blackbg") == 0)␊ |
169 | ␉␉set_blackbg_theme();␊ |
170 | ␉else if (strcmp(theme, "mono") == 0)␊ |
171 | ␉␉use_color = 0;␊ |
172 | ␊ |
173 | ␉return use_color;␊ |
174 | }␊ |
175 | ␊ |
176 | static void init_one_color(struct dialog_color *color)␊ |
177 | {␊ |
178 | ␉static int pair = 0;␊ |
179 | ␊ |
180 | ␉pair++;␊ |
181 | ␉init_pair(pair, color->fg, color->bg);␊ |
182 | ␉if (color->hl)␊ |
183 | ␉␉color->atr = A_BOLD | COLOR_PAIR(pair);␊ |
184 | ␉else␊ |
185 | ␉␉color->atr = COLOR_PAIR(pair);␊ |
186 | }␊ |
187 | ␊ |
188 | static void init_dialog_colors(void)␊ |
189 | {␊ |
190 | ␉init_one_color(&dlg.screen);␊ |
191 | ␉init_one_color(&dlg.shadow);␊ |
192 | ␉init_one_color(&dlg.dialog);␊ |
193 | ␉init_one_color(&dlg.title);␊ |
194 | ␉init_one_color(&dlg.border);␊ |
195 | ␉init_one_color(&dlg.button_active);␊ |
196 | ␉init_one_color(&dlg.button_inactive);␊ |
197 | ␉init_one_color(&dlg.button_key_active);␊ |
198 | ␉init_one_color(&dlg.button_key_inactive);␊ |
199 | ␉init_one_color(&dlg.button_label_active);␊ |
200 | ␉init_one_color(&dlg.button_label_inactive);␊ |
201 | ␉init_one_color(&dlg.inputbox);␊ |
202 | ␉init_one_color(&dlg.inputbox_border);␊ |
203 | ␉init_one_color(&dlg.searchbox);␊ |
204 | ␉init_one_color(&dlg.searchbox_title);␊ |
205 | ␉init_one_color(&dlg.searchbox_border);␊ |
206 | ␉init_one_color(&dlg.position_indicator);␊ |
207 | ␉init_one_color(&dlg.menubox);␊ |
208 | ␉init_one_color(&dlg.menubox_border);␊ |
209 | ␉init_one_color(&dlg.item);␊ |
210 | ␉init_one_color(&dlg.item_selected);␊ |
211 | ␉init_one_color(&dlg.tag);␊ |
212 | ␉init_one_color(&dlg.tag_selected);␊ |
213 | ␉init_one_color(&dlg.tag_key);␊ |
214 | ␉init_one_color(&dlg.tag_key_selected);␊ |
215 | ␉init_one_color(&dlg.check);␊ |
216 | ␉init_one_color(&dlg.check_selected);␊ |
217 | ␉init_one_color(&dlg.uarrow);␊ |
218 | ␉init_one_color(&dlg.darrow);␊ |
219 | }␊ |
220 | ␊ |
221 | /*␊ |
222 | * Setup for color display␊ |
223 | */␊ |
224 | static void color_setup(const char *theme)␊ |
225 | {␊ |
226 | ␉int use_color;␊ |
227 | ␊ |
228 | ␉use_color = set_theme(theme);␊ |
229 | ␉if (use_color && has_colors()) {␊ |
230 | ␉␉start_color();␊ |
231 | ␉␉init_dialog_colors();␊ |
232 | ␉} else␊ |
233 | ␉␉set_mono_theme();␊ |
234 | }␊ |
235 | ␊ |
236 | /*␊ |
237 | * Set window to attribute 'attr'␊ |
238 | */␊ |
239 | void attr_clear(WINDOW * win, int height, int width, chtype attr)␊ |
240 | {␊ |
241 | ␉int i, j;␊ |
242 | ␊ |
243 | ␉wattrset(win, attr);␊ |
244 | ␉for (i = 0; i < height; i++) {␊ |
245 | ␉␉wmove(win, i, 0);␊ |
246 | ␉␉for (j = 0; j < width; j++)␊ |
247 | ␉␉␉waddch(win, ' ');␊ |
248 | ␉}␊ |
249 | ␉touchwin(win);␊ |
250 | }␊ |
251 | ␊ |
252 | void dialog_clear(void)␊ |
253 | {␊ |
254 | ␉attr_clear(stdscr, LINES, COLS, dlg.screen.atr);␊ |
255 | ␉/* Display background title if it exists ... - SLH */␊ |
256 | ␉if (dlg.backtitle != NULL) {␊ |
257 | ␉␉int i;␊ |
258 | ␊ |
259 | ␉␉wattrset(stdscr, dlg.screen.atr);␊ |
260 | ␉␉mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);␊ |
261 | ␉␉wmove(stdscr, 1, 1);␊ |
262 | ␉␉for (i = 1; i < COLS - 1; i++)␊ |
263 | ␉␉␉waddch(stdscr, ACS_HLINE);␊ |
264 | ␉}␊ |
265 | ␉wnoutrefresh(stdscr);␊ |
266 | }␊ |
267 | ␊ |
268 | /*␊ |
269 | * Do some initialization for dialog␊ |
270 | */␊ |
271 | int init_dialog(const char *backtitle)␊ |
272 | {␊ |
273 | ␉int height, width;␊ |
274 | ␊ |
275 | ␉initscr();␉␉/* Init curses */␊ |
276 | ␉getmaxyx(stdscr, height, width);␊ |
277 | ␉if (height < 19 || width < 80) {␊ |
278 | ␉␉endwin();␊ |
279 | ␉␉return -ERRDISPLAYTOOSMALL;␊ |
280 | ␉}␊ |
281 | ␊ |
282 | ␉dlg.backtitle = backtitle;␊ |
283 | ␉color_setup(getenv("MENUCONFIG_COLOR"));␊ |
284 | ␊ |
285 | ␉keypad(stdscr, TRUE);␊ |
286 | ␉cbreak();␊ |
287 | ␉noecho();␊ |
288 | ␉dialog_clear();␊ |
289 | ␊ |
290 | ␉return 0;␊ |
291 | }␊ |
292 | ␊ |
293 | void set_dialog_backtitle(const char *backtitle)␊ |
294 | {␊ |
295 | ␉dlg.backtitle = backtitle;␊ |
296 | }␊ |
297 | ␊ |
298 | /*␊ |
299 | * End using dialog functions.␊ |
300 | */␊ |
301 | void end_dialog(int x, int y)␊ |
302 | {␊ |
303 | ␉/* move cursor back to original position */␊ |
304 | ␉move(y, x);␊ |
305 | ␉refresh();␊ |
306 | ␉endwin();␊ |
307 | }␊ |
308 | ␊ |
309 | /* Print the title of the dialog. Center the title and truncate␊ |
310 | * tile if wider than dialog (- 2 chars).␊ |
311 | **/␊ |
312 | void print_title(WINDOW *dialog, const char *title, int width)␊ |
313 | {␊ |
314 | ␉if (title) {␊ |
315 | ␉␉int tlen = MIN(width - 2, strlen(title));␊ |
316 | ␉␉wattrset(dialog, dlg.title.atr);␊ |
317 | ␉␉mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');␊ |
318 | ␉␉mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);␊ |
319 | ␉␉waddch(dialog, ' ');␊ |
320 | ␉}␊ |
321 | }␊ |
322 | ␊ |
323 | /*␊ |
324 | * Print a string of text in a window, automatically wrap around to the␊ |
325 | * next line if the string is too long to fit on one line. Newline␊ |
326 | * characters '\n' are replaced by spaces. We start on a new line␊ |
327 | * if there is no room for at least 4 nonblanks following a double-space.␊ |
328 | */␊ |
329 | void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)␊ |
330 | {␊ |
331 | ␉int newl, cur_x, cur_y;␊ |
332 | ␉int i, prompt_len, room, wlen;␊ |
333 | ␉char tempstr[MAX_LEN + 1], *word, *sp, *sp2;␊ |
334 | ␊ |
335 | ␉strcpy(tempstr, prompt);␊ |
336 | ␊ |
337 | ␉prompt_len = strlen(tempstr);␊ |
338 | ␊ |
339 | ␉/*␊ |
340 | ␉ * Remove newlines␊ |
341 | ␉ */␊ |
342 | ␉for (i = 0; i < prompt_len; i++) {␊ |
343 | ␉␉if (tempstr[i] == '\n')␊ |
344 | ␉␉␉tempstr[i] = ' ';␊ |
345 | ␉}␊ |
346 | ␊ |
347 | ␉if (prompt_len <= width - x * 2) {␉/* If prompt is short */␊ |
348 | ␉␉wmove(win, y, (width - prompt_len) / 2);␊ |
349 | ␉␉waddstr(win, tempstr);␊ |
350 | ␉} else {␊ |
351 | ␉␉cur_x = x;␊ |
352 | ␉␉cur_y = y;␊ |
353 | ␉␉newl = 1;␊ |
354 | ␉␉word = tempstr;␊ |
355 | ␉␉while (word && *word) {␊ |
356 | ␉␉␉sp = strchr(word, ' ');␊ |
357 | ␉␉␉if (sp)␊ |
358 | ␉␉␉␉*sp++ = 0;␊ |
359 | ␊ |
360 | ␉␉␉/* Wrap to next line if either the word does not fit,␊ |
361 | ␉␉␉ or it is the first word of a new sentence, and it is␊ |
362 | ␉␉␉ short, and the next word does not fit. */␊ |
363 | ␉␉␉room = width - cur_x;␊ |
364 | ␉␉␉wlen = strlen(word);␊ |
365 | ␉␉␉if (wlen > room ||␊ |
366 | ␉␉␉ (newl && wlen < 4 && sp␊ |
367 | ␉␉␉ && wlen + 1 + strlen(sp) > room␊ |
368 | ␉␉␉ && (!(sp2 = strchr(sp, ' '))␊ |
369 | ␉␉␉␉ || wlen + 1 + (sp2 - sp) > room))) {␊ |
370 | ␉␉␉␉cur_y++;␊ |
371 | ␉␉␉␉cur_x = x;␊ |
372 | ␉␉␉}␊ |
373 | ␉␉␉wmove(win, cur_y, cur_x);␊ |
374 | ␉␉␉waddstr(win, word);␊ |
375 | ␉␉␉getyx(win, cur_y, cur_x);␊ |
376 | ␉␉␉cur_x++;␊ |
377 | ␉␉␉if (sp && *sp == ' ') {␊ |
378 | ␉␉␉␉cur_x++;␉/* double space */␊ |
379 | ␉␉␉␉while (*++sp == ' ') ;␊ |
380 | ␉␉␉␉newl = 1;␊ |
381 | ␉␉␉} else␊ |
382 | ␉␉␉␉newl = 0;␊ |
383 | ␉␉␉word = sp;␊ |
384 | ␉␉}␊ |
385 | ␉}␊ |
386 | }␊ |
387 | ␊ |
388 | /*␊ |
389 | * Print a button␊ |
390 | */␊ |
391 | void print_button(WINDOW * win, const char *label, int y, int x, int selected)␊ |
392 | {␊ |
393 | ␉int i, temp;␊ |
394 | ␊ |
395 | ␉wmove(win, y, x);␊ |
396 | ␉wattrset(win, selected ? dlg.button_active.atr␊ |
397 | ␉␉ : dlg.button_inactive.atr);␊ |
398 | ␉waddstr(win, "<");␊ |
399 | ␉temp = strspn(label, " ");␊ |
400 | ␉label += temp;␊ |
401 | ␉wattrset(win, selected ? dlg.button_label_active.atr␊ |
402 | ␉␉ : dlg.button_label_inactive.atr);␊ |
403 | ␉for (i = 0; i < temp; i++)␊ |
404 | ␉␉waddch(win, ' ');␊ |
405 | ␉wattrset(win, selected ? dlg.button_key_active.atr␊ |
406 | ␉␉ : dlg.button_key_inactive.atr);␊ |
407 | ␉waddch(win, label[0]);␊ |
408 | ␉wattrset(win, selected ? dlg.button_label_active.atr␊ |
409 | ␉␉ : dlg.button_label_inactive.atr);␊ |
410 | ␉waddstr(win, (char *)label + 1);␊ |
411 | ␉wattrset(win, selected ? dlg.button_active.atr␊ |
412 | ␉␉ : dlg.button_inactive.atr);␊ |
413 | ␉waddstr(win, ">");␊ |
414 | ␉wmove(win, y, x + temp + 1);␊ |
415 | }␊ |
416 | ␊ |
417 | /*␊ |
418 | * Draw a rectangular box with line drawing characters␊ |
419 | */␊ |
420 | void␊ |
421 | draw_box(WINDOW * win, int y, int x, int height, int width,␊ |
422 | ␉ chtype box, chtype border)␊ |
423 | {␊ |
424 | ␉int i, j;␊ |
425 | ␊ |
426 | ␉wattrset(win, 0);␊ |
427 | ␉for (i = 0; i < height; i++) {␊ |
428 | ␉␉wmove(win, y + i, x);␊ |
429 | ␉␉for (j = 0; j < width; j++)␊ |
430 | ␉␉␉if (!i && !j)␊ |
431 | ␉␉␉␉waddch(win, border | ACS_ULCORNER);␊ |
432 | ␉␉␉else if (i == height - 1 && !j)␊ |
433 | ␉␉␉␉waddch(win, border | ACS_LLCORNER);␊ |
434 | ␉␉␉else if (!i && j == width - 1)␊ |
435 | ␉␉␉␉waddch(win, box | ACS_URCORNER);␊ |
436 | ␉␉␉else if (i == height - 1 && j == width - 1)␊ |
437 | ␉␉␉␉waddch(win, box | ACS_LRCORNER);␊ |
438 | ␉␉␉else if (!i)␊ |
439 | ␉␉␉␉waddch(win, border | ACS_HLINE);␊ |
440 | ␉␉␉else if (i == height - 1)␊ |
441 | ␉␉␉␉waddch(win, box | ACS_HLINE);␊ |
442 | ␉␉␉else if (!j)␊ |
443 | ␉␉␉␉waddch(win, border | ACS_VLINE);␊ |
444 | ␉␉␉else if (j == width - 1)␊ |
445 | ␉␉␉␉waddch(win, box | ACS_VLINE);␊ |
446 | ␉␉␉else␊ |
447 | ␉␉␉␉waddch(win, box | ' ');␊ |
448 | ␉}␊ |
449 | }␊ |
450 | ␊ |
451 | /*␊ |
452 | * Draw shadows along the right and bottom edge to give a more 3D look␊ |
453 | * to the boxes␊ |
454 | */␊ |
455 | void draw_shadow(WINDOW * win, int y, int x, int height, int width)␊ |
456 | {␊ |
457 | ␉int i;␊ |
458 | ␊ |
459 | ␉if (has_colors()) {␉/* Whether terminal supports color? */␊ |
460 | ␉␉wattrset(win, dlg.shadow.atr);␊ |
461 | ␉␉wmove(win, y + height, x + 2);␊ |
462 | ␉␉for (i = 0; i < width; i++)␊ |
463 | ␉␉␉waddch(win, winch(win) & A_CHARTEXT);␊ |
464 | ␉␉for (i = y + 1; i < y + height + 1; i++) {␊ |
465 | ␉␉␉wmove(win, i, x + width);␊ |
466 | ␉␉␉waddch(win, winch(win) & A_CHARTEXT);␊ |
467 | ␉␉␉waddch(win, winch(win) & A_CHARTEXT);␊ |
468 | ␉␉}␊ |
469 | ␉␉wnoutrefresh(win);␊ |
470 | ␉}␊ |
471 | }␊ |
472 | ␊ |
473 | /*␊ |
474 | * Return the position of the first alphabetic character in a string.␊ |
475 | */␊ |
476 | int first_alpha(const char *string, const char *exempt)␊ |
477 | {␊ |
478 | ␉int i, in_paren = 0, c;␊ |
479 | ␊ |
480 | ␉for (i = 0; i < strlen(string); i++) {␊ |
481 | ␉␉c = tolower(string[i]);␊ |
482 | ␊ |
483 | ␉␉if (strchr("<[(", c))␊ |
484 | ␉␉␉++in_paren;␊ |
485 | ␉␉if (strchr(">])", c) && in_paren > 0)␊ |
486 | ␉␉␉--in_paren;␊ |
487 | ␊ |
488 | ␉␉if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)␊ |
489 | ␉␉␉return i;␊ |
490 | ␉}␊ |
491 | ␊ |
492 | ␉return 0;␊ |
493 | }␊ |
494 | ␊ |
495 | /*␊ |
496 | * ncurses uses ESC to detect escaped char sequences. This resutl in␊ |
497 | * a small timeout before ESC is actually delivered to the application.␊ |
498 | * lxdialog suggest <ESC> <ESC> which is correctly translated to two␊ |
499 | * times esc. But then we need to ignore the second esc to avoid stepping␊ |
500 | * out one menu too much. Filter away all escaped key sequences since␊ |
501 | * keypad(FALSE) turn off ncurses support for escape sequences - and thats␊ |
502 | * needed to make notimeout() do as expected.␊ |
503 | */␊ |
504 | int on_key_esc(WINDOW *win)␊ |
505 | {␊ |
506 | ␉int key;␊ |
507 | ␉int key2;␊ |
508 | ␉int key3;␊ |
509 | ␊ |
510 | ␉nodelay(win, TRUE);␊ |
511 | ␉keypad(win, FALSE);␊ |
512 | ␉key = wgetch(win);␊ |
513 | ␉key2 = wgetch(win);␊ |
514 | ␉do {␊ |
515 | ␉␉key3 = wgetch(win);␊ |
516 | ␉} while (key3 != ERR);␊ |
517 | ␉nodelay(win, FALSE);␊ |
518 | ␉keypad(win, TRUE);␊ |
519 | ␉if (key == KEY_ESC && key2 == ERR)␊ |
520 | ␉␉return KEY_ESC;␊ |
521 | ␉else if (key != ERR && key != KEY_ESC && key2 == ERR)␊ |
522 | ␉␉ungetch(key);␊ |
523 | ␊ |
524 | ␉return -1;␊ |
525 | }␊ |
526 | ␊ |
527 | /* redraw screen in new size */␊ |
528 | int on_key_resize(void)␊ |
529 | {␊ |
530 | ␉dialog_clear();␊ |
531 | ␉return KEY_RESIZE;␊ |
532 | }␊ |
533 | ␊ |
534 | struct dialog_list *item_cur;␊ |
535 | struct dialog_list item_nil;␊ |
536 | struct dialog_list *item_head;␊ |
537 | ␊ |
538 | void item_reset(void)␊ |
539 | {␊ |
540 | ␉struct dialog_list *p, *next;␊ |
541 | ␊ |
542 | ␉for (p = item_head; p; p = next) {␊ |
543 | ␉␉next = p->next;␊ |
544 | ␉␉free(p);␊ |
545 | ␉}␊ |
546 | ␉item_head = NULL;␊ |
547 | ␉item_cur = &item_nil;␊ |
548 | }␊ |
549 | ␊ |
550 | void item_make(const char *fmt, ...)␊ |
551 | {␊ |
552 | ␉va_list ap;␊ |
553 | ␉struct dialog_list *p = malloc(sizeof(*p));␊ |
554 | ␊ |
555 | ␉if (item_head)␊ |
556 | ␉␉item_cur->next = p;␊ |
557 | ␉else␊ |
558 | ␉␉item_head = p;␊ |
559 | ␉item_cur = p;␊ |
560 | ␉memset(p, 0, sizeof(*p));␊ |
561 | ␊ |
562 | ␉va_start(ap, fmt);␊ |
563 | ␉vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);␊ |
564 | ␉va_end(ap);␊ |
565 | }␊ |
566 | ␊ |
567 | void item_add_str(const char *fmt, ...)␊ |
568 | {␊ |
569 | ␉va_list ap;␊ |
570 | size_t avail;␊ |
571 | ␊ |
572 | ␉avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);␊ |
573 | ␊ |
574 | ␉va_start(ap, fmt);␊ |
575 | ␉vsnprintf(item_cur->node.str + strlen(item_cur->node.str),␊ |
576 | ␉␉ avail, fmt, ap);␊ |
577 | ␉item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';␊ |
578 | ␉va_end(ap);␊ |
579 | }␊ |
580 | ␊ |
581 | void item_set_tag(char tag)␊ |
582 | {␊ |
583 | ␉item_cur->node.tag = tag;␊ |
584 | }␊ |
585 | void item_set_data(void *ptr)␊ |
586 | {␊ |
587 | ␉item_cur->node.data = ptr;␊ |
588 | }␊ |
589 | ␊ |
590 | void item_set_selected(int val)␊ |
591 | {␊ |
592 | ␉item_cur->node.selected = val;␊ |
593 | }␊ |
594 | ␊ |
595 | int item_activate_selected(void)␊ |
596 | {␊ |
597 | ␉item_foreach()␊ |
598 | ␉␉if (item_is_selected())␊ |
599 | ␉␉␉return 1;␊ |
600 | ␉return 0;␊ |
601 | }␊ |
602 | ␊ |
603 | void *item_data(void)␊ |
604 | {␊ |
605 | ␉return item_cur->node.data;␊ |
606 | }␊ |
607 | ␊ |
608 | char item_tag(void)␊ |
609 | {␊ |
610 | ␉return item_cur->node.tag;␊ |
611 | }␊ |
612 | ␊ |
613 | int item_count(void)␊ |
614 | {␊ |
615 | ␉int n = 0;␊ |
616 | ␉struct dialog_list *p;␊ |
617 | ␊ |
618 | ␉for (p = item_head; p; p = p->next)␊ |
619 | ␉␉n++;␊ |
620 | ␉return n;␊ |
621 | }␊ |
622 | ␊ |
623 | void item_set(int n)␊ |
624 | {␊ |
625 | ␉int i = 0;␊ |
626 | ␉item_foreach()␊ |
627 | ␉␉if (i++ == n)␊ |
628 | ␉␉␉return;␊ |
629 | }␊ |
630 | ␊ |
631 | int item_n(void)␊ |
632 | {␊ |
633 | ␉int n = 0;␊ |
634 | ␉struct dialog_list *p;␊ |
635 | ␊ |
636 | ␉for (p = item_head; p; p = p->next) {␊ |
637 | ␉␉if (p == item_cur)␊ |
638 | ␉␉␉return n;␊ |
639 | ␉␉n++;␊ |
640 | ␉}␊ |
641 | ␉return 0;␊ |
642 | }␊ |
643 | ␊ |
644 | const char *item_str(void)␊ |
645 | {␊ |
646 | ␉return item_cur->node.str;␊ |
647 | }␊ |
648 | ␊ |
649 | int item_is_selected(void)␊ |
650 | {␊ |
651 | ␉return (item_cur->node.selected != 0);␊ |
652 | }␊ |
653 | ␊ |
654 | int item_is_tag(char tag)␊ |
655 | {␊ |
656 | ␉return (item_cur->node.tag == tag);␊ |
657 | }␊ |
658 | ␊ |
659 | /*␊ |
660 | * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>␊ |
661 | * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>␊ |
662 | *␊ |
663 | * Released under the terms of the GNU GPL v2.0.␊ |
664 | */␊ |
665 | ␊ |
666 | //#include <string.h>␊ |
667 | //#include "lkc.h"␊ |
668 | ␊ |
669 | /* file already present in list? If not add it */␊ |
670 | struct file *file_lookup(const char *name)␊ |
671 | {␊ |
672 | ␉struct file *file;␊ |
673 | ␉const char *file_name = sym_expand_string_value(name);␊ |
674 | ␊ |
675 | ␉for (file = file_list; file; file = file->next) {␊ |
676 | ␉␉if (!strcmp(name, file->name)) {␊ |
677 | ␉␉␉free((void *)file_name);␊ |
678 | ␉␉␉return file;␊ |
679 | ␉␉}␊ |
680 | ␉}␊ |
681 | ␊ |
682 | ␉file = malloc(sizeof(*file));␊ |
683 | ␉memset(file, 0, sizeof(*file));␊ |
684 | ␉file->name = file_name;␊ |
685 | ␉file->next = file_list;␊ |
686 | ␉file_list = file;␊ |
687 | ␉return file;␊ |
688 | }␊ |
689 | ␊ |
690 | /* write a dependency file as used by kbuild to track dependencies */␊ |
691 | int file_write_dep(const char *name)␊ |
692 | {␊ |
693 | ␉struct symbol *sym, *env_sym;␊ |
694 | ␉struct expr *e;␊ |
695 | ␉struct file *file;␊ |
696 | ␉FILE *out;␊ |
697 | ␊ |
698 | ␉if (!name)␊ |
699 | ␉␉name = ".kconfig.d";␊ |
700 | ␉out = fopen("..config.tmp", "w");␊ |
701 | ␉if (!out)␊ |
702 | ␉␉return 1;␊ |
703 | ␉fprintf(out, "deps_config := \\\n");␊ |
704 | ␉for (file = file_list; file; file = file->next) {␊ |
705 | ␉␉if (file->next)␊ |
706 | ␉␉␉fprintf(out, "\t%s \\\n", file->name);␊ |
707 | ␉␉else␊ |
708 | ␉␉␉fprintf(out, "\t%s\n", file->name);␊ |
709 | ␉}␊ |
710 | ␉fprintf(out, "\n%s: \\\n"␊ |
711 | "\t$(deps_config)\n\n", conf_get_autoconfig_name());␊ |
712 | ␊ |
713 | ␉expr_list_for_each_sym(sym_env_list, e, sym) {␊ |
714 | ␉␉struct property *prop;␊ |
715 | ␉␉const char *value;␊ |
716 | ␊ |
717 | ␉␉prop = sym_get_env_prop(sym);␊ |
718 | ␉␉env_sym = prop_get_symbol(prop);␊ |
719 | ␉␉if (!env_sym)␊ |
720 | ␉␉␉continue;␊ |
721 | ␉␉value = getenv(env_sym->name);␊ |
722 | ␉␉if (!value)␊ |
723 | ␉␉␉value = "";␊ |
724 | ␉␉fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);␊ |
725 | ␉␉fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name());␊ |
726 | ␉␉fprintf(out, "endif\n");␊ |
727 | ␉}␊ |
728 | ␊ |
729 | ␉fprintf(out, "\n$(deps_config): ;\n");␊ |
730 | ␉fclose(out);␊ |
731 | ␉rename("..config.tmp", name);␊ |
732 | ␉return 0;␊ |
733 | }␊ |
734 | ␊ |
735 | ␊ |
736 | /* Allocate initial growable string */␊ |
737 | struct gstr str_new(void)␊ |
738 | {␊ |
739 | ␉struct gstr gs;␊ |
740 | ␉gs.s = malloc(sizeof(char) * 64);␊ |
741 | ␉gs.len = 64;␊ |
742 | ␉gs.max_width = 0;␊ |
743 | ␉strcpy(gs.s, "\0");␊ |
744 | ␉return gs;␊ |
745 | }␊ |
746 | ␊ |
747 | /* Allocate and assign growable string */␊ |
748 | struct gstr str_assign(const char *s)␊ |
749 | {␊ |
750 | ␉struct gstr gs;␊ |
751 | ␉gs.s = strdup(s);␊ |
752 | ␉gs.len = strlen(s) + 1;␊ |
753 | ␉gs.max_width = 0;␊ |
754 | ␉return gs;␊ |
755 | }␊ |
756 | ␊ |
757 | /* Free storage for growable string */␊ |
758 | void str_free(struct gstr *gs)␊ |
759 | {␊ |
760 | ␉if (gs->s)␊ |
761 | ␉␉free(gs->s);␊ |
762 | ␉gs->s = NULL;␊ |
763 | ␉gs->len = 0;␊ |
764 | }␊ |
765 | ␊ |
766 | /* Append to growable string */␊ |
767 | void str_append(struct gstr *gs, const char *s)␊ |
768 | {␊ |
769 | ␉size_t l;␊ |
770 | ␉if (s) {␊ |
771 | ␉␉l = strlen(gs->s) + strlen(s) + 1;␊ |
772 | ␉␉if (l > gs->len) {␊ |
773 | ␉␉␉gs->s = realloc(gs->s, l);␊ |
774 | ␉␉␉gs->len = l;␊ |
775 | ␉␉}␊ |
776 | ␉␉strcat(gs->s, s);␊ |
777 | ␉}␊ |
778 | }␊ |
779 | ␊ |
780 | /* Append printf formatted string to growable string */␊ |
781 | void str_printf(struct gstr *gs, const char *fmt, ...)␊ |
782 | {␊ |
783 | ␉va_list ap;␊ |
784 | ␉char s[10000]; /* big enough... */␊ |
785 | ␉va_start(ap, fmt);␊ |
786 | ␉vsnprintf(s, sizeof(s), fmt, ap);␊ |
787 | ␉str_append(gs, s);␊ |
788 | ␉va_end(ap);␊ |
789 | }␊ |
790 | ␊ |
791 | /* Retrieve value of growable string */␊ |
792 | const char *str_get(struct gstr *gs)␊ |
793 | {␊ |
794 | ␉return gs->s;␊ |
795 | }␊ |
796 | ␊ |
797 |