diff options
Diffstat (limited to 'util/kconfig/mconf.c')
-rw-r--r-- | util/kconfig/mconf.c | 581 |
1 files changed, 342 insertions, 239 deletions
diff --git a/util/kconfig/mconf.c b/util/kconfig/mconf.c index 692c0e954d..8d299b88d1 100644 --- a/util/kconfig/mconf.c +++ b/util/kconfig/mconf.c @@ -15,21 +15,19 @@ #include <stdarg.h> #include <stdlib.h> #include <string.h> +#include <signal.h> #include <unistd.h> #include <locale.h> -#define LKC_DIRECT_LINK #include "lkc.h" #include "lxdialog/dialog.h" static const char mconf_readme[] = N_( "Overview\n" "--------\n" -"Some features may be built directly into coreboot.\n" -"Some may be made into loadable runtime modules. Some features\n" -"may be completely removed altogether. There are also certain\n" -"parameters which are not really features, but must be\n" -"entered in as decimal or hexadecimal numbers or possibly text.\n" +"This interface lets you select features and parameters for the build.\n" +"Features can either be built-in, modularized, or ignored. Parameters\n" +"must be entered in as decimal or hexadecimal numbers or text.\n" "\n" "Menu items beginning with following braces represent features that\n" " [ ] can be built in or removed\n" @@ -41,16 +39,16 @@ static const char mconf_readme[] = N_( "\n" "To change any of these features, highlight it with the cursor\n" "keys and press <Y> to build it in, <M> to make it a module or\n" -"<N> to removed it. You may also press the <Space Bar> to cycle\n" -"through the available options (ie. Y->N->M->Y).\n" +"<N> to remove it. You may also press the <Space Bar> to cycle\n" +"through the available options (i.e. Y->N->M->Y).\n" "\n" "Some additional keyboard hints:\n" "\n" "Menus\n" "----------\n" -"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" -" you wish to change or submenu wish to select and press <Enter>.\n" -" Submenus are designated by \"--->\".\n" +"o Use the Up/Down arrow keys (cursor keys) to highlight the item you\n" +" wish to change or the submenu you wish to select and press <Enter>.\n" +" Submenus are designated by \"--->\", empty ones by \"----\".\n" "\n" " Shortcut: Press the option's highlighted letter (hotkey).\n" " Pressing a hotkey more than once will sequence\n" @@ -67,13 +65,15 @@ static const char mconf_readme[] = N_( " there is a delayed response which you may find annoying.\n" "\n" " Also, the <TAB> and cursor keys will cycle between <Select>,\n" -" <Exit> and <Help>\n" +" <Exit>, <Help>, <Save>, and <Load>.\n" "\n" "o To get help with an item, use the cursor keys to highlight <Help>\n" -" and Press <ENTER>.\n" +" and press <ENTER>.\n" "\n" " Shortcut: Press <H> or <?>.\n" "\n" +"o To toggle the display of hidden options, press <Z>.\n" +"\n" "\n" "Radiolists (Choice lists)\n" "-----------\n" @@ -105,10 +105,10 @@ static const char mconf_readme[] = N_( "Text Box (Help Window)\n" "--------\n" "o Use the cursor keys to scroll up/down/left/right. The VI editor\n" -" keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n" -" who are familiar with less and lynx.\n" +" keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for\n" +" those who are familiar with less and lynx.\n" "\n" -"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n" +"o Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n" "\n" "\n" "Alternate Configuration Files\n" @@ -117,23 +117,21 @@ static const char mconf_readme[] = N_( "those who, for various reasons, find it necessary to switch\n" "between different configurations.\n" "\n" -"At the end of the main menu you will find two options. One is\n" -"for saving the current configuration to a file of your choosing.\n" -"The other option is for loading a previously saved alternate\n" -"configuration.\n" +"The <Save> button will let you save the current configuration to\n" +"a file of your choosing. Use the <Load> button to load a previously\n" +"saved alternate configuration.\n" "\n" -"Even if you don't use alternate configuration files, but you\n" -"find during a Menuconfig session that you have completely messed\n" -"up your settings, you may use the \"Load Alternate...\" option to\n" -"restore your previously saved settings from \".config\" without\n" -"restarting Menuconfig.\n" +"Even if you don't use alternate configuration files, but you find\n" +"during a Menuconfig session that you have completely messed up your\n" +"settings, you may use the <Load> button to restore your previously\n" +"saved settings from \".config\" without restarting Menuconfig.\n" "\n" "Other information\n" "-----------------\n" -"If you use Menuconfig in an XTERM window make sure you have your\n" -"$TERM variable set to point to a xterm definition which supports color.\n" -"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n" -"display correctly in a RXVT window because rxvt displays only one\n" +"If you use Menuconfig in an XTERM window, make sure you have your\n" +"$TERM variable set to point to an xterm definition which supports\n" +"color. Otherwise, Menuconfig will look rather bad. Menuconfig will\n" +"not display correctly in an RXVT window because rxvt displays only one\n" "intensity of color, bright.\n" "\n" "Menuconfig will display larger menus on screens or xterms which are\n" @@ -148,9 +146,9 @@ static const char mconf_readme[] = N_( "\n" "Optional personality available\n" "------------------------------\n" -"If you prefer to have all of the options listed in a single\n" -"menu, rather than the default multimenu hierarchy, run the menuconfig\n" -"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" +"If you prefer to have all of the options listed in a single menu,\n" +"rather than the default multimenu hierarchy, run the menuconfig with\n" +"MENUCONFIG_MODE environment variable set to single_menu. Example:\n" "\n" "make MENUCONFIG_MODE=single_menu menuconfig\n" "\n" @@ -172,11 +170,11 @@ static const char mconf_readme[] = N_( " mono => selects colors suitable for monochrome displays\n" " blackbg => selects a color scheme with black background\n" " classic => theme with blue background. The classic look\n" -" bluetitle => a LCD friendly version of classic. (default)\n" +" bluetitle => an LCD friendly version of classic. (default)\n" "\n"), menu_instructions[] = N_( "Arrow keys navigate the menu. " - "<Enter> selects submenus --->. " + "<Enter> selects submenus ---> (or empty submenus ----). " "Highlighted letters are hotkeys. " "Pressing <Y> includes, <N> excludes, <M> modularizes features. " "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " @@ -199,8 +197,6 @@ inputbox_instructions_string[] = N_( setmod_text[] = N_( "This feature depends on another which has been configured as a module.\n" "As a result, this feature will be built as a module."), -nohelp_text[] = N_( - "There is no help available for this option.\n"), load_config_text[] = N_( "Enter the name of the configuration file you wish to load. " "Accept the name shown to restore the configuration you " @@ -211,18 +207,18 @@ load_config_help[] = N_( "configurations available on a single machine.\n" "\n" "If you have saved a previous configuration in a file other than the\n" - "default, entering the name of the file here will allow you\n" - "to modify that configuration.\n" + "default one, entering its name here will allow you to modify that\n" + "configuration.\n" "\n" "If you are uncertain, then you have probably never used alternate\n" - "configuration files. You should therefor leave this blank to abort.\n"), + "configuration files. You should therefore leave this blank to abort.\n"), save_config_text[] = N_( "Enter a filename to which this configuration should be saved " "as an alternate. Leave blank to abort."), save_config_help[] = N_( "\n" - "For various reasons, one may wish to keep different\n" - "configurations available on a single machine.\n" + "For various reasons, one may wish to keep different configurations\n" + "available on a single machine.\n" "\n" "Entering a file name here will allow you to later retrieve, modify\n" "and use the current configuration as an alternate to whatever\n" @@ -232,164 +228,184 @@ save_config_help[] = N_( "leave this blank.\n"), search_help[] = N_( "\n" - "Search for CONFIG_ symbols and display their relations.\n" + "Search for symbols and display their relations.\n" "Regular expressions are allowed.\n" "Example: search for \"^FOO\"\n" "Result:\n" "-----------------------------------------------------------------\n" "Symbol: FOO [=m]\n" + "Type : tristate\n" "Prompt: Foo bus is used to drive the bar HW\n" - "Defined at drivers/pci/Kconfig:47\n" - "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" - "Location:\n" - " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" - " -> PCI support (PCI [=y])\n" - " -> PCI access mode (<choice> [=y])\n" - "Selects: LIBCRC32\n" - "Selected by: BAR\n" + " Location:\n" + " -> Bus options (PCI, PCMCIA, EISA, ISA)\n" + " -> PCI support (PCI [=y])\n" + "(1) -> PCI access mode (<choice> [=y])\n" + " Defined at drivers/pci/Kconfig:47\n" + " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" + " Selects: LIBCRC32\n" + " Selected by: BAR [=n]\n" "-----------------------------------------------------------------\n" + "o The line 'Type:' shows the type of the configuration option for\n" + " this symbol (boolean, tristate, string, ...)\n" "o The line 'Prompt:' shows the text used in the menu structure for\n" - " this CONFIG_ symbol\n" - "o The 'Defined at' line tell at what file / line number the symbol\n" + " this symbol\n" + "o The 'Defined at' line tells at what file / line number the symbol\n" " is defined\n" - "o The 'Depends on:' line tell what symbols needs to be defined for\n" + "o The 'Depends on:' line tells what symbols need to be defined for\n" " this symbol to be visible in the menu (selectable)\n" - "o The 'Location:' lines tell where in the menu structure this symbol\n" + "o The 'Location:' lines tells where in the menu structure this symbol\n" " is located\n" - " A location followed by a [=y] indicate that this is a selectable\n" - " menu item - and current value is displayed inside brackets.\n" - "o The 'Selects:' line tell what symbol will be automatically\n" + " A location followed by a [=y] indicates that this is a\n" + " selectable menu item - and the current value is displayed inside\n" + " brackets.\n" + " Press the key in the (#) prefix to jump directly to that\n" + " location. You will be returned to the current search results\n" + " after exiting this new menu.\n" + "o The 'Selects:' line tells what symbols will be automatically\n" " selected if this symbol is selected (y or m)\n" - "o The 'Selected by' line tell what symbol has selected this symbol\n" + "o The 'Selected by' line tells what symbol has selected this symbol\n" "\n" "Only relevant lines are shown.\n" "\n\n" "Search examples:\n" - "Examples: USB => find all CONFIG_ symbols containing USB\n" - " ^USB => find all CONFIG_ symbols starting with USB\n" - " USB$ => find all CONFIG_ symbols ending with USB\n" + "Examples: USB => find all symbols containing USB\n" + " ^USB => find all symbols starting with USB\n" + " USB$ => find all symbols ending with USB\n" "\n"); static int indent; static struct menu *current_menu; static int child_count; static int single_menu_mode; +static int show_all_options; +static int save_and_exit; -static void conf(struct menu *menu); +static void conf(struct menu *menu, struct menu *active_menu); static void conf_choice(struct menu *menu); static void conf_string(struct menu *menu); static void conf_load(void); static void conf_save(void); +static int show_textbox_ext(const char *title, char *text, int r, int c, + int *keys, int *vscroll, int *hscroll, + update_text_fn update_text, void *data); static void show_textbox(const char *title, const char *text, int r, int c); static void show_helptext(const char *title, const char *text); static void show_help(struct menu *menu); -static void get_prompt_str(struct gstr *r, struct property *prop) +static char filename[PATH_MAX+1]; +static void set_config_filename(const char *config_filename) +{ + static char menu_backtitle[PATH_MAX+128]; + int size; + + size = snprintf(menu_backtitle, sizeof(menu_backtitle), + "%s - %s", config_filename, rootmenu.prompt->text); + if (size >= sizeof(menu_backtitle)) + menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; + set_dialog_backtitle(menu_backtitle); + + size = snprintf(filename, sizeof(filename), "%s", config_filename); + if (size >= sizeof(filename)) + filename[sizeof(filename)-1] = '\0'; +} + +struct subtitle_part { + struct list_head entries; + const char *text; +}; +static LIST_HEAD(trail); + +static struct subtitle_list *subtitles; +static void set_subtitle(void) { - int i, j; - struct menu *submenu[8], *menu; - - str_printf(r, _("Prompt: %s\n"), _(prop->text)); - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); + struct subtitle_part *sp; + struct subtitle_list *pos, *tmp; + + for (pos = subtitles; pos != NULL; pos = tmp) { + tmp = pos->next; + free(pos); } - menu = prop->menu->parent; - for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) - submenu[i++] = menu; - if (i > 0) { - str_printf(r, _(" Location:\n")); - for (j = 4; --i >= 0; j += 2) { - menu = submenu[i]; - str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); - if (menu->sym) { - str_printf(r, " (%s [=%s])", menu->sym->name ? - menu->sym->name : _("<choice>"), - sym_get_string_value(menu->sym)); + + subtitles = NULL; + list_for_each_entry(sp, &trail, entries) { + if (sp->text) { + if (pos) { + pos->next = xcalloc(sizeof(*pos), 1); + pos = pos->next; + } else { + subtitles = pos = xcalloc(sizeof(*pos), 1); } - str_append(r, "\n"); + pos->text = sp->text; } } + + set_dialog_subtitles(subtitles); } -static void get_symbol_str(struct gstr *r, struct symbol *sym) +static void reset_subtitle(void) { - bool hit; - struct property *prop; + struct subtitle_list *pos, *tmp; - if (sym && sym->name) - str_printf(r, "Symbol: %s [=%s]\n", sym->name, - sym_get_string_value(sym)); - for_all_prompts(sym, prop) - get_prompt_str(r, prop); - hit = false; - for_all_properties(sym, prop, P_SELECT) { - if (!hit) { - str_append(r, " Selects: "); - hit = true; - } else - str_printf(r, " && "); - expr_gstr_print(prop->expr, r); + for (pos = subtitles; pos != NULL; pos = tmp) { + tmp = pos->next; + free(pos); } - if (hit) - str_append(r, "\n"); - if (sym->rev_dep.expr) { - str_append(r, _(" Selected by: ")); - expr_gstr_print(sym->rev_dep.expr, r); - str_append(r, "\n"); - } - str_append(r, "\n\n"); + subtitles = NULL; + set_dialog_subtitles(subtitles); } -static struct gstr get_relations_str(struct symbol **sym_arr) +struct search_data { + struct list_head *head; + struct menu **targets; + int *keys; +}; + +static void update_text(char *buf, size_t start, size_t end, void *_data) { - struct symbol *sym; - struct gstr res = str_new(); - int i; + struct search_data *data = _data; + struct jump_key *pos; + int k = 0; - for (i = 0; sym_arr && (sym = sym_arr[i]); i++) - get_symbol_str(&res, sym); - if (!i) - str_append(&res, _("No matches found.\n")); - return res; -} + list_for_each_entry(pos, data->head, entries) { + if (pos->offset >= start && pos->offset < end) { + char header[4]; -static char filename[PATH_MAX+1]; -static void set_config_filename(const char *config_filename) -{ - static char menu_backtitle[PATH_MAX+128]; - int size; - struct symbol *sym; + if (k < JUMP_NB) { + int key = '0' + (pos->index % JUMP_NB) + 1; - sym = sym_lookup("KERNELVERSION", 0); - sym_calc_value(sym); - size = snprintf(menu_backtitle, sizeof(menu_backtitle), - _("%s - coreboot v%s Configuration"), - config_filename, getenv("KERNELVERSION")); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; - set_dialog_backtitle(menu_backtitle); + sprintf(header, "(%c)", key); + data->keys[k] = key; + data->targets[k] = pos->target; + k++; + } else { + sprintf(header, " "); + } - size = snprintf(filename, sizeof(filename), "%s", config_filename); - if (size >= sizeof(filename)) - filename[sizeof(filename)-1] = '\0'; + memcpy(buf + pos->offset, header, sizeof(header) - 1); + } + } + data->keys[k] = 0; } - static void search_conf(void) { struct symbol **sym_arr; struct gstr res; + struct gstr title; char *dialog_input; - int dres; + int dres, vscroll = 0, hscroll = 0; + bool again; + struct gstr sttext; + struct subtitle_part stpart; + + title = str_new(); + str_printf( &title, _("Enter (sub)string or regexp to search for " + "(with or without \"%s\")"), CONFIG_); + again: dialog_clear(); dres = dialog_inputbox(_("Search Configuration Parameter"), - _("Enter CONFIG_ (sub)string to search for " - "(with or without \"CONFIG\")"), + str_get(&title), 10, 75, ""); switch (dres) { case 0: @@ -398,19 +414,52 @@ again: show_helptext(_("Search Configuration"), search_help); goto again; default: + str_free(&title); return; } - /* strip CONFIG_ if necessary */ + /* strip the prefix if necessary */ dialog_input = dialog_input_result; - if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) - dialog_input += 7; + if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) + dialog_input += strlen(CONFIG_); + + sttext = str_new(); + str_printf(&sttext, "Search (%s)", dialog_input_result); + stpart.text = str_get(&sttext); + list_add_tail(&stpart.entries, &trail); sym_arr = sym_re_search(dialog_input); - res = get_relations_str(sym_arr); + do { + LIST_HEAD(head); + struct menu *targets[JUMP_NB]; + int keys[JUMP_NB + 1], i; + struct search_data data = { + .head = &head, + .targets = targets, + .keys = keys, + }; + struct jump_key *pos, *tmp; + + res = get_relations_str(sym_arr, &head); + set_subtitle(); + dres = show_textbox_ext(_("Search Results"), (char *) + str_get(&res), 0, 0, keys, &vscroll, + &hscroll, &update_text, (void *) + &data); + again = false; + for (i = 0; i < JUMP_NB && keys[i]; i++) + if (dres == keys[i]) { + conf(targets[i]->parent, targets[i]); + again = true; + } + str_free(&res); + list_for_each_entry_safe(pos, tmp, &head, entries) + free(pos); + } while (again); free(sym_arr); - show_textbox(_("Search Results"), str_get(&res), 0, 0); - str_free(&res); + str_free(&title); + list_del(trail.prev); + str_free(&sttext); } static void build_conf(struct menu *menu) @@ -421,8 +470,16 @@ static void build_conf(struct menu *menu) int type, tmp, doint = 2; tristate val; char ch; + bool visible; - if (!menu_is_visible(menu)) + /* + * note: menu_is_visible() has side effect that it will + * recalc the value of the symbol. + */ + visible = menu_is_visible(menu); + if (show_all_options && !menu_has_prompt(menu)) + return; + else if (!show_all_options && !visible) return; sym = menu->sym; @@ -439,8 +496,9 @@ static void build_conf(struct menu *menu) menu->data ? "-->" : "++>", indent + 1, ' ', prompt); } else - item_make(" %*c%s --->", indent + 1, ' ', prompt); - + item_make(" %*c%s %s", + indent + 1, ' ', prompt, + menu_is_empty(menu) ? "----" : "--->"); item_set_tag('m'); item_set_data(menu); if (single_menu_mode && menu->data) @@ -506,14 +564,11 @@ static void build_conf(struct menu *menu) if (def_menu) { item_add_str(" (%s)", _(menu_get_prompt(def_menu))); item_add_str(" --->"); -#if 0 -/* coreboot doesn't need this representation */ if (def_menu->list) { indent += 2; build_conf(def_menu); indent -= 2; } -#endif } return; } @@ -574,7 +629,7 @@ static void build_conf(struct menu *menu) (sym_has_value(sym) || !sym_is_changable(sym)) ? "" : _(" (NEW)")); if (menu->prompt->type == P_MENU) { - item_add_str(" --->"); + item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); return; } } @@ -586,40 +641,40 @@ conf_childs: indent -= doint; } -static void conf(struct menu *menu) +static void conf(struct menu *menu, struct menu *active_menu) { struct menu *submenu; const char *prompt = menu_get_prompt(menu); + struct subtitle_part stpart; struct symbol *sym; - struct menu *active_menu = NULL; int res; int s_scroll = 0; + if (menu != &rootmenu) + stpart.text = menu_get_prompt(menu); + else + stpart.text = NULL; + list_add_tail(&stpart.entries, &trail); + while (1) { item_reset(); current_menu = menu; build_conf(menu); if (!child_count) break; - if (menu == &rootmenu) { - item_make("--- "); - item_set_tag(':'); - item_make(_(" Load an Alternate Configuration File")); - item_set_tag('L'); - item_make(_(" Save an Alternate Configuration File")); - item_set_tag('S'); - } + set_subtitle(); dialog_clear(); res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), _(menu_instructions), active_menu, &s_scroll); if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) break; - if (!item_activate_selected()) - continue; - if (!item_tag()) - continue; - + if (item_count() != 0) { + if (!item_activate_selected()) + continue; + if (!item_tag()) + continue; + } submenu = item_data(); active_menu = item_data(); if (submenu) @@ -634,32 +689,36 @@ static void conf(struct menu *menu) if (single_menu_mode) submenu->data = (void *) (long) !submenu->data; else - conf(submenu); + conf(submenu, NULL); break; case 't': if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) conf_choice(submenu); else if (submenu->prompt->type == P_MENU) - conf(submenu); + conf(submenu, NULL); break; case 's': conf_string(submenu); break; - case 'L': - conf_load(); - break; - case 'S': - conf_save(); - break; } break; case 2: if (sym) show_help(submenu); - else + else { + reset_subtitle(); show_helptext(_("README"), _(mconf_readme)); + } break; case 3: + reset_subtitle(); + conf_save(); + break; + case 4: + reset_subtitle(); + conf_load(); + break; + case 5: if (item_is_tag('t')) { if (sym_set_tristate_value(sym, yes)) break; @@ -667,31 +726,45 @@ static void conf(struct menu *menu) show_textbox(NULL, setmod_text, 6, 74); } break; - case 4: + case 6: if (item_is_tag('t')) sym_set_tristate_value(sym, no); break; - case 5: + case 7: if (item_is_tag('t')) sym_set_tristate_value(sym, mod); break; - case 6: + case 8: if (item_is_tag('t')) sym_toggle_tristate_value(sym); else if (item_is_tag('m')) - conf(submenu); + conf(submenu, NULL); break; - case 7: + case 9: search_conf(); break; + case 10: + show_all_options = !show_all_options; + break; } } + + list_del(trail.prev); } -static void show_textbox(const char *title, const char *text, int r, int c) +static int show_textbox_ext(const char *title, char *text, int r, int c, int + *keys, int *vscroll, int *hscroll, update_text_fn + update_text, void *data) { dialog_clear(); - dialog_textbox(title, text, r, c); + return dialog_textbox(title, text, r, c, keys, vscroll, hscroll, + update_text, data); +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ + show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL, + NULL, NULL); } static void show_helptext(const char *title, const char *text) @@ -699,22 +772,24 @@ static void show_helptext(const char *title, const char *text) show_textbox(title, text, 0, 0); } +static void conf_message_callback(const char *fmt, va_list ap) +{ + char buf[PATH_MAX+1]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + if (save_and_exit) + printf("%s", buf); + else + show_textbox(NULL, buf, 6, 60); +} + static void show_help(struct menu *menu) { struct gstr help = str_new(); - struct symbol *sym = menu->sym; - - if (menu_has_help(menu)) - { - if (sym->name) { - str_printf(&help, "CONFIG_%s:\n\n", sym->name); - str_append(&help, _(menu_get_help(menu))); - str_append(&help, "\n"); - } - } else { - str_append(&help, nohelp_text); - } - get_symbol_str(&help, sym); + + help.max_width = getmaxx(stdscr) - 10; + menu_get_ext_help(menu, &help); + show_helptext(_(menu_get_prompt(menu)), str_get(&help)); str_free(&help); } @@ -735,7 +810,12 @@ static void conf_choice(struct menu *menu) for (child = menu->list; child; child = child->next) { if (!menu_is_visible(child)) continue; - item_make("%s", _(menu_get_prompt(child))); + if (child->sym) + item_make("%s", _(menu_get_prompt(child))); + else { + item_make("*** %s ***", _(menu_get_prompt(child))); + item_set_tag(':'); + } item_set_data(child); if (child->sym == active) item_set_selected(1); @@ -745,12 +825,17 @@ static void conf_choice(struct menu *menu) dialog_clear(); res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), _(radiolist_instructions), - 15, 70, 6); + MENUBOX_HEIGTH_MIN, + MENUBOX_WIDTH_MIN, + CHECKLIST_HEIGTH_MIN); selected = item_activate_selected(); switch (res) { case 0: if (selected) { child = item_data(); + if (!child->sym) + break; + sym_set_tristate_value(child->sym, yes); } return; @@ -864,9 +949,58 @@ static void conf_save(void) } } +static int handle_exit(void) +{ + int res; + + save_and_exit = 1; + reset_subtitle(); + dialog_clear(); + if (conf_get_changed()) + res = dialog_yesno(NULL, + _("Do you wish to save your new configuration?\n" + "(Press <ESC><ESC> to continue configuration.)"), + 6, 60); + else + res = -1; + + end_dialog(saved_x, saved_y); + + switch (res) { + case 0: + if (conf_write(filename)) { + fprintf(stderr, _("\n\n" + "Error while writing of the configuration.\n" + "Your configuration changes were NOT saved." + "\n\n")); + return 1; + } + /* fall through */ + case -1: + printf(_("\n\n" + "*** End of the configuration.\n" + "*** Execute 'make' to start the build or try 'make help'." + "\n\n")); + res = 0; + break; + default: + fprintf(stderr, _("\n\n" + "Your configuration changes were NOT saved." + "\n\n")); + if (res != KEY_ESC) + res = 0; + } + + return res; +} + +static void sig_handler(int signo) +{ + exit(handle_exit()); +} + int main(int ac, char **av) { - int saved_x = 0, saved_y = 0; char *mode; int res; @@ -874,6 +1008,8 @@ int main(int ac, char **av) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); + signal(SIGINT, sig_handler); + conf_parse(av[1]); conf_read(NULL); @@ -883,7 +1019,6 @@ int main(int ac, char **av) single_menu_mode = 1; } - if (stdscr) getyx(stdscr, saved_y, saved_x); if (init_dialog(NULL)) { fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); @@ -891,44 +1026,12 @@ int main(int ac, char **av) } set_config_filename(conf_get_configname()); + conf_set_message_callback(conf_message_callback); do { - conf(&rootmenu); - dialog_clear(); - if (conf_get_changed()) - res = dialog_yesno(NULL, - _("Do you wish to save your " - "new configuration?\n" - "<ESC><ESC> to continue."), - 6, 60); - else - res = -1; + conf(&rootmenu, NULL); + res = handle_exit(); } while (res == KEY_ESC); - end_dialog(saved_x, saved_y); - switch (res) { - case 0: - if (conf_write(filename)) { - fprintf(stderr, _("\n\n" - "Error during writing of the configuration.\n" - "Your configuration changes were NOT saved." - "\n\n")); - return 1; - } - if (conf_write_autoconf()) { - fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); - return 1; - } - case -1: - printf(_("\n\n" - "*** End of coreboot configuration.\n" - "*** Execute 'make' to build or try 'make help'." - "\n\n")); - break; - default: - fprintf(stderr, _("\n\n" - "Your configuration changes were NOT saved." - "\n\n")); - } - - return 0; + return res; } + |