diff options
Diffstat (limited to 'scripts/kconfig/nconf.c')
| -rw-r--r-- | scripts/kconfig/nconf.c | 487 |
1 files changed, 237 insertions, 250 deletions
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 2ba71bcd38e6..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( |
| @@ -693,13 +633,9 @@ static char menu_backtitle[PATH_MAX+128]; | |||
| 693 | static const char *set_config_filename(const char *config_filename) | 633 | static const char *set_config_filename(const char *config_filename) |
| 694 | { | 634 | { |
| 695 | int size; | 635 | int size; |
| 696 | struct symbol *sym; | ||
| 697 | 636 | ||
| 698 | sym = sym_lookup("KERNELVERSION", 0); | ||
| 699 | sym_calc_value(sym); | ||
| 700 | size = snprintf(menu_backtitle, sizeof(menu_backtitle), | 637 | size = snprintf(menu_backtitle, sizeof(menu_backtitle), |
| 701 | _("%s - Linux Kernel v%s Configuration"), | 638 | "%s - %s", config_filename, rootmenu.prompt->text); |
| 702 | config_filename, sym_get_string_value(sym)); | ||
| 703 | if (size >= sizeof(menu_backtitle)) | 639 | if (size >= sizeof(menu_backtitle)) |
| 704 | menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; | 640 | menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; |
| 705 | 641 | ||
| @@ -709,25 +645,6 @@ static const char *set_config_filename(const char *config_filename) | |||
| 709 | return menu_backtitle; | 645 | return menu_backtitle; |
| 710 | } | 646 | } |
| 711 | 647 | ||
| 712 | /* command = 0 is supress, 1 is restore */ | ||
| 713 | static void supress_stdout(int command) | ||
| 714 | { | ||
| 715 | static FILE *org_stdout; | ||
| 716 | static FILE *org_stderr; | ||
| 717 | |||
| 718 | if (command == 0) { | ||
| 719 | org_stdout = stdout; | ||
| 720 | org_stderr = stderr; | ||
| 721 | stdout = fopen("/dev/null", "a"); | ||
| 722 | stderr = fopen("/dev/null", "a"); | ||
| 723 | } else { | ||
| 724 | fclose(stdout); | ||
| 725 | fclose(stderr); | ||
| 726 | stdout = org_stdout; | ||
| 727 | stderr = org_stderr; | ||
| 728 | } | ||
| 729 | } | ||
| 730 | |||
| 731 | /* return = 0 means we are successful. | 648 | /* return = 0 means we are successful. |
| 732 | * -1 means go on doing what you were doing | 649 | * -1 means go on doing what you were doing |
| 733 | */ | 650 | */ |
| @@ -739,8 +656,7 @@ static int do_exit(void) | |||
| 739 | return 0; | 656 | return 0; |
| 740 | } | 657 | } |
| 741 | res = btn_dialog(main_window, | 658 | res = btn_dialog(main_window, |
| 742 | _("Do you wish to save your " | 659 | _("Do you wish to save your new configuration?\n" |
| 743 | "new kernel configuration?\n" | ||
| 744 | "<ESC> to cancel and resume nconfig."), | 660 | "<ESC> to cancel and resume nconfig."), |
| 745 | 2, | 661 | 2, |
| 746 | " <save> ", | 662 | " <save> ", |
| @@ -753,36 +669,19 @@ static int do_exit(void) | |||
| 753 | /* if we got here, the user really wants to exit */ | 669 | /* if we got here, the user really wants to exit */ |
| 754 | switch (res) { | 670 | switch (res) { |
| 755 | case 0: | 671 | case 0: |
| 756 | supress_stdout(0); | ||
| 757 | res = conf_write(filename); | 672 | res = conf_write(filename); |
| 758 | supress_stdout(1); | ||
| 759 | if (res) | 673 | if (res) |
| 760 | btn_dialog( | 674 | btn_dialog( |
| 761 | main_window, | 675 | main_window, |
| 762 | _("Error during writing of the kernel " | 676 | _("Error during writing of configuration.\n" |
| 763 | "configuration.\n" | 677 | "Your configuration changes were NOT saved."), |
| 764 | "Your kernel configuration " | ||
| 765 | "changes were NOT saved."), | ||
| 766 | 1, | 678 | 1, |
| 767 | "<OK>"); | 679 | "<OK>"); |
| 768 | else { | ||
| 769 | char buf[1024]; | ||
| 770 | snprintf(buf, 1024, | ||
| 771 | _("Configuration written to %s\n" | ||
| 772 | "End of Linux kernel configuration.\n" | ||
| 773 | "Execute 'make' to build the kernel or try" | ||
| 774 | " 'make help'."), filename); | ||
| 775 | btn_dialog( | ||
| 776 | main_window, | ||
| 777 | buf, | ||
| 778 | 1, | ||
| 779 | "<OK>"); | ||
| 780 | } | ||
| 781 | break; | 680 | break; |
| 782 | default: | 681 | default: |
| 783 | btn_dialog( | 682 | btn_dialog( |
| 784 | main_window, | 683 | main_window, |
| 785 | _("Your kernel configuration changes were NOT saved."), | 684 | _("Your configuration changes were NOT saved."), |
| 786 | 1, | 685 | 1, |
| 787 | "<OK>"); | 686 | "<OK>"); |
| 788 | break; | 687 | break; |
| @@ -802,8 +701,8 @@ static void search_conf(void) | |||
| 802 | again: | 701 | again: |
| 803 | dres = dialog_inputbox(main_window, | 702 | dres = dialog_inputbox(main_window, |
| 804 | _("Search Configuration Parameter"), | 703 | _("Search Configuration Parameter"), |
| 805 | _("Enter CONFIG_ (sub)string to search for " | 704 | _("Enter " CONFIG_ " (sub)string to search for " |
| 806 | "(with or without \"CONFIG\")"), | 705 | "(with or without \"" CONFIG_ "\")"), |
| 807 | "", dialog_input_result, 99); | 706 | "", dialog_input_result, 99); |
| 808 | switch (dres) { | 707 | switch (dres) { |
| 809 | case 0: | 708 | case 0: |
| @@ -816,10 +715,10 @@ again: | |||
| 816 | return; | 715 | return; |
| 817 | } | 716 | } |
| 818 | 717 | ||
| 819 | /* strip CONFIG_ if necessary */ | 718 | /* strip the prefix if necessary */ |
| 820 | dialog_input = dialog_input_result; | 719 | dialog_input = dialog_input_result; |
| 821 | if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) | 720 | if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) |
| 822 | dialog_input += 7; | 721 | dialog_input += strlen(CONFIG_); |
| 823 | 722 | ||
| 824 | sym_arr = sym_re_search(dialog_input); | 723 | sym_arr = sym_re_search(dialog_input); |
| 825 | res = get_relations_str(sym_arr); | 724 | res = get_relations_str(sym_arr); |
| @@ -1027,23 +926,18 @@ static void reset_menu(void) | |||
| 1027 | static void center_item(int selected_index, int *last_top_row) | 926 | static void center_item(int selected_index, int *last_top_row) |
| 1028 | { | 927 | { |
| 1029 | int toprow; | 928 | int toprow; |
| 1030 | int maxy, maxx; | ||
| 1031 | 929 | ||
| 1032 | scale_menu(curses_menu, &maxy, &maxx); | ||
| 1033 | set_top_row(curses_menu, *last_top_row); | 930 | set_top_row(curses_menu, *last_top_row); |
| 1034 | toprow = top_row(curses_menu); | 931 | toprow = top_row(curses_menu); |
| 1035 | if (selected_index >= toprow && selected_index < toprow+maxy) { | 932 | if (selected_index < toprow || |
| 1036 | /* we can only move the selected item. no need to scroll */ | 933 | selected_index >= toprow+mwin_max_lines) { |
| 1037 | set_current_item(curses_menu, | 934 | toprow = max(selected_index-mwin_max_lines/2, 0); |
| 1038 | curses_menu_items[selected_index]); | 935 | if (toprow >= item_count(curses_menu)-mwin_max_lines) |
| 1039 | } else { | ||
| 1040 | toprow = max(selected_index-maxy/2, 0); | ||
| 1041 | if (toprow >= item_count(curses_menu)-maxy) | ||
| 1042 | toprow = item_count(curses_menu)-mwin_max_lines; | 936 | toprow = item_count(curses_menu)-mwin_max_lines; |
| 1043 | set_top_row(curses_menu, toprow); | 937 | set_top_row(curses_menu, toprow); |
| 1044 | set_current_item(curses_menu, | ||
| 1045 | curses_menu_items[selected_index]); | ||
| 1046 | } | 938 | } |
| 939 | set_current_item(curses_menu, | ||
| 940 | curses_menu_items[selected_index]); | ||
| 1047 | *last_top_row = toprow; | 941 | *last_top_row = toprow; |
| 1048 | post_menu(curses_menu); | 942 | post_menu(curses_menu); |
| 1049 | refresh_all_windows(main_window); | 943 | refresh_all_windows(main_window); |
| @@ -1075,7 +969,7 @@ static void show_menu(const char *prompt, const char *instructions, | |||
| 1075 | /* position the menu at the middle of the screen */ | 969 | /* position the menu at the middle of the screen */ |
| 1076 | scale_menu(curses_menu, &maxy, &maxx); | 970 | scale_menu(curses_menu, &maxy, &maxx); |
| 1077 | maxx = min(maxx, mwin_max_cols-2); | 971 | maxx = min(maxx, mwin_max_cols-2); |
| 1078 | maxy = mwin_max_lines-2; | 972 | maxy = mwin_max_lines; |
| 1079 | menu_window = derwin(main_window, | 973 | menu_window = derwin(main_window, |
| 1080 | maxy, | 974 | maxy, |
| 1081 | maxx, | 975 | maxx, |
| @@ -1099,10 +993,77 @@ static void show_menu(const char *prompt, const char *instructions, | |||
| 1099 | refresh_all_windows(main_window); | 993 | refresh_all_windows(main_window); |
| 1100 | } | 994 | } |
| 1101 | 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 | } | ||
| 1102 | 1006 | ||
| 1103 | static void conf(struct menu *menu) | 1007 | struct match_state |
| 1104 | { | 1008 | { |
| 1009 | int in_search; | ||
| 1010 | match_f match_direction; | ||
| 1105 | 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 | { | ||
| 1106 | struct menu *submenu = 0; | 1067 | struct menu *submenu = 0; |
| 1107 | const char *prompt = menu_get_prompt(menu); | 1068 | const char *prompt = menu_get_prompt(menu); |
| 1108 | struct symbol *sym; | 1069 | struct symbol *sym; |
| @@ -1110,8 +1071,11 @@ static void conf(struct menu *menu) | |||
| 1110 | int res; | 1071 | int res; |
| 1111 | int current_index = 0; | 1072 | int current_index = 0; |
| 1112 | int last_top_row = 0; | 1073 | int last_top_row = 0; |
| 1113 | 1074 | struct match_state match_state = { | |
| 1114 | bzero(pattern, sizeof(pattern)); | 1075 | .in_search = 0, |
| 1076 | .match_direction = MATCH_TINKER_PATTERN_DOWN, | ||
| 1077 | .pattern = "", | ||
| 1078 | }; | ||
| 1115 | 1079 | ||
| 1116 | while (!global_exit) { | 1080 | while (!global_exit) { |
| 1117 | reset_menu(); | 1081 | reset_menu(); |
| @@ -1124,7 +1088,22 @@ static void conf(struct menu *menu) | |||
| 1124 | _(menu_instructions), | 1088 | _(menu_instructions), |
| 1125 | current_index, &last_top_row); | 1089 | current_index, &last_top_row); |
| 1126 | keypad((menu_win(curses_menu)), TRUE); | 1090 | keypad((menu_win(curses_menu)), TRUE); |
| 1127 | 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 | } | ||
| 1128 | if (process_special_keys(&res, | 1107 | if (process_special_keys(&res, |
| 1129 | (struct menu *) item_data())) | 1108 | (struct menu *) item_data())) |
| 1130 | break; | 1109 | break; |
| @@ -1155,19 +1134,13 @@ static void conf(struct menu *menu) | |||
| 1155 | if (res == 10 || res == 27 || | 1134 | if (res == 10 || res == 27 || |
| 1156 | res == 32 || res == 'n' || res == 'y' || | 1135 | res == 32 || res == 'n' || res == 'y' || |
| 1157 | res == KEY_LEFT || res == KEY_RIGHT || | 1136 | res == KEY_LEFT || res == KEY_RIGHT || |
| 1158 | res == 'm' || res == '/') | 1137 | res == 'm') |
| 1159 | break; | 1138 | break; |
| 1160 | else if (canbhot(res)) { | ||
| 1161 | /* check for hot keys: */ | ||
| 1162 | int tmp = get_next_hot(res); | ||
| 1163 | if (tmp != -1) | ||
| 1164 | center_item(tmp, &last_top_row); | ||
| 1165 | } | ||
| 1166 | refresh_all_windows(main_window); | 1139 | refresh_all_windows(main_window); |
| 1167 | } | 1140 | } |
| 1168 | 1141 | ||
| 1169 | refresh_all_windows(main_window); | 1142 | refresh_all_windows(main_window); |
| 1170 | /* if ESC or left*/ | 1143 | /* if ESC or left*/ |
| 1171 | if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) | 1144 | if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) |
| 1172 | break; | 1145 | break; |
| 1173 | 1146 | ||
| @@ -1235,23 +1208,30 @@ static void conf(struct menu *menu) | |||
| 1235 | if (item_is_tag('t')) | 1208 | if (item_is_tag('t')) |
| 1236 | sym_set_tristate_value(sym, mod); | 1209 | sym_set_tristate_value(sym, mod); |
| 1237 | break; | 1210 | break; |
| 1238 | case '/': | ||
| 1239 | search_conf(); | ||
| 1240 | break; | ||
| 1241 | } | 1211 | } |
| 1242 | } | 1212 | } |
| 1243 | } | 1213 | } |
| 1244 | 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 | |||
| 1245 | static void show_help(struct menu *menu) | 1223 | static void show_help(struct menu *menu) |
| 1246 | { | 1224 | { |
| 1247 | struct gstr help = str_new(); | 1225 | struct gstr help = str_new(); |
| 1248 | 1226 | ||
| 1249 | if (menu && menu->sym && menu_has_help(menu)) { | 1227 | if (menu && menu->sym && menu_has_help(menu)) { |
| 1250 | if (menu->sym->name) { | 1228 | if (menu->sym->name) { |
| 1251 | str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name); | 1229 | str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name); |
| 1252 | str_append(&help, _(menu_get_help(menu))); | 1230 | str_append(&help, _(menu_get_help(menu))); |
| 1253 | str_append(&help, "\n"); | 1231 | str_append(&help, "\n"); |
| 1254 | get_symbol_str(&help, menu->sym); | 1232 | get_symbol_str(&help, menu->sym); |
| 1233 | } else { | ||
| 1234 | str_append(&help, _(menu_get_help(menu))); | ||
| 1255 | } | 1235 | } |
| 1256 | } else { | 1236 | } else { |
| 1257 | str_append(&help, nohelp_text); | 1237 | str_append(&help, nohelp_text); |
| @@ -1268,6 +1248,11 @@ static void conf_choice(struct menu *menu) | |||
| 1268 | int selected_index = 0; | 1248 | int selected_index = 0; |
| 1269 | int last_top_row = 0; | 1249 | int last_top_row = 0; |
| 1270 | 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 | }; | ||
| 1271 | 1256 | ||
| 1272 | active = sym_get_choice_value(menu->sym); | 1257 | active = sym_get_choice_value(menu->sym); |
| 1273 | /* this is mostly duplicated from the conf() function. */ | 1258 | /* this is mostly duplicated from the conf() function. */ |
| @@ -1294,7 +1279,22 @@ static void conf_choice(struct menu *menu) | |||
| 1294 | _(radiolist_instructions), | 1279 | _(radiolist_instructions), |
| 1295 | selected_index, | 1280 | selected_index, |
| 1296 | &last_top_row); | 1281 | &last_top_row); |
| 1297 | 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 | } | ||
| 1298 | if (process_special_keys( | 1298 | if (process_special_keys( |
| 1299 | &res, | 1299 | &res, |
| 1300 | (struct menu *) item_data())) | 1300 | (struct menu *) item_data())) |
| @@ -1324,13 +1324,8 @@ static void conf_choice(struct menu *menu) | |||
| 1324 | break; | 1324 | break; |
| 1325 | } | 1325 | } |
| 1326 | if (res == 10 || res == 27 || res == ' ' || | 1326 | if (res == 10 || res == 27 || res == ' ' || |
| 1327 | res == KEY_LEFT) | 1327 | res == KEY_LEFT){ |
| 1328 | break; | 1328 | break; |
| 1329 | else if (canbhot(res)) { | ||
| 1330 | /* check for hot keys: */ | ||
| 1331 | int tmp = get_next_hot(res); | ||
| 1332 | if (tmp != -1) | ||
| 1333 | center_item(tmp, &last_top_row); | ||
| 1334 | } | 1329 | } |
| 1335 | refresh_all_windows(main_window); | 1330 | refresh_all_windows(main_window); |
| 1336 | } | 1331 | } |
| @@ -1449,16 +1444,8 @@ static void conf_save(void) | |||
| 1449 | case 0: | 1444 | case 0: |
| 1450 | if (!dialog_input_result[0]) | 1445 | if (!dialog_input_result[0]) |
| 1451 | return; | 1446 | return; |
| 1452 | supress_stdout(0); | ||
| 1453 | res = conf_write(dialog_input_result); | 1447 | res = conf_write(dialog_input_result); |
| 1454 | supress_stdout(1); | ||
| 1455 | if (!res) { | 1448 | if (!res) { |
| 1456 | char buf[1024]; | ||
| 1457 | sprintf(buf, "%s %s", | ||
| 1458 | _("configuration file saved to: "), | ||
| 1459 | dialog_input_result); | ||
| 1460 | btn_dialog(main_window, | ||
| 1461 | buf, 1, "<OK>"); | ||
| 1462 | set_config_filename(dialog_input_result); | 1449 | set_config_filename(dialog_input_result); |
| 1463 | return; | 1450 | return; |
| 1464 | } | 1451 | } |
| @@ -1485,7 +1472,7 @@ void setup_windows(void) | |||
| 1485 | /* set up the menu and menu window */ | 1472 | /* set up the menu and menu window */ |
| 1486 | main_window = newwin(LINES-2, COLS-2, 2, 1); | 1473 | main_window = newwin(LINES-2, COLS-2, 2, 1); |
| 1487 | keypad(main_window, TRUE); | 1474 | keypad(main_window, TRUE); |
| 1488 | mwin_max_lines = LINES-6; | 1475 | mwin_max_lines = LINES-7; |
| 1489 | mwin_max_cols = COLS-6; | 1476 | mwin_max_cols = COLS-6; |
| 1490 | 1477 | ||
| 1491 | /* panels order is from bottom to top */ | 1478 | /* panels order is from bottom to top */ |
| @@ -1532,9 +1519,10 @@ int main(int ac, char **av) | |||
| 1532 | /* set btns menu */ | 1519 | /* set btns menu */ |
| 1533 | curses_menu = new_menu(curses_menu_items); | 1520 | curses_menu = new_menu(curses_menu_items); |
| 1534 | menu_opts_off(curses_menu, O_SHOWDESC); | 1521 | menu_opts_off(curses_menu, O_SHOWDESC); |
| 1535 | menu_opts_off(curses_menu, O_SHOWMATCH); | 1522 | menu_opts_on(curses_menu, O_SHOWMATCH); |
| 1536 | menu_opts_on(curses_menu, O_ONEVALUE); | 1523 | menu_opts_on(curses_menu, O_ONEVALUE); |
| 1537 | menu_opts_on(curses_menu, O_NONCYCLIC); | 1524 | menu_opts_on(curses_menu, O_NONCYCLIC); |
| 1525 | menu_opts_on(curses_menu, O_IGNORECASE); | ||
| 1538 | set_menu_mark(curses_menu, " "); | 1526 | set_menu_mark(curses_menu, " "); |
| 1539 | set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); | 1527 | set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); |
| 1540 | set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); | 1528 | set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); |
| @@ -1550,8 +1538,7 @@ int main(int ac, char **av) | |||
| 1550 | _(menu_no_f_instructions)); | 1538 | _(menu_no_f_instructions)); |
| 1551 | } | 1539 | } |
| 1552 | 1540 | ||
| 1553 | 1541 | conf_set_message_callback(conf_message_callback); | |
| 1554 | |||
| 1555 | /* do the work */ | 1542 | /* do the work */ |
| 1556 | while (!global_exit) { | 1543 | while (!global_exit) { |
| 1557 | conf(&rootmenu); | 1544 | conf(&rootmenu); |
