diff options
Diffstat (limited to 'scripts/kconfig/nconf.c')
-rw-r--r-- | scripts/kconfig/nconf.c | 489 |
1 files changed, 239 insertions, 250 deletions
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 762caf80ce37..272a987f23e0 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c | |||
@@ -5,25 +5,26 @@ | |||
5 | * Derived from menuconfig. | 5 | * Derived from menuconfig. |
6 | * | 6 | * |
7 | */ | 7 | */ |
8 | #define _GNU_SOURCE | ||
9 | #include <string.h> | ||
8 | #define LKC_DIRECT_LINK | 10 | #define LKC_DIRECT_LINK |
9 | #include "lkc.h" | 11 | #include "lkc.h" |
10 | #include "nconf.h" | 12 | #include "nconf.h" |
13 | #include <ctype.h> | ||
11 | 14 | ||
12 | static const char nconf_readme[] = N_( | 15 | static const char nconf_readme[] = N_( |
13 | "Overview\n" | 16 | "Overview\n" |
14 | "--------\n" | 17 | "--------\n" |
15 | "Some kernel features may be built directly into the kernel.\n" | 18 | "This interface let you select features and parameters for the build.\n" |
16 | "Some may be made into loadable runtime modules. Some features\n" | 19 | "Features can either be built-in, modularized, or ignored. Parameters\n" |
17 | "may be completely removed altogether. There are also certain\n" | 20 | "must be entered in as decimal or hexadecimal numbers or text.\n" |
18 | "kernel parameters which are not really features, but must be\n" | ||
19 | "entered in as decimal or hexadecimal numbers or possibly text.\n" | ||
20 | "\n" | 21 | "\n" |
21 | "Menu items beginning with following braces represent features that\n" | 22 | "Menu items beginning with following braces represent features that\n" |
22 | " [ ] can be built in or removed\n" | 23 | " [ ] can be built in or removed\n" |
23 | " < > can be built in, modularized or removed\n" | 24 | " < > can be built in, modularized or removed\n" |
24 | " { } can be built in or modularized (selected by other feature)\n" | 25 | " { } can be built in or modularized (selected by other feature)\n" |
25 | " - - are selected by other feature,\n" | 26 | " - - are selected by other feature,\n" |
26 | " XXX cannot be selected. use Symbol Info to find out why,\n" | 27 | " XXX cannot be selected. Use Symbol Info to find out why,\n" |
27 | "while *, M or whitespace inside braces means to build in, build as\n" | 28 | "while *, M or whitespace inside braces means to build in, build as\n" |
28 | "a module or to exclude the feature respectively.\n" | 29 | "a module or to exclude the feature respectively.\n" |
29 | "\n" | 30 | "\n" |
@@ -41,9 +42,13 @@ static const char nconf_readme[] = N_( | |||
41 | " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" | 42 | " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" |
42 | " Submenus are designated by \"--->\".\n" | 43 | " Submenus are designated by \"--->\".\n" |
43 | "\n" | 44 | "\n" |
44 | " Shortcut: Press the option's highlighted letter (hotkey).\n" | 45 | " Searching: pressing '/' triggers interactive search mode.\n" |
45 | " Pressing a hotkey more than once will sequence\n" | 46 | " nconfig performs a case insensitive search for the string\n" |
46 | " through all visible items which use that hotkey.\n" | 47 | " in the menu prompts (no regex support).\n" |
48 | " Pressing the up/down keys highlights the previous/next\n" | ||
49 | " matching item. Backspace removes one character from the\n" | ||
50 | " match string. Pressing either '/' again or ESC exits\n" | ||
51 | " search mode. All other keys behave normally.\n" | ||
47 | "\n" | 52 | "\n" |
48 | " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" | 53 | " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" |
49 | " unseen options into view.\n" | 54 | " unseen options into view.\n" |
@@ -88,7 +93,7 @@ static const char nconf_readme[] = N_( | |||
88 | "-----------------------------\n" | 93 | "-----------------------------\n" |
89 | "nconfig supports the use of alternate configuration files for\n" | 94 | "nconfig supports the use of alternate configuration files for\n" |
90 | "those who, for various reasons, find it necessary to switch\n" | 95 | "those who, for various reasons, find it necessary to switch\n" |
91 | "between different kernel configurations.\n" | 96 | "between different configurations.\n" |
92 | "\n" | 97 | "\n" |
93 | "At the end of the main menu you will find two options. One is\n" | 98 | "At the end of the main menu you will find two options. One is\n" |
94 | "for saving the current configuration to a file of your choosing.\n" | 99 | "for saving the current configuration to a file of your choosing.\n" |
@@ -121,9 +126,9 @@ static const char nconf_readme[] = N_( | |||
121 | "\n" | 126 | "\n" |
122 | "Optional personality available\n" | 127 | "Optional personality available\n" |
123 | "------------------------------\n" | 128 | "------------------------------\n" |
124 | "If you prefer to have all of the kernel options listed in a single\n" | 129 | "If you prefer to have all of the options listed in a single menu, rather\n" |
125 | "menu, rather than the default multimenu hierarchy, run the nconfig\n" | 130 | "than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n" |
126 | "with NCONFIG_MODE environment variable set to single_menu. Example:\n" | 131 | "environment variable set to single_menu. Example:\n" |
127 | "\n" | 132 | "\n" |
128 | "make NCONFIG_MODE=single_menu nconfig\n" | 133 | "make NCONFIG_MODE=single_menu nconfig\n" |
129 | "\n" | 134 | "\n" |
@@ -141,21 +146,21 @@ menu_no_f_instructions[] = N_( | |||
141 | " <Enter> or <right-arrow> selects submenus --->.\n" | 146 | " <Enter> or <right-arrow> selects submenus --->.\n" |
142 | " Capital Letters are hotkeys.\n" | 147 | " Capital Letters are hotkeys.\n" |
143 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" | 148 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" |
144 | " Pressing SpaceBar toggles between the above options\n" | 149 | " Pressing SpaceBar toggles between the above options.\n" |
145 | " Press <Esc> or <left-arrow> to go back one menu, \n" | 150 | " Press <Esc> or <left-arrow> to go back one menu,\n" |
146 | " <?> or <h> for Help, </> for Search.\n" | 151 | " <?> or <h> for Help, </> for Search.\n" |
147 | " <1> is interchangable with <F1>, <2> with <F2>, etc.\n" | 152 | " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n" |
148 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" | 153 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" |
149 | " <Esc> always leaves the current window\n"), | 154 | " <Esc> always leaves the current window.\n"), |
150 | menu_instructions[] = N_( | 155 | menu_instructions[] = N_( |
151 | " Arrow keys navigate the menu.\n" | 156 | " Arrow keys navigate the menu.\n" |
152 | " <Enter> or <right-arrow> selects submenus --->.\n" | 157 | " <Enter> or <right-arrow> selects submenus --->.\n" |
153 | " Capital Letters are hotkeys.\n" | 158 | " Capital Letters are hotkeys.\n" |
154 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" | 159 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" |
155 | " Pressing SpaceBar toggles between the above options\n" | 160 | " Pressing SpaceBar toggles between the above options\n" |
156 | " Press <Esc>, <F3> or <left-arrow> to go back one menu, \n" | 161 | " Press <Esc>, <F5> or <left-arrow> to go back one menu,\n" |
157 | " <?>, <F1> or <h> for Help, </> for Search.\n" | 162 | " <?>, <F1> or <h> for Help, </> for Search.\n" |
158 | " <1> is interchangable with <F1>, <2> with <F2>, etc.\n" | 163 | " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n" |
159 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" | 164 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" |
160 | " <Esc> always leaves the current window\n"), | 165 | " <Esc> always leaves the current window\n"), |
161 | radiolist_instructions[] = N_( | 166 | radiolist_instructions[] = N_( |
@@ -178,19 +183,19 @@ setmod_text[] = N_( | |||
178 | "has been configured as a module.\n" | 183 | "has been configured as a module.\n" |
179 | "As a result, this feature will be built as a module."), | 184 | "As a result, this feature will be built as a module."), |
180 | nohelp_text[] = N_( | 185 | nohelp_text[] = N_( |
181 | "There is no help available for this kernel option.\n"), | 186 | "There is no help available for this option.\n"), |
182 | load_config_text[] = N_( | 187 | load_config_text[] = N_( |
183 | "Enter the name of the configuration file you wish to load.\n" | 188 | "Enter the name of the configuration file you wish to load.\n" |
184 | "Accept the name shown to restore the configuration you\n" | 189 | "Accept the name shown to restore the configuration you\n" |
185 | "last retrieved. Leave blank to abort."), | 190 | "last retrieved. Leave blank to abort."), |
186 | load_config_help[] = N_( | 191 | load_config_help[] = N_( |
187 | "\n" | 192 | "\n" |
188 | "For various reasons, one may wish to keep several different kernel\n" | 193 | "For various reasons, one may wish to keep several different\n" |
189 | "configurations available on a single machine.\n" | 194 | "configurations available on a single machine.\n" |
190 | "\n" | 195 | "\n" |
191 | "If you have saved a previous configuration in a file other than the\n" | 196 | "If you have saved a previous configuration in a file other than the\n" |
192 | "kernel's default, entering the name of the file here will allow you\n" | 197 | "default one, entering its name here will allow you to modify that\n" |
193 | "to modify that configuration.\n" | 198 | "configuration.\n" |
194 | "\n" | 199 | "\n" |
195 | "If you are uncertain, then you have probably never used alternate\n" | 200 | "If you are uncertain, then you have probably never used alternate\n" |
196 | "configuration files. You should therefor leave this blank to abort.\n"), | 201 | "configuration files. You should therefor leave this blank to abort.\n"), |
@@ -199,8 +204,8 @@ save_config_text[] = N_( | |||
199 | "as an alternate. Leave blank to abort."), | 204 | "as an alternate. Leave blank to abort."), |
200 | save_config_help[] = N_( | 205 | save_config_help[] = N_( |
201 | "\n" | 206 | "\n" |
202 | "For various reasons, one may wish to keep different kernel\n" | 207 | "For various reasons, one may wish to keep different configurations\n" |
203 | "configurations available on a single machine.\n" | 208 | "available on a single machine.\n" |
204 | "\n" | 209 | "\n" |
205 | "Entering a file name here will allow you to later retrieve, modify\n" | 210 | "Entering a file name here will allow you to later retrieve, modify\n" |
206 | "and use the current configuration as an alternate to whatever\n" | 211 | "and use the current configuration as an alternate to whatever\n" |
@@ -210,8 +215,8 @@ save_config_help[] = N_( | |||
210 | "leave this blank.\n"), | 215 | "leave this blank.\n"), |
211 | search_help[] = N_( | 216 | search_help[] = N_( |
212 | "\n" | 217 | "\n" |
213 | "Search for CONFIG_ symbols and display their relations.\n" | 218 | "Search for symbols and display their relations. Regular expressions\n" |
214 | "Regular expressions are allowed.\n" | 219 | "are allowed.\n" |
215 | "Example: search for \"^FOO\"\n" | 220 | "Example: search for \"^FOO\"\n" |
216 | "Result:\n" | 221 | "Result:\n" |
217 | "-----------------------------------------------------------------\n" | 222 | "-----------------------------------------------------------------\n" |
@@ -227,7 +232,7 @@ search_help[] = N_( | |||
227 | "Selected by: BAR\n" | 232 | "Selected by: BAR\n" |
228 | "-----------------------------------------------------------------\n" | 233 | "-----------------------------------------------------------------\n" |
229 | "o The line 'Prompt:' shows the text used in the menu structure for\n" | 234 | "o The line 'Prompt:' shows the text used in the menu structure for\n" |
230 | " this CONFIG_ symbol\n" | 235 | " this symbol\n" |
231 | "o The 'Defined at' line tell at what file / line number the symbol\n" | 236 | "o The 'Defined at' line tell at what file / line number the symbol\n" |
232 | " is defined\n" | 237 | " is defined\n" |
233 | "o The 'Depends on:' line tell what symbols needs to be defined for\n" | 238 | "o The 'Depends on:' line tell what symbols needs to be defined for\n" |
@@ -243,16 +248,15 @@ search_help[] = N_( | |||
243 | "Only relevant lines are shown.\n" | 248 | "Only relevant lines are shown.\n" |
244 | "\n\n" | 249 | "\n\n" |
245 | "Search examples:\n" | 250 | "Search examples:\n" |
246 | "Examples: USB = > find all CONFIG_ symbols containing USB\n" | 251 | "Examples: USB = > find all symbols containing USB\n" |
247 | " ^USB => find all CONFIG_ symbols starting with USB\n" | 252 | " ^USB => find all symbols starting with USB\n" |
248 | " USB$ => find all CONFIG_ symbols ending with USB\n" | 253 | " USB$ => find all symbols ending with USB\n" |
249 | "\n"); | 254 | "\n"); |
250 | 255 | ||
251 | struct mitem { | 256 | struct mitem { |
252 | char str[256]; | 257 | char str[256]; |
253 | char tag; | 258 | char tag; |
254 | void *usrptr; | 259 | void *usrptr; |
255 | int is_hot; | ||
256 | int is_visible; | 260 | int is_visible; |
257 | }; | 261 | }; |
258 | 262 | ||
@@ -275,14 +279,6 @@ static int items_num; | |||
275 | static int global_exit; | 279 | static int global_exit; |
276 | /* the currently selected button */ | 280 | /* the currently selected button */ |
277 | const char *current_instructions = menu_instructions; | 281 | const char *current_instructions = menu_instructions; |
278 | /* this array is used to implement hot keys. it is updated in item_make and | ||
279 | * resetted in clean_items. It would be better to use a hash, but lets keep it | ||
280 | * simple... */ | ||
281 | #define MAX_SAME_KEY MAX_MENU_ITEMS | ||
282 | struct { | ||
283 | int count; | ||
284 | int ptrs[MAX_MENU_ITEMS]; | ||
285 | } hotkeys[1<<(sizeof(char)*8)]; | ||
286 | 282 | ||
287 | static void conf(struct menu *menu); | 283 | static void conf(struct menu *menu); |
288 | static void conf_choice(struct menu *menu); | 284 | static void conf_choice(struct menu *menu); |
@@ -292,6 +288,7 @@ static void conf_save(void); | |||
292 | static void show_help(struct menu *menu); | 288 | static void show_help(struct menu *menu); |
293 | static int do_exit(void); | 289 | static int do_exit(void); |
294 | static void setup_windows(void); | 290 | static void setup_windows(void); |
291 | static void search_conf(void); | ||
295 | 292 | ||
296 | typedef void (*function_key_handler_t)(int *key, struct menu *menu); | 293 | typedef void (*function_key_handler_t)(int *key, struct menu *menu); |
297 | static void handle_f1(int *key, struct menu *current_item); | 294 | static void handle_f1(int *key, struct menu *current_item); |
@@ -302,6 +299,7 @@ static void handle_f5(int *key, struct menu *current_item); | |||
302 | static void handle_f6(int *key, struct menu *current_item); | 299 | static void handle_f6(int *key, struct menu *current_item); |
303 | static void handle_f7(int *key, struct menu *current_item); | 300 | static void handle_f7(int *key, struct menu *current_item); |
304 | static void handle_f8(int *key, struct menu *current_item); | 301 | static void handle_f8(int *key, struct menu *current_item); |
302 | static void handle_f9(int *key, struct menu *current_item); | ||
305 | 303 | ||
306 | struct function_keys { | 304 | struct function_keys { |
307 | const char *key_str; | 305 | const char *key_str; |
@@ -310,7 +308,7 @@ struct function_keys { | |||
310 | function_key_handler_t handler; | 308 | function_key_handler_t handler; |
311 | }; | 309 | }; |
312 | 310 | ||
313 | static const int function_keys_num = 8; | 311 | static const int function_keys_num = 9; |
314 | struct function_keys function_keys[] = { | 312 | struct function_keys function_keys[] = { |
315 | { | 313 | { |
316 | .key_str = "F1", | 314 | .key_str = "F1", |
@@ -320,13 +318,13 @@ struct function_keys function_keys[] = { | |||
320 | }, | 318 | }, |
321 | { | 319 | { |
322 | .key_str = "F2", | 320 | .key_str = "F2", |
323 | .func = "Symbol Info", | 321 | .func = "Sym Info", |
324 | .key = F_SYMBOL, | 322 | .key = F_SYMBOL, |
325 | .handler = handle_f2, | 323 | .handler = handle_f2, |
326 | }, | 324 | }, |
327 | { | 325 | { |
328 | .key_str = "F3", | 326 | .key_str = "F3", |
329 | .func = "Instructions", | 327 | .func = "Insts", |
330 | .key = F_INSTS, | 328 | .key = F_INSTS, |
331 | .handler = handle_f3, | 329 | .handler = handle_f3, |
332 | }, | 330 | }, |
@@ -356,9 +354,15 @@ struct function_keys function_keys[] = { | |||
356 | }, | 354 | }, |
357 | { | 355 | { |
358 | .key_str = "F8", | 356 | .key_str = "F8", |
357 | .func = "Sym Search", | ||
358 | .key = F_SEARCH, | ||
359 | .handler = handle_f8, | ||
360 | }, | ||
361 | { | ||
362 | .key_str = "F9", | ||
359 | .func = "Exit", | 363 | .func = "Exit", |
360 | .key = F_EXIT, | 364 | .key = F_EXIT, |
361 | .handler = handle_f8, | 365 | .handler = handle_f9, |
362 | }, | 366 | }, |
363 | }; | 367 | }; |
364 | 368 | ||
@@ -444,9 +448,16 @@ static void handle_f7(int *key, struct menu *current_item) | |||
444 | return; | 448 | return; |
445 | } | 449 | } |
446 | 450 | ||
447 | /* exit */ | 451 | /* search */ |
448 | static void handle_f8(int *key, struct menu *current_item) | 452 | static void handle_f8(int *key, struct menu *current_item) |
449 | { | 453 | { |
454 | search_conf(); | ||
455 | return; | ||
456 | } | ||
457 | |||
458 | /* exit */ | ||
459 | static void handle_f9(int *key, struct menu *current_item) | ||
460 | { | ||
450 | do_exit(); | 461 | do_exit(); |
451 | return; | 462 | return; |
452 | } | 463 | } |
@@ -479,110 +490,44 @@ static void clean_items(void) | |||
479 | free_item(curses_menu_items[i]); | 490 | free_item(curses_menu_items[i]); |
480 | bzero(curses_menu_items, sizeof(curses_menu_items)); | 491 | bzero(curses_menu_items, sizeof(curses_menu_items)); |
481 | bzero(k_menu_items, sizeof(k_menu_items)); | 492 | bzero(k_menu_items, sizeof(k_menu_items)); |
482 | bzero(hotkeys, sizeof(hotkeys)); | ||
483 | items_num = 0; | 493 | items_num = 0; |
484 | } | 494 | } |
485 | 495 | ||
486 | /* return the index of the next hot item, or -1 if no such item exists */ | 496 | typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, |
487 | static int get_next_hot(int c) | 497 | FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f; |
488 | { | ||
489 | static int hot_index; | ||
490 | static int hot_char; | ||
491 | |||
492 | if (c < 0 || c > 255 || hotkeys[c].count <= 0) | ||
493 | return -1; | ||
494 | |||
495 | if (hot_char == c) { | ||
496 | hot_index = (hot_index+1)%hotkeys[c].count; | ||
497 | return hotkeys[c].ptrs[hot_index]; | ||
498 | } else { | ||
499 | hot_char = c; | ||
500 | hot_index = 0; | ||
501 | return hotkeys[c].ptrs[0]; | ||
502 | } | ||
503 | } | ||
504 | |||
505 | /* can the char c be a hot key? no, if c is a common shortcut used elsewhere */ | ||
506 | static int canbhot(char c) | ||
507 | { | ||
508 | c = tolower(c); | ||
509 | return isalnum(c) && c != 'y' && c != 'm' && c != 'h' && | ||
510 | c != 'n' && c != '?'; | ||
511 | } | ||
512 | |||
513 | /* check if str already contains a hot key. */ | ||
514 | static int is_hot(int index) | ||
515 | { | ||
516 | return k_menu_items[index].is_hot; | ||
517 | } | ||
518 | 498 | ||
519 | /* find the first possible hot key, and mark it. | 499 | /* return the index of the matched item, or -1 if no such item exists */ |
520 | * index is the index of the item in the menu | 500 | static int get_mext_match(const char *match_str, match_f flag) |
521 | * return 0 on success*/ | ||
522 | static int make_hot(char *dest, int len, const char *org, int index) | ||
523 | { | 501 | { |
524 | int position = -1; | 502 | int match_start = item_index(current_item(curses_menu)); |
525 | int i; | 503 | int index; |
526 | int tmp; | 504 | |
527 | int c; | 505 | if (flag == FIND_NEXT_MATCH_DOWN) |
528 | int org_len = strlen(org); | 506 | ++match_start; |
529 | 507 | else if (flag == FIND_NEXT_MATCH_UP) | |
530 | if (org == NULL || is_hot(index)) | 508 | --match_start; |
531 | return 1; | 509 | |
532 | 510 | index = match_start; | |
533 | /* make sure not to make hot keys out of markers. | 511 | index = (index + items_num) % items_num; |
534 | * find where to start looking for a hot key | 512 | while (true) { |
535 | */ | 513 | char *str = k_menu_items[index].str; |
536 | i = 0; | 514 | if (strcasestr(str, match_str) != 0) |
537 | /* skip white space */ | 515 | return index; |
538 | while (i < org_len && org[i] == ' ') | 516 | if (flag == FIND_NEXT_MATCH_UP || |
539 | i++; | 517 | flag == MATCH_TINKER_PATTERN_UP) |
540 | if (i == org_len) | 518 | --index; |
541 | return -1; | 519 | else |
542 | /* if encountering '(' or '<' or '[', find the match and look from there | 520 | ++index; |
543 | **/ | 521 | index = (index + items_num) % items_num; |
544 | if (org[i] == '[' || org[i] == '<' || org[i] == '(') { | 522 | if (index == match_start) |
545 | i++; | 523 | return -1; |
546 | for (; i < org_len; i++) | ||
547 | if (org[i] == ']' || org[i] == '>' || org[i] == ')') | ||
548 | break; | ||
549 | } | ||
550 | if (i == org_len) | ||
551 | return -1; | ||
552 | for (; i < org_len; i++) { | ||
553 | if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') { | ||
554 | position = i; | ||
555 | break; | ||
556 | } | ||
557 | } | 524 | } |
558 | if (position == -1) | ||
559 | return 1; | ||
560 | |||
561 | /* ok, char at org[position] should be a hot key to this item */ | ||
562 | c = tolower(org[position]); | ||
563 | tmp = hotkeys[c].count; | ||
564 | hotkeys[c].ptrs[tmp] = index; | ||
565 | hotkeys[c].count++; | ||
566 | /* | ||
567 | snprintf(dest, len, "%.*s(%c)%s", position, org, org[position], | ||
568 | &org[position+1]); | ||
569 | */ | ||
570 | /* make org[position] uppercase, and all leading letter small case */ | ||
571 | strncpy(dest, org, len); | ||
572 | for (i = 0; i < position; i++) | ||
573 | dest[i] = tolower(dest[i]); | ||
574 | dest[position] = toupper(dest[position]); | ||
575 | k_menu_items[index].is_hot = 1; | ||
576 | return 0; | ||
577 | } | 525 | } |
578 | 526 | ||
579 | /* Make a new item. Add a hotkey mark in the first possible letter. | 527 | /* Make a new item. */ |
580 | * As ncurses does not allow any attributes inside menue item, we mark the | ||
581 | * hot key as the first capitalized letter in the string */ | ||
582 | static void item_make(struct menu *menu, char tag, const char *fmt, ...) | 528 | static void item_make(struct menu *menu, char tag, const char *fmt, ...) |
583 | { | 529 | { |
584 | va_list ap; | 530 | va_list ap; |
585 | char tmp_str[256]; | ||
586 | 531 | ||
587 | if (items_num > MAX_MENU_ITEMS-1) | 532 | if (items_num > MAX_MENU_ITEMS-1) |
588 | return; | 533 | return; |
@@ -597,16 +542,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...) | |||
597 | k_menu_items[items_num].is_visible = 1; | 542 | k_menu_items[items_num].is_visible = 1; |
598 | 543 | ||
599 | va_start(ap, fmt); | 544 | va_start(ap, fmt); |
600 | vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); | 545 | vsnprintf(k_menu_items[items_num].str, |
601 | if (!k_menu_items[items_num].is_visible) | 546 | sizeof(k_menu_items[items_num].str), |
602 | memcpy(tmp_str, "XXX", 3); | 547 | fmt, ap); |
603 | va_end(ap); | 548 | va_end(ap); |
604 | if (make_hot( | 549 | |
605 | k_menu_items[items_num].str, | 550 | if (!k_menu_items[items_num].is_visible) |
606 | sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) | 551 | memcpy(k_menu_items[items_num].str, "XXX", 3); |
607 | strncpy(k_menu_items[items_num].str, | ||
608 | tmp_str, | ||
609 | sizeof(k_menu_items[items_num].str)); | ||
610 | 552 | ||
611 | curses_menu_items[items_num] = new_item( | 553 | curses_menu_items[items_num] = new_item( |
612 | k_menu_items[items_num].str, | 554 | k_menu_items[items_num].str, |
@@ -638,11 +580,9 @@ static void item_add_str(const char *fmt, ...) | |||
638 | va_end(ap); | 580 | va_end(ap); |
639 | snprintf(tmp_str, sizeof(tmp_str), "%s%s", | 581 | snprintf(tmp_str, sizeof(tmp_str), "%s%s", |
640 | k_menu_items[index].str, new_str); | 582 | k_menu_items[index].str, new_str); |
641 | if (make_hot(k_menu_items[index].str, | 583 | strncpy(k_menu_items[index].str, |
642 | sizeof(k_menu_items[index].str), tmp_str, index) != 0) | 584 | tmp_str, |
643 | strncpy(k_menu_items[index].str, | 585 | sizeof(k_menu_items[index].str)); |
644 | tmp_str, | ||
645 | sizeof(k_menu_items[index].str)); | ||
646 | 586 | ||
647 | free_item(curses_menu_items[index]); | 587 | free_item(curses_menu_items[index]); |
648 | curses_menu_items[index] = new_item( | 588 | curses_menu_items[index] = new_item( |
@@ -676,6 +616,8 @@ static void *item_data(void) | |||
676 | struct mitem *mcur; | 616 | struct mitem *mcur; |
677 | 617 | ||
678 | cur = current_item(curses_menu); | 618 | cur = current_item(curses_menu); |
619 | if (!cur) | ||
620 | return NULL; | ||
679 | mcur = (struct mitem *) item_userptr(cur); | 621 | mcur = (struct mitem *) item_userptr(cur); |
680 | return mcur->usrptr; | 622 | return mcur->usrptr; |
681 | 623 | ||
@@ -691,13 +633,9 @@ static char menu_backtitle[PATH_MAX+128]; | |||
691 | static const char *set_config_filename(const char *config_filename) | 633 | static const char *set_config_filename(const char *config_filename) |
692 | { | 634 | { |
693 | int size; | 635 | int size; |
694 | struct symbol *sym; | ||
695 | 636 | ||
696 | sym = sym_lookup("KERNELVERSION", 0); | ||
697 | sym_calc_value(sym); | ||
698 | size = snprintf(menu_backtitle, sizeof(menu_backtitle), | 637 | size = snprintf(menu_backtitle, sizeof(menu_backtitle), |
699 | _("%s - Linux Kernel v%s Configuration"), | 638 | "%s - %s", config_filename, rootmenu.prompt->text); |
700 | config_filename, sym_get_string_value(sym)); | ||
701 | if (size >= sizeof(menu_backtitle)) | 639 | if (size >= sizeof(menu_backtitle)) |
702 | menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; | 640 | menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; |
703 | 641 | ||
@@ -707,25 +645,6 @@ static const char *set_config_filename(const char *config_filename) | |||
707 | return menu_backtitle; | 645 | return menu_backtitle; |
708 | } | 646 | } |
709 | 647 | ||
710 | /* command = 0 is supress, 1 is restore */ | ||
711 | static void supress_stdout(int command) | ||
712 | { | ||
713 | static FILE *org_stdout; | ||
714 | static FILE *org_stderr; | ||
715 | |||
716 | if (command == 0) { | ||
717 | org_stdout = stdout; | ||
718 | org_stderr = stderr; | ||
719 | stdout = fopen("/dev/null", "a"); | ||
720 | stderr = fopen("/dev/null", "a"); | ||
721 | } else { | ||
722 | fclose(stdout); | ||
723 | fclose(stderr); | ||
724 | stdout = org_stdout; | ||
725 | stderr = org_stderr; | ||
726 | } | ||
727 | } | ||
728 | |||
729 | /* return = 0 means we are successful. | 648 | /* return = 0 means we are successful. |
730 | * -1 means go on doing what you were doing | 649 | * -1 means go on doing what you were doing |
731 | */ | 650 | */ |
@@ -737,8 +656,7 @@ static int do_exit(void) | |||
737 | return 0; | 656 | return 0; |
738 | } | 657 | } |
739 | res = btn_dialog(main_window, | 658 | res = btn_dialog(main_window, |
740 | _("Do you wish to save your " | 659 | _("Do you wish to save your new configuration?\n" |
741 | "new kernel configuration?\n" | ||
742 | "<ESC> to cancel and resume nconfig."), | 660 | "<ESC> to cancel and resume nconfig."), |
743 | 2, | 661 | 2, |
744 | " <save> ", | 662 | " <save> ", |
@@ -751,36 +669,19 @@ static int do_exit(void) | |||
751 | /* if we got here, the user really wants to exit */ | 669 | /* if we got here, the user really wants to exit */ |
752 | switch (res) { | 670 | switch (res) { |
753 | case 0: | 671 | case 0: |
754 | supress_stdout(0); | ||
755 | res = conf_write(filename); | 672 | res = conf_write(filename); |
756 | supress_stdout(1); | ||
757 | if (res) | 673 | if (res) |
758 | btn_dialog( | 674 | btn_dialog( |
759 | main_window, | 675 | main_window, |
760 | _("Error during writing of the kernel " | 676 | _("Error during writing of configuration.\n" |
761 | "configuration.\n" | 677 | "Your configuration changes were NOT saved."), |
762 | "Your kernel configuration " | ||
763 | "changes were NOT saved."), | ||
764 | 1, | 678 | 1, |
765 | "<OK>"); | 679 | "<OK>"); |
766 | else { | ||
767 | char buf[1024]; | ||
768 | snprintf(buf, 1024, | ||
769 | _("Configuration written to %s\n" | ||
770 | "End of Linux kernel configuration.\n" | ||
771 | "Execute 'make' to build the kernel or try" | ||
772 | " 'make help'."), filename); | ||
773 | btn_dialog( | ||
774 | main_window, | ||
775 | buf, | ||
776 | 1, | ||
777 | "<OK>"); | ||
778 | } | ||
779 | break; | 680 | break; |
780 | default: | 681 | default: |
781 | btn_dialog( | 682 | btn_dialog( |
782 | main_window, | 683 | main_window, |
783 | _("Your kernel configuration changes were NOT saved."), | 684 | _("Your configuration changes were NOT saved."), |
784 | 1, | 685 | 1, |
785 | "<OK>"); | 686 | "<OK>"); |
786 | break; | 687 | break; |
@@ -800,8 +701,8 @@ static void search_conf(void) | |||
800 | again: | 701 | again: |
801 | dres = dialog_inputbox(main_window, | 702 | dres = dialog_inputbox(main_window, |
802 | _("Search Configuration Parameter"), | 703 | _("Search Configuration Parameter"), |
803 | _("Enter CONFIG_ (sub)string to search for " | 704 | _("Enter " CONFIG_ " (sub)string to search for " |
804 | "(with or without \"CONFIG\")"), | 705 | "(with or without \"" CONFIG_ "\")"), |
805 | "", dialog_input_result, 99); | 706 | "", dialog_input_result, 99); |
806 | switch (dres) { | 707 | switch (dres) { |
807 | case 0: | 708 | case 0: |
@@ -814,10 +715,10 @@ again: | |||
814 | return; | 715 | return; |
815 | } | 716 | } |
816 | 717 | ||
817 | /* strip CONFIG_ if necessary */ | 718 | /* strip the prefix if necessary */ |
818 | dialog_input = dialog_input_result; | 719 | dialog_input = dialog_input_result; |
819 | if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) | 720 | if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) |
820 | dialog_input += 7; | 721 | dialog_input += strlen(CONFIG_); |
821 | 722 | ||
822 | sym_arr = sym_re_search(dialog_input); | 723 | sym_arr = sym_re_search(dialog_input); |
823 | res = get_relations_str(sym_arr); | 724 | res = get_relations_str(sym_arr); |
@@ -1025,23 +926,18 @@ static void reset_menu(void) | |||
1025 | static void center_item(int selected_index, int *last_top_row) | 926 | static void center_item(int selected_index, int *last_top_row) |
1026 | { | 927 | { |
1027 | int toprow; | 928 | int toprow; |
1028 | int maxy, maxx; | ||
1029 | 929 | ||
1030 | scale_menu(curses_menu, &maxy, &maxx); | ||
1031 | set_top_row(curses_menu, *last_top_row); | 930 | set_top_row(curses_menu, *last_top_row); |
1032 | toprow = top_row(curses_menu); | 931 | toprow = top_row(curses_menu); |
1033 | if (selected_index >= toprow && selected_index < toprow+maxy) { | 932 | if (selected_index < toprow || |
1034 | /* we can only move the selected item. no need to scroll */ | 933 | selected_index >= toprow+mwin_max_lines) { |
1035 | set_current_item(curses_menu, | 934 | toprow = max(selected_index-mwin_max_lines/2, 0); |
1036 | curses_menu_items[selected_index]); | 935 | if (toprow >= item_count(curses_menu)-mwin_max_lines) |
1037 | } else { | ||
1038 | toprow = max(selected_index-maxy/2, 0); | ||
1039 | if (toprow >= item_count(curses_menu)-maxy) | ||
1040 | toprow = item_count(curses_menu)-mwin_max_lines; | 936 | toprow = item_count(curses_menu)-mwin_max_lines; |
1041 | set_top_row(curses_menu, toprow); | 937 | set_top_row(curses_menu, toprow); |
1042 | set_current_item(curses_menu, | ||
1043 | curses_menu_items[selected_index]); | ||
1044 | } | 938 | } |
939 | set_current_item(curses_menu, | ||
940 | curses_menu_items[selected_index]); | ||
1045 | *last_top_row = toprow; | 941 | *last_top_row = toprow; |
1046 | post_menu(curses_menu); | 942 | post_menu(curses_menu); |
1047 | refresh_all_windows(main_window); | 943 | refresh_all_windows(main_window); |
@@ -1073,7 +969,7 @@ static void show_menu(const char *prompt, const char *instructions, | |||
1073 | /* position the menu at the middle of the screen */ | 969 | /* position the menu at the middle of the screen */ |
1074 | scale_menu(curses_menu, &maxy, &maxx); | 970 | scale_menu(curses_menu, &maxy, &maxx); |
1075 | maxx = min(maxx, mwin_max_cols-2); | 971 | maxx = min(maxx, mwin_max_cols-2); |
1076 | maxy = mwin_max_lines-2; | 972 | maxy = mwin_max_lines; |
1077 | menu_window = derwin(main_window, | 973 | menu_window = derwin(main_window, |
1078 | maxy, | 974 | maxy, |
1079 | maxx, | 975 | maxx, |
@@ -1097,10 +993,77 @@ static void show_menu(const char *prompt, const char *instructions, | |||
1097 | refresh_all_windows(main_window); | 993 | refresh_all_windows(main_window); |
1098 | } | 994 | } |
1099 | 995 | ||
996 | static void adj_match_dir(match_f *match_direction) | ||
997 | { | ||
998 | if (*match_direction == FIND_NEXT_MATCH_DOWN) | ||
999 | *match_direction = | ||
1000 | MATCH_TINKER_PATTERN_DOWN; | ||
1001 | else if (*match_direction == FIND_NEXT_MATCH_UP) | ||
1002 | *match_direction = | ||
1003 | MATCH_TINKER_PATTERN_UP; | ||
1004 | /* else, do no change.. */ | ||
1005 | } | ||
1100 | 1006 | ||
1101 | static void conf(struct menu *menu) | 1007 | struct match_state |
1102 | { | 1008 | { |
1009 | int in_search; | ||
1010 | match_f match_direction; | ||
1103 | char pattern[256]; | 1011 | char pattern[256]; |
1012 | }; | ||
1013 | |||
1014 | /* Return 0 means I have handled the key. In such a case, ans should hold the | ||
1015 | * item to center, or -1 otherwise. | ||
1016 | * Else return -1 . | ||
1017 | */ | ||
1018 | static int do_match(int key, struct match_state *state, int *ans) | ||
1019 | { | ||
1020 | char c = (char) key; | ||
1021 | int terminate_search = 0; | ||
1022 | *ans = -1; | ||
1023 | if (key == '/' || (state->in_search && key == 27)) { | ||
1024 | move(0, 0); | ||
1025 | refresh(); | ||
1026 | clrtoeol(); | ||
1027 | state->in_search = 1-state->in_search; | ||
1028 | bzero(state->pattern, sizeof(state->pattern)); | ||
1029 | state->match_direction = MATCH_TINKER_PATTERN_DOWN; | ||
1030 | return 0; | ||
1031 | } else if (!state->in_search) | ||
1032 | return 1; | ||
1033 | |||
1034 | if (isalnum(c) || isgraph(c) || c == ' ') { | ||
1035 | state->pattern[strlen(state->pattern)] = c; | ||
1036 | state->pattern[strlen(state->pattern)] = '\0'; | ||
1037 | adj_match_dir(&state->match_direction); | ||
1038 | *ans = get_mext_match(state->pattern, | ||
1039 | state->match_direction); | ||
1040 | } else if (key == KEY_DOWN) { | ||
1041 | state->match_direction = FIND_NEXT_MATCH_DOWN; | ||
1042 | *ans = get_mext_match(state->pattern, | ||
1043 | state->match_direction); | ||
1044 | } else if (key == KEY_UP) { | ||
1045 | state->match_direction = FIND_NEXT_MATCH_UP; | ||
1046 | *ans = get_mext_match(state->pattern, | ||
1047 | state->match_direction); | ||
1048 | } else if (key == KEY_BACKSPACE || key == 127) { | ||
1049 | state->pattern[strlen(state->pattern)-1] = '\0'; | ||
1050 | adj_match_dir(&state->match_direction); | ||
1051 | } else | ||
1052 | terminate_search = 1; | ||
1053 | |||
1054 | if (terminate_search) { | ||
1055 | state->in_search = 0; | ||
1056 | bzero(state->pattern, sizeof(state->pattern)); | ||
1057 | move(0, 0); | ||
1058 | refresh(); | ||
1059 | clrtoeol(); | ||
1060 | return -1; | ||
1061 | } | ||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | static void conf(struct menu *menu) | ||
1066 | { | ||
1104 | struct menu *submenu = 0; | 1067 | struct menu *submenu = 0; |
1105 | const char *prompt = menu_get_prompt(menu); | 1068 | const char *prompt = menu_get_prompt(menu); |
1106 | struct symbol *sym; | 1069 | struct symbol *sym; |
@@ -1108,8 +1071,11 @@ static void conf(struct menu *menu) | |||
1108 | int res; | 1071 | int res; |
1109 | int current_index = 0; | 1072 | int current_index = 0; |
1110 | int last_top_row = 0; | 1073 | int last_top_row = 0; |
1111 | 1074 | struct match_state match_state = { | |
1112 | bzero(pattern, sizeof(pattern)); | 1075 | .in_search = 0, |
1076 | .match_direction = MATCH_TINKER_PATTERN_DOWN, | ||
1077 | .pattern = "", | ||
1078 | }; | ||
1113 | 1079 | ||
1114 | while (!global_exit) { | 1080 | while (!global_exit) { |
1115 | reset_menu(); | 1081 | reset_menu(); |
@@ -1122,7 +1088,22 @@ static void conf(struct menu *menu) | |||
1122 | _(menu_instructions), | 1088 | _(menu_instructions), |
1123 | current_index, &last_top_row); | 1089 | current_index, &last_top_row); |
1124 | keypad((menu_win(curses_menu)), TRUE); | 1090 | keypad((menu_win(curses_menu)), TRUE); |
1125 | while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { | 1091 | while (!global_exit) { |
1092 | if (match_state.in_search) { | ||
1093 | mvprintw(0, 0, | ||
1094 | "searching: %s", match_state.pattern); | ||
1095 | clrtoeol(); | ||
1096 | } | ||
1097 | refresh_all_windows(main_window); | ||
1098 | res = wgetch(menu_win(curses_menu)); | ||
1099 | if (!res) | ||
1100 | break; | ||
1101 | if (do_match(res, &match_state, ¤t_index) == 0) { | ||
1102 | if (current_index != -1) | ||
1103 | center_item(current_index, | ||
1104 | &last_top_row); | ||
1105 | continue; | ||
1106 | } | ||
1126 | if (process_special_keys(&res, | 1107 | if (process_special_keys(&res, |
1127 | (struct menu *) item_data())) | 1108 | (struct menu *) item_data())) |
1128 | break; | 1109 | break; |
@@ -1153,19 +1134,13 @@ static void conf(struct menu *menu) | |||
1153 | if (res == 10 || res == 27 || | 1134 | if (res == 10 || res == 27 || |
1154 | res == 32 || res == 'n' || res == 'y' || | 1135 | res == 32 || res == 'n' || res == 'y' || |
1155 | res == KEY_LEFT || res == KEY_RIGHT || | 1136 | res == KEY_LEFT || res == KEY_RIGHT || |
1156 | res == 'm' || res == '/') | 1137 | res == 'm') |
1157 | break; | 1138 | break; |
1158 | else if (canbhot(res)) { | ||
1159 | /* check for hot keys: */ | ||
1160 | int tmp = get_next_hot(res); | ||
1161 | if (tmp != -1) | ||
1162 | center_item(tmp, &last_top_row); | ||
1163 | } | ||
1164 | refresh_all_windows(main_window); | 1139 | refresh_all_windows(main_window); |
1165 | } | 1140 | } |
1166 | 1141 | ||
1167 | refresh_all_windows(main_window); | 1142 | refresh_all_windows(main_window); |
1168 | /* if ESC or left*/ | 1143 | /* if ESC or left*/ |
1169 | if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) | 1144 | if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) |
1170 | break; | 1145 | break; |
1171 | 1146 | ||
@@ -1233,23 +1208,30 @@ static void conf(struct menu *menu) | |||
1233 | if (item_is_tag('t')) | 1208 | if (item_is_tag('t')) |
1234 | sym_set_tristate_value(sym, mod); | 1209 | sym_set_tristate_value(sym, mod); |
1235 | break; | 1210 | break; |
1236 | case '/': | ||
1237 | search_conf(); | ||
1238 | break; | ||
1239 | } | 1211 | } |
1240 | } | 1212 | } |
1241 | } | 1213 | } |
1242 | 1214 | ||
1215 | static void conf_message_callback(const char *fmt, va_list ap) | ||
1216 | { | ||
1217 | char buf[1024]; | ||
1218 | |||
1219 | vsnprintf(buf, sizeof(buf), fmt, ap); | ||
1220 | btn_dialog(main_window, buf, 1, "<OK>"); | ||
1221 | } | ||
1222 | |||
1243 | static void show_help(struct menu *menu) | 1223 | static void show_help(struct menu *menu) |
1244 | { | 1224 | { |
1245 | struct gstr help = str_new(); | 1225 | struct gstr help = str_new(); |
1246 | 1226 | ||
1247 | if (menu && menu->sym && menu_has_help(menu)) { | 1227 | if (menu && menu->sym && menu_has_help(menu)) { |
1248 | if (menu->sym->name) { | 1228 | if (menu->sym->name) { |
1249 | str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name); | 1229 | str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name); |
1250 | str_append(&help, _(menu_get_help(menu))); | 1230 | str_append(&help, _(menu_get_help(menu))); |
1251 | str_append(&help, "\n"); | 1231 | str_append(&help, "\n"); |
1252 | get_symbol_str(&help, menu->sym); | 1232 | get_symbol_str(&help, menu->sym); |
1233 | } else { | ||
1234 | str_append(&help, _(menu_get_help(menu))); | ||
1253 | } | 1235 | } |
1254 | } else { | 1236 | } else { |
1255 | str_append(&help, nohelp_text); | 1237 | str_append(&help, nohelp_text); |
@@ -1266,6 +1248,11 @@ static void conf_choice(struct menu *menu) | |||
1266 | int selected_index = 0; | 1248 | int selected_index = 0; |
1267 | int last_top_row = 0; | 1249 | int last_top_row = 0; |
1268 | int res, i = 0; | 1250 | int res, i = 0; |
1251 | struct match_state match_state = { | ||
1252 | .in_search = 0, | ||
1253 | .match_direction = MATCH_TINKER_PATTERN_DOWN, | ||
1254 | .pattern = "", | ||
1255 | }; | ||
1269 | 1256 | ||
1270 | active = sym_get_choice_value(menu->sym); | 1257 | active = sym_get_choice_value(menu->sym); |
1271 | /* this is mostly duplicated from the conf() function. */ | 1258 | /* this is mostly duplicated from the conf() function. */ |
@@ -1292,7 +1279,22 @@ static void conf_choice(struct menu *menu) | |||
1292 | _(radiolist_instructions), | 1279 | _(radiolist_instructions), |
1293 | selected_index, | 1280 | selected_index, |
1294 | &last_top_row); | 1281 | &last_top_row); |
1295 | while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { | 1282 | while (!global_exit) { |
1283 | if (match_state.in_search) { | ||
1284 | mvprintw(0, 0, "searching: %s", | ||
1285 | match_state.pattern); | ||
1286 | clrtoeol(); | ||
1287 | } | ||
1288 | refresh_all_windows(main_window); | ||
1289 | res = wgetch(menu_win(curses_menu)); | ||
1290 | if (!res) | ||
1291 | break; | ||
1292 | if (do_match(res, &match_state, &selected_index) == 0) { | ||
1293 | if (selected_index != -1) | ||
1294 | center_item(selected_index, | ||
1295 | &last_top_row); | ||
1296 | continue; | ||
1297 | } | ||
1296 | if (process_special_keys( | 1298 | if (process_special_keys( |
1297 | &res, | 1299 | &res, |
1298 | (struct menu *) item_data())) | 1300 | (struct menu *) item_data())) |
@@ -1322,13 +1324,8 @@ static void conf_choice(struct menu *menu) | |||
1322 | break; | 1324 | break; |
1323 | } | 1325 | } |
1324 | if (res == 10 || res == 27 || res == ' ' || | 1326 | if (res == 10 || res == 27 || res == ' ' || |
1325 | res == KEY_LEFT) | 1327 | res == KEY_LEFT){ |
1326 | break; | 1328 | break; |
1327 | else if (canbhot(res)) { | ||
1328 | /* check for hot keys: */ | ||
1329 | int tmp = get_next_hot(res); | ||
1330 | if (tmp != -1) | ||
1331 | center_item(tmp, &last_top_row); | ||
1332 | } | 1329 | } |
1333 | refresh_all_windows(main_window); | 1330 | refresh_all_windows(main_window); |
1334 | } | 1331 | } |
@@ -1447,16 +1444,8 @@ static void conf_save(void) | |||
1447 | case 0: | 1444 | case 0: |
1448 | if (!dialog_input_result[0]) | 1445 | if (!dialog_input_result[0]) |
1449 | return; | 1446 | return; |
1450 | supress_stdout(0); | ||
1451 | res = conf_write(dialog_input_result); | 1447 | res = conf_write(dialog_input_result); |
1452 | supress_stdout(1); | ||
1453 | if (!res) { | 1448 | if (!res) { |
1454 | char buf[1024]; | ||
1455 | sprintf(buf, "%s %s", | ||
1456 | _("configuration file saved to: "), | ||
1457 | dialog_input_result); | ||
1458 | btn_dialog(main_window, | ||
1459 | buf, 1, "<OK>"); | ||
1460 | set_config_filename(dialog_input_result); | 1449 | set_config_filename(dialog_input_result); |
1461 | return; | 1450 | return; |
1462 | } | 1451 | } |
@@ -1483,7 +1472,7 @@ void setup_windows(void) | |||
1483 | /* set up the menu and menu window */ | 1472 | /* set up the menu and menu window */ |
1484 | main_window = newwin(LINES-2, COLS-2, 2, 1); | 1473 | main_window = newwin(LINES-2, COLS-2, 2, 1); |
1485 | keypad(main_window, TRUE); | 1474 | keypad(main_window, TRUE); |
1486 | mwin_max_lines = LINES-6; | 1475 | mwin_max_lines = LINES-7; |
1487 | mwin_max_cols = COLS-6; | 1476 | mwin_max_cols = COLS-6; |
1488 | 1477 | ||
1489 | /* panels order is from bottom to top */ | 1478 | /* panels order is from bottom to top */ |
@@ -1530,9 +1519,10 @@ int main(int ac, char **av) | |||
1530 | /* set btns menu */ | 1519 | /* set btns menu */ |
1531 | curses_menu = new_menu(curses_menu_items); | 1520 | curses_menu = new_menu(curses_menu_items); |
1532 | menu_opts_off(curses_menu, O_SHOWDESC); | 1521 | menu_opts_off(curses_menu, O_SHOWDESC); |
1533 | menu_opts_off(curses_menu, O_SHOWMATCH); | 1522 | menu_opts_on(curses_menu, O_SHOWMATCH); |
1534 | menu_opts_on(curses_menu, O_ONEVALUE); | 1523 | menu_opts_on(curses_menu, O_ONEVALUE); |
1535 | menu_opts_on(curses_menu, O_NONCYCLIC); | 1524 | menu_opts_on(curses_menu, O_NONCYCLIC); |
1525 | menu_opts_on(curses_menu, O_IGNORECASE); | ||
1536 | set_menu_mark(curses_menu, " "); | 1526 | set_menu_mark(curses_menu, " "); |
1537 | set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); | 1527 | set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); |
1538 | set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); | 1528 | set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); |
@@ -1548,8 +1538,7 @@ int main(int ac, char **av) | |||
1548 | _(menu_no_f_instructions)); | 1538 | _(menu_no_f_instructions)); |
1549 | } | 1539 | } |
1550 | 1540 | ||
1551 | 1541 | conf_set_message_callback(conf_message_callback); | |
1552 | |||
1553 | /* do the work */ | 1542 | /* do the work */ |
1554 | while (!global_exit) { | 1543 | while (!global_exit) { |
1555 | conf(&rootmenu); | 1544 | conf(&rootmenu); |