diff options
| -rw-r--r-- | scripts/kconfig/nconf.c | 365 | ||||
| -rw-r--r-- | scripts/kconfig/nconf.gui.c | 20 | ||||
| -rw-r--r-- | scripts/kconfig/nconf.h | 3 |
3 files changed, 208 insertions, 180 deletions
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 2ba71bcd38e6..18a215de9f36 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c | |||
| @@ -5,9 +5,12 @@ | |||
| 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" |
| @@ -23,7 +26,7 @@ static const char nconf_readme[] = N_( | |||
| 23 | " < > can be built in, modularized or removed\n" | 26 | " < > can be built in, modularized or removed\n" |
| 24 | " { } can be built in or modularized (selected by other feature)\n" | 27 | " { } can be built in or modularized (selected by other feature)\n" |
| 25 | " - - are selected by other feature,\n" | 28 | " - - are selected by other feature,\n" |
| 26 | " XXX cannot be selected. use Symbol Info to find out why,\n" | 29 | " 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" | 30 | "while *, M or whitespace inside braces means to build in, build as\n" |
| 28 | "a module or to exclude the feature respectively.\n" | 31 | "a module or to exclude the feature respectively.\n" |
| 29 | "\n" | 32 | "\n" |
| @@ -41,9 +44,13 @@ static const char nconf_readme[] = N_( | |||
| 41 | " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" | 44 | " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" |
| 42 | " Submenus are designated by \"--->\".\n" | 45 | " Submenus are designated by \"--->\".\n" |
| 43 | "\n" | 46 | "\n" |
| 44 | " Shortcut: Press the option's highlighted letter (hotkey).\n" | 47 | " Searching: pressing '/' triggers interactive search mode.\n" |
| 45 | " Pressing a hotkey more than once will sequence\n" | 48 | " nconfig performs a case insensitive search for the string\n" |
| 46 | " through all visible items which use that hotkey.\n" | 49 | " in the menu prompts (no regex support).\n" |
| 50 | " Pressing the up/down keys highlights the previous/next\n" | ||
| 51 | " matching item. Backspace removes one character from the\n" | ||
| 52 | " match string. Pressing either '/' again or ESC exits\n" | ||
| 53 | " search mode. All other keys behave normally.\n" | ||
| 47 | "\n" | 54 | "\n" |
| 48 | " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" | 55 | " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" |
| 49 | " unseen options into view.\n" | 56 | " unseen options into view.\n" |
| @@ -141,21 +148,21 @@ menu_no_f_instructions[] = N_( | |||
| 141 | " <Enter> or <right-arrow> selects submenus --->.\n" | 148 | " <Enter> or <right-arrow> selects submenus --->.\n" |
| 142 | " Capital Letters are hotkeys.\n" | 149 | " Capital Letters are hotkeys.\n" |
| 143 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" | 150 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" |
| 144 | " Pressing SpaceBar toggles between the above options\n" | 151 | " Pressing SpaceBar toggles between the above options.\n" |
| 145 | " Press <Esc> or <left-arrow> to go back one menu, \n" | 152 | " Press <Esc> or <left-arrow> to go back one menu,\n" |
| 146 | " <?> or <h> for Help, </> for Search.\n" | 153 | " <?> or <h> for Help, </> for Search.\n" |
| 147 | " <1> is interchangable with <F1>, <2> with <F2>, etc.\n" | 154 | " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n" |
| 148 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" | 155 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" |
| 149 | " <Esc> always leaves the current window\n"), | 156 | " <Esc> always leaves the current window.\n"), |
| 150 | menu_instructions[] = N_( | 157 | menu_instructions[] = N_( |
| 151 | " Arrow keys navigate the menu.\n" | 158 | " Arrow keys navigate the menu.\n" |
| 152 | " <Enter> or <right-arrow> selects submenus --->.\n" | 159 | " <Enter> or <right-arrow> selects submenus --->.\n" |
| 153 | " Capital Letters are hotkeys.\n" | 160 | " Capital Letters are hotkeys.\n" |
| 154 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" | 161 | " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" |
| 155 | " Pressing SpaceBar toggles between the above options\n" | 162 | " Pressing SpaceBar toggles between the above options\n" |
| 156 | " Press <Esc>, <F3> or <left-arrow> to go back one menu, \n" | 163 | " Press <Esc>, <F5> or <left-arrow> to go back one menu,\n" |
| 157 | " <?>, <F1> or <h> for Help, </> for Search.\n" | 164 | " <?>, <F1> or <h> for Help, </> for Search.\n" |
| 158 | " <1> is interchangable with <F1>, <2> with <F2>, etc.\n" | 165 | " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n" |
| 159 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" | 166 | " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" |
| 160 | " <Esc> always leaves the current window\n"), | 167 | " <Esc> always leaves the current window\n"), |
| 161 | radiolist_instructions[] = N_( | 168 | radiolist_instructions[] = N_( |
| @@ -252,7 +259,6 @@ struct mitem { | |||
| 252 | char str[256]; | 259 | char str[256]; |
| 253 | char tag; | 260 | char tag; |
| 254 | void *usrptr; | 261 | void *usrptr; |
| 255 | int is_hot; | ||
| 256 | int is_visible; | 262 | int is_visible; |
| 257 | }; | 263 | }; |
| 258 | 264 | ||
| @@ -275,14 +281,6 @@ static int items_num; | |||
| 275 | static int global_exit; | 281 | static int global_exit; |
| 276 | /* the currently selected button */ | 282 | /* the currently selected button */ |
| 277 | const char *current_instructions = menu_instructions; | 283 | 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 | 284 | ||
| 287 | static void conf(struct menu *menu); | 285 | static void conf(struct menu *menu); |
| 288 | static void conf_choice(struct menu *menu); | 286 | static void conf_choice(struct menu *menu); |
| @@ -292,6 +290,7 @@ static void conf_save(void); | |||
| 292 | static void show_help(struct menu *menu); | 290 | static void show_help(struct menu *menu); |
| 293 | static int do_exit(void); | 291 | static int do_exit(void); |
| 294 | static void setup_windows(void); | 292 | static void setup_windows(void); |
| 293 | static void search_conf(void); | ||
| 295 | 294 | ||
| 296 | typedef void (*function_key_handler_t)(int *key, struct menu *menu); | 295 | typedef void (*function_key_handler_t)(int *key, struct menu *menu); |
| 297 | static void handle_f1(int *key, struct menu *current_item); | 296 | static void handle_f1(int *key, struct menu *current_item); |
| @@ -302,6 +301,7 @@ static void handle_f5(int *key, struct menu *current_item); | |||
| 302 | static void handle_f6(int *key, struct menu *current_item); | 301 | static void handle_f6(int *key, struct menu *current_item); |
| 303 | static void handle_f7(int *key, struct menu *current_item); | 302 | static void handle_f7(int *key, struct menu *current_item); |
| 304 | static void handle_f8(int *key, struct menu *current_item); | 303 | static void handle_f8(int *key, struct menu *current_item); |
| 304 | static void handle_f9(int *key, struct menu *current_item); | ||
| 305 | 305 | ||
| 306 | struct function_keys { | 306 | struct function_keys { |
| 307 | const char *key_str; | 307 | const char *key_str; |
| @@ -310,7 +310,7 @@ struct function_keys { | |||
| 310 | function_key_handler_t handler; | 310 | function_key_handler_t handler; |
| 311 | }; | 311 | }; |
| 312 | 312 | ||
| 313 | static const int function_keys_num = 8; | 313 | static const int function_keys_num = 9; |
| 314 | struct function_keys function_keys[] = { | 314 | struct function_keys function_keys[] = { |
| 315 | { | 315 | { |
| 316 | .key_str = "F1", | 316 | .key_str = "F1", |
| @@ -320,13 +320,13 @@ struct function_keys function_keys[] = { | |||
| 320 | }, | 320 | }, |
| 321 | { | 321 | { |
| 322 | .key_str = "F2", | 322 | .key_str = "F2", |
| 323 | .func = "Symbol Info", | 323 | .func = "Sym Info", |
| 324 | .key = F_SYMBOL, | 324 | .key = F_SYMBOL, |
| 325 | .handler = handle_f2, | 325 | .handler = handle_f2, |
| 326 | }, | 326 | }, |
| 327 | { | 327 | { |
| 328 | .key_str = "F3", | 328 | .key_str = "F3", |
| 329 | .func = "Instructions", | 329 | .func = "Insts", |
| 330 | .key = F_INSTS, | 330 | .key = F_INSTS, |
| 331 | .handler = handle_f3, | 331 | .handler = handle_f3, |
| 332 | }, | 332 | }, |
| @@ -356,9 +356,15 @@ struct function_keys function_keys[] = { | |||
| 356 | }, | 356 | }, |
| 357 | { | 357 | { |
| 358 | .key_str = "F8", | 358 | .key_str = "F8", |
| 359 | .func = "Sym Search", | ||
| 360 | .key = F_SEARCH, | ||
| 361 | .handler = handle_f8, | ||
| 362 | }, | ||
| 363 | { | ||
| 364 | .key_str = "F9", | ||
| 359 | .func = "Exit", | 365 | .func = "Exit", |
| 360 | .key = F_EXIT, | 366 | .key = F_EXIT, |
| 361 | .handler = handle_f8, | 367 | .handler = handle_f9, |
| 362 | }, | 368 | }, |
| 363 | }; | 369 | }; |
| 364 | 370 | ||
| @@ -444,9 +450,16 @@ static void handle_f7(int *key, struct menu *current_item) | |||
| 444 | return; | 450 | return; |
| 445 | } | 451 | } |
| 446 | 452 | ||
| 447 | /* exit */ | 453 | /* search */ |
| 448 | static void handle_f8(int *key, struct menu *current_item) | 454 | static void handle_f8(int *key, struct menu *current_item) |
| 449 | { | 455 | { |
| 456 | search_conf(); | ||
| 457 | return; | ||
| 458 | } | ||
| 459 | |||
| 460 | /* exit */ | ||
| 461 | static void handle_f9(int *key, struct menu *current_item) | ||
| 462 | { | ||
| 450 | do_exit(); | 463 | do_exit(); |
| 451 | return; | 464 | return; |
| 452 | } | 465 | } |
| @@ -479,110 +492,44 @@ static void clean_items(void) | |||
| 479 | free_item(curses_menu_items[i]); | 492 | free_item(curses_menu_items[i]); |
| 480 | bzero(curses_menu_items, sizeof(curses_menu_items)); | 493 | bzero(curses_menu_items, sizeof(curses_menu_items)); |
| 481 | bzero(k_menu_items, sizeof(k_menu_items)); | 494 | bzero(k_menu_items, sizeof(k_menu_items)); |
| 482 | bzero(hotkeys, sizeof(hotkeys)); | ||
| 483 | items_num = 0; | 495 | items_num = 0; |
| 484 | } | 496 | } |
| 485 | 497 | ||
| 486 | /* return the index of the next hot item, or -1 if no such item exists */ | 498 | typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, |
| 487 | static int get_next_hot(int c) | 499 | 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 | 500 | ||
| 519 | /* find the first possible hot key, and mark it. | 501 | /* 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 | 502 | 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 | { | 503 | { |
| 524 | int position = -1; | 504 | int match_start = item_index(current_item(curses_menu)); |
| 525 | int i; | 505 | int index; |
| 526 | int tmp; | 506 | |
| 527 | int c; | 507 | if (flag == FIND_NEXT_MATCH_DOWN) |
| 528 | int org_len = strlen(org); | 508 | ++match_start; |
| 529 | 509 | else if (flag == FIND_NEXT_MATCH_UP) | |
| 530 | if (org == NULL || is_hot(index)) | 510 | --match_start; |
| 531 | return 1; | 511 | |
| 532 | 512 | index = match_start; | |
| 533 | /* make sure not to make hot keys out of markers. | 513 | index = (index + items_num) % items_num; |
| 534 | * find where to start looking for a hot key | 514 | while (true) { |
| 535 | */ | 515 | char *str = k_menu_items[index].str; |
| 536 | i = 0; | 516 | if (strcasestr(str, match_str) != 0) |
| 537 | /* skip white space */ | 517 | return index; |
| 538 | while (i < org_len && org[i] == ' ') | 518 | if (flag == FIND_NEXT_MATCH_UP || |
| 539 | i++; | 519 | flag == MATCH_TINKER_PATTERN_UP) |
| 540 | if (i == org_len) | 520 | --index; |
| 541 | return -1; | 521 | else |
| 542 | /* if encountering '(' or '<' or '[', find the match and look from there | 522 | ++index; |
| 543 | **/ | 523 | index = (index + items_num) % items_num; |
| 544 | if (org[i] == '[' || org[i] == '<' || org[i] == '(') { | 524 | if (index == match_start) |
| 545 | i++; | 525 | 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 | } | 526 | } |
| 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 | } | 527 | } |
| 578 | 528 | ||
| 579 | /* Make a new item. Add a hotkey mark in the first possible letter. | 529 | /* 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, ...) | 530 | static void item_make(struct menu *menu, char tag, const char *fmt, ...) |
| 583 | { | 531 | { |
| 584 | va_list ap; | 532 | va_list ap; |
| 585 | char tmp_str[256]; | ||
| 586 | 533 | ||
| 587 | if (items_num > MAX_MENU_ITEMS-1) | 534 | if (items_num > MAX_MENU_ITEMS-1) |
| 588 | return; | 535 | return; |
| @@ -597,16 +544,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...) | |||
| 597 | k_menu_items[items_num].is_visible = 1; | 544 | k_menu_items[items_num].is_visible = 1; |
| 598 | 545 | ||
| 599 | va_start(ap, fmt); | 546 | va_start(ap, fmt); |
| 600 | vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); | 547 | vsnprintf(k_menu_items[items_num].str, |
| 601 | if (!k_menu_items[items_num].is_visible) | 548 | sizeof(k_menu_items[items_num].str), |
| 602 | memcpy(tmp_str, "XXX", 3); | 549 | fmt, ap); |
| 603 | va_end(ap); | 550 | va_end(ap); |
| 604 | if (make_hot( | 551 | |
| 605 | k_menu_items[items_num].str, | 552 | if (!k_menu_items[items_num].is_visible) |
| 606 | sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) | 553 | 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 | 554 | ||
| 611 | curses_menu_items[items_num] = new_item( | 555 | curses_menu_items[items_num] = new_item( |
| 612 | k_menu_items[items_num].str, | 556 | k_menu_items[items_num].str, |
| @@ -638,11 +582,9 @@ static void item_add_str(const char *fmt, ...) | |||
| 638 | va_end(ap); | 582 | va_end(ap); |
| 639 | snprintf(tmp_str, sizeof(tmp_str), "%s%s", | 583 | snprintf(tmp_str, sizeof(tmp_str), "%s%s", |
| 640 | k_menu_items[index].str, new_str); | 584 | k_menu_items[index].str, new_str); |
| 641 | if (make_hot(k_menu_items[index].str, | 585 | strncpy(k_menu_items[index].str, |
| 642 | sizeof(k_menu_items[index].str), tmp_str, index) != 0) | 586 | tmp_str, |
| 643 | strncpy(k_menu_items[index].str, | 587 | sizeof(k_menu_items[index].str)); |
| 644 | tmp_str, | ||
| 645 | sizeof(k_menu_items[index].str)); | ||
| 646 | 588 | ||
| 647 | free_item(curses_menu_items[index]); | 589 | free_item(curses_menu_items[index]); |
| 648 | curses_menu_items[index] = new_item( | 590 | curses_menu_items[index] = new_item( |
| @@ -1027,23 +969,18 @@ static void reset_menu(void) | |||
| 1027 | static void center_item(int selected_index, int *last_top_row) | 969 | static void center_item(int selected_index, int *last_top_row) |
| 1028 | { | 970 | { |
| 1029 | int toprow; | 971 | int toprow; |
| 1030 | int maxy, maxx; | ||
| 1031 | 972 | ||
| 1032 | scale_menu(curses_menu, &maxy, &maxx); | ||
| 1033 | set_top_row(curses_menu, *last_top_row); | 973 | set_top_row(curses_menu, *last_top_row); |
| 1034 | toprow = top_row(curses_menu); | 974 | toprow = top_row(curses_menu); |
| 1035 | if (selected_index >= toprow && selected_index < toprow+maxy) { | 975 | if (selected_index < toprow || |
| 1036 | /* we can only move the selected item. no need to scroll */ | 976 | selected_index >= toprow+mwin_max_lines) { |
| 1037 | set_current_item(curses_menu, | 977 | toprow = max(selected_index-mwin_max_lines/2, 0); |
| 1038 | curses_menu_items[selected_index]); | 978 | 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; | 979 | toprow = item_count(curses_menu)-mwin_max_lines; |
| 1043 | set_top_row(curses_menu, toprow); | 980 | set_top_row(curses_menu, toprow); |
| 1044 | set_current_item(curses_menu, | ||
| 1045 | curses_menu_items[selected_index]); | ||
| 1046 | } | 981 | } |
| 982 | set_current_item(curses_menu, | ||
| 983 | curses_menu_items[selected_index]); | ||
| 1047 | *last_top_row = toprow; | 984 | *last_top_row = toprow; |
| 1048 | post_menu(curses_menu); | 985 | post_menu(curses_menu); |
| 1049 | refresh_all_windows(main_window); | 986 | refresh_all_windows(main_window); |
| @@ -1075,7 +1012,7 @@ static void show_menu(const char *prompt, const char *instructions, | |||
| 1075 | /* position the menu at the middle of the screen */ | 1012 | /* position the menu at the middle of the screen */ |
| 1076 | scale_menu(curses_menu, &maxy, &maxx); | 1013 | scale_menu(curses_menu, &maxy, &maxx); |
| 1077 | maxx = min(maxx, mwin_max_cols-2); | 1014 | maxx = min(maxx, mwin_max_cols-2); |
| 1078 | maxy = mwin_max_lines-2; | 1015 | maxy = mwin_max_lines; |
| 1079 | menu_window = derwin(main_window, | 1016 | menu_window = derwin(main_window, |
| 1080 | maxy, | 1017 | maxy, |
| 1081 | maxx, | 1018 | maxx, |
| @@ -1099,10 +1036,77 @@ static void show_menu(const char *prompt, const char *instructions, | |||
| 1099 | refresh_all_windows(main_window); | 1036 | refresh_all_windows(main_window); |
| 1100 | } | 1037 | } |
| 1101 | 1038 | ||
| 1039 | static void adj_match_dir(match_f *match_direction) | ||
| 1040 | { | ||
| 1041 | if (*match_direction == FIND_NEXT_MATCH_DOWN) | ||
| 1042 | *match_direction = | ||
| 1043 | MATCH_TINKER_PATTERN_DOWN; | ||
| 1044 | else if (*match_direction == FIND_NEXT_MATCH_UP) | ||
| 1045 | *match_direction = | ||
| 1046 | MATCH_TINKER_PATTERN_UP; | ||
| 1047 | /* else, do no change.. */ | ||
| 1048 | } | ||
| 1102 | 1049 | ||
| 1103 | static void conf(struct menu *menu) | 1050 | struct match_state |
| 1104 | { | 1051 | { |
| 1052 | int in_search; | ||
| 1053 | match_f match_direction; | ||
| 1105 | char pattern[256]; | 1054 | char pattern[256]; |
| 1055 | }; | ||
| 1056 | |||
| 1057 | /* Return 0 means I have handled the key. In such a case, ans should hold the | ||
| 1058 | * item to center, or -1 otherwise. | ||
| 1059 | * Else return -1 . | ||
| 1060 | */ | ||
| 1061 | static int do_match(int key, struct match_state *state, int *ans) | ||
| 1062 | { | ||
| 1063 | char c = (char) key; | ||
| 1064 | int terminate_search = 0; | ||
| 1065 | *ans = -1; | ||
| 1066 | if (key == '/' || (state->in_search && key == 27)) { | ||
| 1067 | move(0, 0); | ||
| 1068 | refresh(); | ||
| 1069 | clrtoeol(); | ||
| 1070 | state->in_search = 1-state->in_search; | ||
| 1071 | bzero(state->pattern, sizeof(state->pattern)); | ||
| 1072 | state->match_direction = MATCH_TINKER_PATTERN_DOWN; | ||
| 1073 | return 0; | ||
| 1074 | } else if (!state->in_search) | ||
| 1075 | return 1; | ||
| 1076 | |||
| 1077 | if (isalnum(c) || isgraph(c) || c == ' ') { | ||
| 1078 | state->pattern[strlen(state->pattern)] = c; | ||
| 1079 | state->pattern[strlen(state->pattern)] = '\0'; | ||
| 1080 | adj_match_dir(&state->match_direction); | ||
| 1081 | *ans = get_mext_match(state->pattern, | ||
| 1082 | state->match_direction); | ||
| 1083 | } else if (key == KEY_DOWN) { | ||
| 1084 | state->match_direction = FIND_NEXT_MATCH_DOWN; | ||
| 1085 | *ans = get_mext_match(state->pattern, | ||
| 1086 | state->match_direction); | ||
| 1087 | } else if (key == KEY_UP) { | ||
| 1088 | state->match_direction = FIND_NEXT_MATCH_UP; | ||
| 1089 | *ans = get_mext_match(state->pattern, | ||
| 1090 | state->match_direction); | ||
| 1091 | } else if (key == KEY_BACKSPACE || key == 127) { | ||
| 1092 | state->pattern[strlen(state->pattern)-1] = '\0'; | ||
| 1093 | adj_match_dir(&state->match_direction); | ||
| 1094 | } else | ||
| 1095 | terminate_search = 1; | ||
| 1096 | |||
| 1097 | if (terminate_search) { | ||
| 1098 | state->in_search = 0; | ||
| 1099 | bzero(state->pattern, sizeof(state->pattern)); | ||
| 1100 | move(0, 0); | ||
| 1101 | refresh(); | ||
| 1102 | clrtoeol(); | ||
| 1103 | return -1; | ||
| 1104 | } | ||
| 1105 | return 0; | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | static void conf(struct menu *menu) | ||
| 1109 | { | ||
| 1106 | struct menu *submenu = 0; | 1110 | struct menu *submenu = 0; |
| 1107 | const char *prompt = menu_get_prompt(menu); | 1111 | const char *prompt = menu_get_prompt(menu); |
| 1108 | struct symbol *sym; | 1112 | struct symbol *sym; |
| @@ -1110,8 +1114,11 @@ static void conf(struct menu *menu) | |||
| 1110 | int res; | 1114 | int res; |
| 1111 | int current_index = 0; | 1115 | int current_index = 0; |
| 1112 | int last_top_row = 0; | 1116 | int last_top_row = 0; |
| 1113 | 1117 | struct match_state match_state = { | |
| 1114 | bzero(pattern, sizeof(pattern)); | 1118 | .in_search = 0, |
| 1119 | .match_direction = MATCH_TINKER_PATTERN_DOWN, | ||
| 1120 | .pattern = "", | ||
| 1121 | }; | ||
| 1115 | 1122 | ||
| 1116 | while (!global_exit) { | 1123 | while (!global_exit) { |
| 1117 | reset_menu(); | 1124 | reset_menu(); |
| @@ -1124,7 +1131,22 @@ static void conf(struct menu *menu) | |||
| 1124 | _(menu_instructions), | 1131 | _(menu_instructions), |
| 1125 | current_index, &last_top_row); | 1132 | current_index, &last_top_row); |
| 1126 | keypad((menu_win(curses_menu)), TRUE); | 1133 | keypad((menu_win(curses_menu)), TRUE); |
| 1127 | while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { | 1134 | while (!global_exit) { |
| 1135 | if (match_state.in_search) { | ||
| 1136 | mvprintw(0, 0, | ||
| 1137 | "searching: %s", match_state.pattern); | ||
| 1138 | clrtoeol(); | ||
| 1139 | } | ||
| 1140 | refresh_all_windows(main_window); | ||
| 1141 | res = wgetch(menu_win(curses_menu)); | ||
| 1142 | if (!res) | ||
| 1143 | break; | ||
| 1144 | if (do_match(res, &match_state, ¤t_index) == 0) { | ||
| 1145 | if (current_index != -1) | ||
| 1146 | center_item(current_index, | ||
| 1147 | &last_top_row); | ||
| 1148 | continue; | ||
| 1149 | } | ||
| 1128 | if (process_special_keys(&res, | 1150 | if (process_special_keys(&res, |
| 1129 | (struct menu *) item_data())) | 1151 | (struct menu *) item_data())) |
| 1130 | break; | 1152 | break; |
| @@ -1155,19 +1177,13 @@ static void conf(struct menu *menu) | |||
| 1155 | if (res == 10 || res == 27 || | 1177 | if (res == 10 || res == 27 || |
| 1156 | res == 32 || res == 'n' || res == 'y' || | 1178 | res == 32 || res == 'n' || res == 'y' || |
| 1157 | res == KEY_LEFT || res == KEY_RIGHT || | 1179 | res == KEY_LEFT || res == KEY_RIGHT || |
| 1158 | res == 'm' || res == '/') | 1180 | res == 'm') |
| 1159 | break; | 1181 | 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); | 1182 | refresh_all_windows(main_window); |
| 1167 | } | 1183 | } |
| 1168 | 1184 | ||
| 1169 | refresh_all_windows(main_window); | 1185 | refresh_all_windows(main_window); |
| 1170 | /* if ESC or left*/ | 1186 | /* if ESC or left*/ |
| 1171 | if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) | 1187 | if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) |
| 1172 | break; | 1188 | break; |
| 1173 | 1189 | ||
| @@ -1235,9 +1251,6 @@ static void conf(struct menu *menu) | |||
| 1235 | if (item_is_tag('t')) | 1251 | if (item_is_tag('t')) |
| 1236 | sym_set_tristate_value(sym, mod); | 1252 | sym_set_tristate_value(sym, mod); |
| 1237 | break; | 1253 | break; |
| 1238 | case '/': | ||
| 1239 | search_conf(); | ||
| 1240 | break; | ||
| 1241 | } | 1254 | } |
| 1242 | } | 1255 | } |
| 1243 | } | 1256 | } |
| @@ -1268,6 +1281,11 @@ static void conf_choice(struct menu *menu) | |||
| 1268 | int selected_index = 0; | 1281 | int selected_index = 0; |
| 1269 | int last_top_row = 0; | 1282 | int last_top_row = 0; |
| 1270 | int res, i = 0; | 1283 | int res, i = 0; |
| 1284 | struct match_state match_state = { | ||
| 1285 | .in_search = 0, | ||
| 1286 | .match_direction = MATCH_TINKER_PATTERN_DOWN, | ||
| 1287 | .pattern = "", | ||
| 1288 | }; | ||
| 1271 | 1289 | ||
| 1272 | active = sym_get_choice_value(menu->sym); | 1290 | active = sym_get_choice_value(menu->sym); |
| 1273 | /* this is mostly duplicated from the conf() function. */ | 1291 | /* this is mostly duplicated from the conf() function. */ |
| @@ -1294,7 +1312,22 @@ static void conf_choice(struct menu *menu) | |||
| 1294 | _(radiolist_instructions), | 1312 | _(radiolist_instructions), |
| 1295 | selected_index, | 1313 | selected_index, |
| 1296 | &last_top_row); | 1314 | &last_top_row); |
| 1297 | while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { | 1315 | while (!global_exit) { |
| 1316 | if (match_state.in_search) { | ||
| 1317 | mvprintw(0, 0, "searching: %s", | ||
| 1318 | match_state.pattern); | ||
| 1319 | clrtoeol(); | ||
| 1320 | } | ||
| 1321 | refresh_all_windows(main_window); | ||
| 1322 | res = wgetch(menu_win(curses_menu)); | ||
| 1323 | if (!res) | ||
| 1324 | break; | ||
| 1325 | if (do_match(res, &match_state, &selected_index) == 0) { | ||
| 1326 | if (selected_index != -1) | ||
| 1327 | center_item(selected_index, | ||
| 1328 | &last_top_row); | ||
| 1329 | continue; | ||
| 1330 | } | ||
| 1298 | if (process_special_keys( | 1331 | if (process_special_keys( |
| 1299 | &res, | 1332 | &res, |
| 1300 | (struct menu *) item_data())) | 1333 | (struct menu *) item_data())) |
| @@ -1324,13 +1357,8 @@ static void conf_choice(struct menu *menu) | |||
| 1324 | break; | 1357 | break; |
| 1325 | } | 1358 | } |
| 1326 | if (res == 10 || res == 27 || res == ' ' || | 1359 | if (res == 10 || res == 27 || res == ' ' || |
| 1327 | res == KEY_LEFT) | 1360 | res == KEY_LEFT){ |
| 1328 | break; | 1361 | 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 | } | 1362 | } |
| 1335 | refresh_all_windows(main_window); | 1363 | refresh_all_windows(main_window); |
| 1336 | } | 1364 | } |
| @@ -1485,7 +1513,7 @@ void setup_windows(void) | |||
| 1485 | /* set up the menu and menu window */ | 1513 | /* set up the menu and menu window */ |
| 1486 | main_window = newwin(LINES-2, COLS-2, 2, 1); | 1514 | main_window = newwin(LINES-2, COLS-2, 2, 1); |
| 1487 | keypad(main_window, TRUE); | 1515 | keypad(main_window, TRUE); |
| 1488 | mwin_max_lines = LINES-6; | 1516 | mwin_max_lines = LINES-7; |
| 1489 | mwin_max_cols = COLS-6; | 1517 | mwin_max_cols = COLS-6; |
| 1490 | 1518 | ||
| 1491 | /* panels order is from bottom to top */ | 1519 | /* panels order is from bottom to top */ |
| @@ -1532,9 +1560,10 @@ int main(int ac, char **av) | |||
| 1532 | /* set btns menu */ | 1560 | /* set btns menu */ |
| 1533 | curses_menu = new_menu(curses_menu_items); | 1561 | curses_menu = new_menu(curses_menu_items); |
| 1534 | menu_opts_off(curses_menu, O_SHOWDESC); | 1562 | menu_opts_off(curses_menu, O_SHOWDESC); |
| 1535 | menu_opts_off(curses_menu, O_SHOWMATCH); | 1563 | menu_opts_on(curses_menu, O_SHOWMATCH); |
| 1536 | menu_opts_on(curses_menu, O_ONEVALUE); | 1564 | menu_opts_on(curses_menu, O_ONEVALUE); |
| 1537 | menu_opts_on(curses_menu, O_NONCYCLIC); | 1565 | menu_opts_on(curses_menu, O_NONCYCLIC); |
| 1566 | menu_opts_on(curses_menu, O_IGNORECASE); | ||
| 1538 | set_menu_mark(curses_menu, " "); | 1567 | set_menu_mark(curses_menu, " "); |
| 1539 | set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); | 1568 | set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); |
| 1540 | set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); | 1569 | set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); |
| @@ -1550,8 +1579,6 @@ int main(int ac, char **av) | |||
| 1550 | _(menu_no_f_instructions)); | 1579 | _(menu_no_f_instructions)); |
| 1551 | } | 1580 | } |
| 1552 | 1581 | ||
| 1553 | |||
| 1554 | |||
| 1555 | /* do the work */ | 1582 | /* do the work */ |
| 1556 | while (!global_exit) { | 1583 | while (!global_exit) { |
| 1557 | conf(&rootmenu); | 1584 | conf(&rootmenu); |
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index a9d9344e1365..d963071e48df 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c | |||
| @@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win, | |||
| 167 | length = strlen(string); | 167 | length = strlen(string); |
| 168 | temp = (width - length) / 2; | 168 | temp = (width - length) / 2; |
| 169 | x = startx + (int)temp; | 169 | x = startx + (int)temp; |
| 170 | wattrset(win, color); | 170 | (void) wattrset(win, color); |
| 171 | mvwprintw(win, y, x, "%s", string); | 171 | mvwprintw(win, y, x, "%s", string); |
| 172 | refresh(); | 172 | refresh(); |
| 173 | } | 173 | } |
| @@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) | |||
| 297 | set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); | 297 | set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); |
| 298 | set_menu_back(menu, attributes[DIALOG_MENU_BACK]); | 298 | set_menu_back(menu, attributes[DIALOG_MENU_BACK]); |
| 299 | 299 | ||
| 300 | wattrset(win, attributes[DIALOG_BOX]); | 300 | (void) wattrset(win, attributes[DIALOG_BOX]); |
| 301 | box(win, 0, 0); | 301 | box(win, 0, 0); |
| 302 | 302 | ||
| 303 | /* print message */ | 303 | /* print message */ |
| 304 | wattrset(msg_win, attributes[DIALOG_TEXT]); | 304 | (void) wattrset(msg_win, attributes[DIALOG_TEXT]); |
| 305 | fill_window(msg_win, msg); | 305 | fill_window(msg_win, msg); |
| 306 | 306 | ||
| 307 | set_menu_win(menu, win); | 307 | set_menu_win(menu, win); |
| @@ -392,16 +392,16 @@ int dialog_inputbox(WINDOW *main_window, | |||
| 392 | form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); | 392 | form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); |
| 393 | keypad(form_win, TRUE); | 393 | keypad(form_win, TRUE); |
| 394 | 394 | ||
| 395 | wattrset(form_win, attributes[INPUT_FIELD]); | 395 | (void) wattrset(form_win, attributes[INPUT_FIELD]); |
| 396 | 396 | ||
| 397 | wattrset(win, attributes[INPUT_BOX]); | 397 | (void) wattrset(win, attributes[INPUT_BOX]); |
| 398 | box(win, 0, 0); | 398 | box(win, 0, 0); |
| 399 | wattrset(win, attributes[INPUT_HEADING]); | 399 | (void) wattrset(win, attributes[INPUT_HEADING]); |
| 400 | if (title) | 400 | if (title) |
| 401 | mvwprintw(win, 0, 3, "%s", title); | 401 | mvwprintw(win, 0, 3, "%s", title); |
| 402 | 402 | ||
| 403 | /* print message */ | 403 | /* print message */ |
| 404 | wattrset(prompt_win, attributes[INPUT_TEXT]); | 404 | (void) wattrset(prompt_win, attributes[INPUT_TEXT]); |
| 405 | fill_window(prompt_win, prompt); | 405 | fill_window(prompt_win, prompt); |
| 406 | 406 | ||
| 407 | mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); | 407 | mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); |
| @@ -531,7 +531,7 @@ void show_scroll_win(WINDOW *main_window, | |||
| 531 | 531 | ||
| 532 | /* create the pad */ | 532 | /* create the pad */ |
| 533 | pad = newpad(total_lines+10, total_cols+10); | 533 | pad = newpad(total_lines+10, total_cols+10); |
| 534 | wattrset(pad, attributes[SCROLLWIN_TEXT]); | 534 | (void) wattrset(pad, attributes[SCROLLWIN_TEXT]); |
| 535 | fill_window(pad, text); | 535 | fill_window(pad, text); |
| 536 | 536 | ||
| 537 | win_lines = min(total_lines+4, LINES-2); | 537 | win_lines = min(total_lines+4, LINES-2); |
| @@ -546,9 +546,9 @@ void show_scroll_win(WINDOW *main_window, | |||
| 546 | win = newwin(win_lines, win_cols, y, x); | 546 | win = newwin(win_lines, win_cols, y, x); |
| 547 | keypad(win, TRUE); | 547 | keypad(win, TRUE); |
| 548 | /* show the help in the help window, and show the help panel */ | 548 | /* show the help in the help window, and show the help panel */ |
| 549 | wattrset(win, attributes[SCROLLWIN_BOX]); | 549 | (void) wattrset(win, attributes[SCROLLWIN_BOX]); |
| 550 | box(win, 0, 0); | 550 | box(win, 0, 0); |
| 551 | wattrset(win, attributes[SCROLLWIN_HEADING]); | 551 | (void) wattrset(win, attributes[SCROLLWIN_HEADING]); |
| 552 | mvwprintw(win, 0, 3, " %s ", title); | 552 | mvwprintw(win, 0, 3, " %s ", title); |
| 553 | panel = new_panel(win); | 553 | panel = new_panel(win); |
| 554 | 554 | ||
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index fb4296666004..58fbda8fc0dc 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h | |||
| @@ -69,7 +69,8 @@ typedef enum { | |||
| 69 | F_BACK = 5, | 69 | F_BACK = 5, |
| 70 | F_SAVE = 6, | 70 | F_SAVE = 6, |
| 71 | F_LOAD = 7, | 71 | F_LOAD = 7, |
| 72 | F_EXIT = 8 | 72 | F_SEARCH = 8, |
| 73 | F_EXIT = 9, | ||
| 73 | } function_key; | 74 | } function_key; |
| 74 | 75 | ||
| 75 | void set_colors(void); | 76 | void set_colors(void); |
