blob: 5f29618d1845c534a39975a45a74ae25b1ba33ed [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07007 *
8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 */
10
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <ctype.h>
12#include <errno.h>
13#include <fcntl.h>
14#include <limits.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <stdarg.h>
16#include <stdlib.h>
17#include <string.h>
Davidlohr Bueso564899f2011-08-21 22:04:09 -030018#include <signal.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <unistd.h>
Jean-Christophe Dubois442ff702005-06-25 14:55:43 -070020#include <locale.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include "lkc.h"
Sam Ravnborg2982de62006-07-27 22:10:27 +020023#include "lxdialog/dialog.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070025static const char mconf_readme[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -070026"Overview\n"
27"--------\n"
Arnaud Lacombe652cf982010-08-14 23:51:40 -040028"This interface let you select features and parameters for the build.\n"
29"Features can either be built-in, modularized, or ignored. Parameters\n"
30"must be entered in as decimal or hexadecimal numbers or text.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -070031"\n"
Matej Laitlb5d609d2007-10-02 13:46:50 -070032"Menu items beginning with following braces represent features that\n"
33" [ ] can be built in or removed\n"
34" < > can be built in, modularized or removed\n"
35" { } can be built in or modularized (selected by other feature)\n"
36" - - are selected by other feature,\n"
37"while *, M or whitespace inside braces means to build in, build as\n"
38"a module or to exclude the feature respectively.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -070039"\n"
40"To change any of these features, highlight it with the cursor\n"
41"keys and press <Y> to build it in, <M> to make it a module or\n"
42"<N> to removed it. You may also press the <Space Bar> to cycle\n"
43"through the available options (ie. Y->N->M->Y).\n"
44"\n"
45"Some additional keyboard hints:\n"
46"\n"
47"Menus\n"
48"----------\n"
49"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
50" you wish to change or submenu wish to select and press <Enter>.\n"
51" Submenus are designated by \"--->\".\n"
52"\n"
53" Shortcut: Press the option's highlighted letter (hotkey).\n"
54" Pressing a hotkey more than once will sequence\n"
55" through all visible items which use that hotkey.\n"
56"\n"
57" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
58" unseen options into view.\n"
59"\n"
60"o To exit a menu use the cursor keys to highlight the <Exit> button\n"
61" and press <ENTER>.\n"
62"\n"
63" Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
64" using those letters. You may press a single <ESC>, but\n"
65" there is a delayed response which you may find annoying.\n"
66"\n"
67" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
Li Zefan22c7eca2010-04-14 11:46:02 +080068" <Exit> and <Help>.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -070069"\n"
70"o To get help with an item, use the cursor keys to highlight <Help>\n"
Li Zefan22c7eca2010-04-14 11:46:02 +080071" and press <ENTER>.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -070072"\n"
73" Shortcut: Press <H> or <?>.\n"
74"\n"
Li Zefanf9447c42010-05-07 13:57:22 +080075"o To toggle the display of hidden options, press <Z>.\n"
Li Zefan22c7eca2010-04-14 11:46:02 +080076"\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -070077"\n"
78"Radiolists (Choice lists)\n"
79"-----------\n"
80"o Use the cursor keys to select the option you wish to set and press\n"
81" <S> or the <SPACE BAR>.\n"
82"\n"
83" Shortcut: Press the first letter of the option you wish to set then\n"
84" press <S> or <SPACE BAR>.\n"
85"\n"
86"o To see available help for the item, use the cursor keys to highlight\n"
87" <Help> and Press <ENTER>.\n"
88"\n"
89" Shortcut: Press <H> or <?>.\n"
90"\n"
91" Also, the <TAB> and cursor keys will cycle between <Select> and\n"
92" <Help>\n"
93"\n"
94"\n"
95"Data Entry\n"
96"-----------\n"
97"o Enter the requested information and press <ENTER>\n"
98" If you are entering hexadecimal values, it is not necessary to\n"
99" add the '0x' prefix to the entry.\n"
100"\n"
101"o For help, use the <TAB> or cursor keys to highlight the help option\n"
102" and press <ENTER>. You can try <TAB><H> as well.\n"
103"\n"
104"\n"
105"Text Box (Help Window)\n"
106"--------\n"
107"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
Benjamin Poirier9d4792c2012-07-24 16:12:02 -0400108" keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for \n"
109" those who are familiar with less and lynx.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110"\n"
Benjamin Poirier9d4792c2012-07-24 16:12:02 -0400111"o Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112"\n"
113"\n"
114"Alternate Configuration Files\n"
115"-----------------------------\n"
116"Menuconfig supports the use of alternate configuration files for\n"
117"those who, for various reasons, find it necessary to switch\n"
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400118"between different configurations.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119"\n"
120"At the end of the main menu you will find two options. One is\n"
121"for saving the current configuration to a file of your choosing.\n"
122"The other option is for loading a previously saved alternate\n"
123"configuration.\n"
124"\n"
125"Even if you don't use alternate configuration files, but you\n"
126"find during a Menuconfig session that you have completely messed\n"
127"up your settings, you may use the \"Load Alternate...\" option to\n"
128"restore your previously saved settings from \".config\" without\n"
129"restarting Menuconfig.\n"
130"\n"
131"Other information\n"
132"-----------------\n"
133"If you use Menuconfig in an XTERM window make sure you have your\n"
134"$TERM variable set to point to a xterm definition which supports color.\n"
135"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n"
136"display correctly in a RXVT window because rxvt displays only one\n"
137"intensity of color, bright.\n"
138"\n"
139"Menuconfig will display larger menus on screens or xterms which are\n"
140"set to display more than the standard 25 row by 80 column geometry.\n"
141"In order for this to work, the \"stty size\" command must be able to\n"
142"display the screen's current row and column geometry. I STRONGLY\n"
143"RECOMMEND that you make sure you do NOT have the shell variables\n"
144"LINES and COLUMNS exported into your environment. Some distributions\n"
145"export those variables via /etc/profile. Some ncurses programs can\n"
146"become confused when those variables (LINES & COLUMNS) don't reflect\n"
147"the true screen size.\n"
148"\n"
149"Optional personality available\n"
150"------------------------------\n"
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400151"If you prefer to have all of the options listed in a single menu, rather\n"
152"than the default multimenu hierarchy, run the menuconfig with\n"
153"MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154"\n"
155"make MENUCONFIG_MODE=single_menu menuconfig\n"
156"\n"
157"<Enter> will then unroll the appropriate category, or enfold it if it\n"
158"is already unrolled.\n"
159"\n"
160"Note that this mode can eventually be a little more CPU expensive\n"
161"(especially with a larger number of unrolled categories) than the\n"
Sam Ravnborg45897212006-07-24 22:04:04 +0200162"default mode.\n"
163"\n"
164"Different color themes available\n"
165"--------------------------------\n"
166"It is possible to select different color themes using the variable\n"
167"MENUCONFIG_COLOR. To select a theme use:\n"
168"\n"
169"make MENUCONFIG_COLOR=<theme> menuconfig\n"
170"\n"
171"Available themes are\n"
172" mono => selects colors suitable for monochrome displays\n"
173" blackbg => selects a color scheme with black background\n"
Sam Ravnborg350b5b72006-07-24 22:19:51 +0200174" classic => theme with blue background. The classic look\n"
175" bluetitle => a LCD friendly version of classic. (default)\n"
Sam Ravnborg45897212006-07-24 22:04:04 +0200176"\n"),
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700177menu_instructions[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 "Arrow keys navigate the menu. "
179 "<Enter> selects submenus --->. "
180 "Highlighted letters are hotkeys. "
181 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
182 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700183 "Legend: [*] built-in [ ] excluded <M> module < > module capable"),
184radiolist_instructions[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 "Use the arrow keys to navigate this window or "
186 "press the hotkey of the item you wish to select "
187 "followed by the <SPACE BAR>. "
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700188 "Press <?> for additional information about this option."),
189inputbox_instructions_int[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 "Please enter a decimal value. "
191 "Fractions will not be accepted. "
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700192 "Use the <TAB> key to move from the input field to the buttons below it."),
193inputbox_instructions_hex[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 "Please enter a hexadecimal value. "
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700195 "Use the <TAB> key to move from the input field to the buttons below it."),
196inputbox_instructions_string[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 "Please enter a string value. "
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700198 "Use the <TAB> key to move from the input field to the buttons below it."),
199setmod_text[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 "This feature depends on another which has been configured as a module.\n"
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700201 "As a result, this feature will be built as a module."),
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700202load_config_text[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 "Enter the name of the configuration file you wish to load. "
204 "Accept the name shown to restore the configuration you "
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700205 "last retrieved. Leave blank to abort."),
206load_config_help[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 "\n"
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400208 "For various reasons, one may wish to keep several different\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 "configurations available on a single machine.\n"
210 "\n"
211 "If you have saved a previous configuration in a file other than the\n"
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400212 "default one, entering its name here will allow you to modify that\n"
213 "configuration.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 "\n"
215 "If you are uncertain, then you have probably never used alternate\n"
André Goddard Rosaaf901ca2009-11-14 13:09:05 -0200216 "configuration files. You should therefore leave this blank to abort.\n"),
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700217save_config_text[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 "Enter a filename to which this configuration should be saved "
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700219 "as an alternate. Leave blank to abort."),
220save_config_help[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 "\n"
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400222 "For various reasons, one may wish to keep different configurations\n"
223 "available on a single machine.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 "\n"
225 "Entering a file name here will allow you to later retrieve, modify\n"
226 "and use the current configuration as an alternate to whatever\n"
227 "configuration options you have selected at that time.\n"
228 "\n"
229 "If you are uncertain what all this means then you should probably\n"
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700230 "leave this blank.\n"),
231search_help[] = N_(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 "\n"
Arnaud Lacombe59dfa242010-08-21 00:43:46 -0400233 "Search for symbols and display their relations.\n"
Randy Dunlap503af332005-10-30 15:02:15 -0800234 "Regular expressions are allowed.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 "Example: search for \"^FOO\"\n"
236 "Result:\n"
237 "-----------------------------------------------------------------\n"
238 "Symbol: FOO [=m]\n"
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400239 "Type : tristate\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 "Prompt: Foo bus is used to drive the bar HW\n"
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400241 " Defined at drivers/pci/Kconfig:47\n"
242 " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
243 " Location:\n"
244 " -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
245 " -> PCI support (PCI [=y])\n"
246 "(1) -> PCI access mode (<choice> [=y])\n"
247 " Selects: LIBCRC32\n"
248 " Selected by: BAR\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 "-----------------------------------------------------------------\n"
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400250 "o The line 'Type:' shows the type of the configuration option for\n"
251 " this symbol (boolean, tristate, string, ...)\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 "o The line 'Prompt:' shows the text used in the menu structure for\n"
Arnaud Lacombe59dfa242010-08-21 00:43:46 -0400253 " this symbol\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 "o The 'Defined at' line tell at what file / line number the symbol\n"
255 " is defined\n"
256 "o The 'Depends on:' line tell what symbols needs to be defined for\n"
257 " this symbol to be visible in the menu (selectable)\n"
258 "o The 'Location:' lines tell where in the menu structure this symbol\n"
259 " is located\n"
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400260 " A location followed by a [=y] indicates that this is a\n"
261 " selectable menu item - and the current value is displayed inside\n"
262 " brackets.\n"
263 " Press the key in the (#) prefix to jump directly to that\n"
264 " location. You will be returned to the current search results\n"
265 " after exiting this new menu.\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 "o The 'Selects:' line tell what symbol will be automatically\n"
267 " selected if this symbol is selected (y or m)\n"
268 "o The 'Selected by' line tell what symbol has selected this symbol\n"
269 "\n"
270 "Only relevant lines are shown.\n"
271 "\n\n"
272 "Search examples:\n"
Arnaud Lacombe59dfa242010-08-21 00:43:46 -0400273 "Examples: USB => find all symbols containing USB\n"
274 " ^USB => find all symbols starting with USB\n"
275 " USB$ => find all symbols ending with USB\n"
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700276 "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278static int indent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279static struct menu *current_menu;
280static int child_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281static int single_menu_mode;
Li Zefan22c7eca2010-04-14 11:46:02 +0800282static int show_all_options;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400284static void conf(struct menu *menu, struct menu *active_menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285static void conf_choice(struct menu *menu);
286static void conf_string(struct menu *menu);
287static void conf_load(void);
288static void conf_save(void);
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400289static int show_textbox_ext(const char *title, char *text, int r, int c,
290 int *keys, int *vscroll, int *hscroll,
291 update_text_fn update_text, void *data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292static void show_textbox(const char *title, const char *text, int r, int c);
293static void show_helptext(const char *title, const char *text);
294static void show_help(struct menu *menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100296static char filename[PATH_MAX+1];
297static void set_config_filename(const char *config_filename)
298{
299 static char menu_backtitle[PATH_MAX+128];
300 int size;
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100301
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100302 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
Arnaud Lacombe09548282010-08-18 01:57:13 -0400303 "%s - %s", config_filename, rootmenu.prompt->text);
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100304 if (size >= sizeof(menu_backtitle))
305 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
306 set_dialog_backtitle(menu_backtitle);
307
308 size = snprintf(filename, sizeof(filename), "%s", config_filename);
309 if (size >= sizeof(filename))
310 filename[sizeof(filename)-1] = '\0';
311}
312
313
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400314struct search_data {
315 struct jk_head *head;
316 struct menu **targets;
317 int *keys;
318};
319
320static void update_text(char *buf, size_t start, size_t end, void *_data)
321{
322 struct search_data *data = _data;
323 struct jump_key *pos;
324 int k = 0;
325
326 CIRCLEQ_FOREACH(pos, data->head, entries) {
327 if (pos->offset >= start && pos->offset < end) {
328 char header[4];
329
330 if (k < JUMP_NB) {
331 int key = '0' + (pos->index % JUMP_NB) + 1;
332
333 sprintf(header, "(%c)", key);
334 data->keys[k] = key;
335 data->targets[k] = pos->target;
336 k++;
337 } else {
338 sprintf(header, " ");
339 }
340
341 memcpy(buf + pos->offset, header, sizeof(header) - 1);
342 }
343 }
344 data->keys[k] = 0;
345}
346
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347static void search_conf(void)
348{
349 struct symbol **sym_arr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 struct gstr res;
Yann E. MORIN337a2752012-10-20 01:06:23 +0200351 struct gstr title;
Bernhard Walle0584f9f2007-07-09 11:43:56 -0700352 char *dialog_input;
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400353 int dres, vscroll = 0, hscroll = 0;
354 bool again;
355
Yann E. MORIN337a2752012-10-20 01:06:23 +0200356 title = str_new();
357 str_printf( &title, _("Enter %s (sub)string to search for "
358 "(with or without \"%s\")"), CONFIG_, CONFIG_);
359
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360again:
Sam Ravnborge94c5bd2006-09-25 17:35:43 +0200361 dialog_clear();
Sam Ravnborg2982de62006-07-27 22:10:27 +0200362 dres = dialog_inputbox(_("Search Configuration Parameter"),
Yann E. MORIN337a2752012-10-20 01:06:23 +0200363 str_get(&title),
Sam Ravnborg2982de62006-07-27 22:10:27 +0200364 10, 75, "");
365 switch (dres) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 case 0:
367 break;
368 case 1:
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700369 show_helptext(_("Search Configuration"), search_help);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 goto again;
371 default:
Yann E. MORIN337a2752012-10-20 01:06:23 +0200372 str_free(&title);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 return;
374 }
375
Arnaud Lacombeffb59572010-08-14 23:57:43 -0400376 /* strip the prefix if necessary */
Bernhard Walle0584f9f2007-07-09 11:43:56 -0700377 dialog_input = dialog_input_result;
Arnaud Lacombeffb59572010-08-14 23:57:43 -0400378 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
379 dialog_input += strlen(CONFIG_);
Bernhard Walle0584f9f2007-07-09 11:43:56 -0700380
381 sym_arr = sym_re_search(dialog_input);
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400382 do {
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400383 struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head);
384 struct menu *targets[JUMP_NB];
385 int keys[JUMP_NB + 1], i;
386 struct search_data data = {
387 .head = &head,
388 .targets = targets,
389 .keys = keys,
390 };
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400391
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400392 res = get_relations_str(sym_arr, &head);
393 dres = show_textbox_ext(_("Search Results"), (char *)
394 str_get(&res), 0, 0, keys, &vscroll,
395 &hscroll, &update_text, (void *)
396 &data);
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400397 again = false;
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400398 for (i = 0; i < JUMP_NB && keys[i]; i++)
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400399 if (dres == keys[i]) {
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400400 conf(targets[i]->parent, targets[i]);
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400401 again = true;
402 }
403 str_free(&res);
404 } while (again);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 free(sym_arr);
Yann E. MORIN337a2752012-10-20 01:06:23 +0200406 str_free(&title);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407}
408
409static void build_conf(struct menu *menu)
410{
411 struct symbol *sym;
412 struct property *prop;
413 struct menu *child;
414 int type, tmp, doint = 2;
415 tristate val;
416 char ch;
Li Zefan22c7eca2010-04-14 11:46:02 +0800417 bool visible;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Li Zefan22c7eca2010-04-14 11:46:02 +0800419 /*
420 * note: menu_is_visible() has side effect that it will
421 * recalc the value of the symbol.
422 */
423 visible = menu_is_visible(menu);
424 if (show_all_options && !menu_has_prompt(menu))
425 return;
426 else if (!show_all_options && !visible)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 return;
428
429 sym = menu->sym;
430 prop = menu->prompt;
431 if (!sym) {
432 if (prop && menu != current_menu) {
433 const char *prompt = menu_get_prompt(menu);
434 switch (prop->type) {
435 case P_MENU:
436 child_count++;
EGRY Gabor413f0062008-01-11 23:50:37 +0100437 prompt = _(prompt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 if (single_menu_mode) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200439 item_make("%s%*c%s",
440 menu->data ? "-->" : "++>",
441 indent + 1, ' ', prompt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 } else
Sam Ravnborg2982de62006-07-27 22:10:27 +0200443 item_make(" %*c%s --->", indent + 1, ' ', prompt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444
Sam Ravnborg2982de62006-07-27 22:10:27 +0200445 item_set_tag('m');
446 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 if (single_menu_mode && menu->data)
448 goto conf_childs;
449 return;
Sam Ravnborg48874072007-09-18 21:12:26 +0200450 case P_COMMENT:
451 if (prompt) {
452 child_count++;
EGRY Gabor413f0062008-01-11 23:50:37 +0100453 item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt));
Sam Ravnborg48874072007-09-18 21:12:26 +0200454 item_set_tag(':');
455 item_set_data(menu);
456 }
457 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 default:
459 if (prompt) {
460 child_count++;
EGRY Gabor413f0062008-01-11 23:50:37 +0100461 item_make("---%*c%s", indent + 1, ' ', _(prompt));
Sam Ravnborg2982de62006-07-27 22:10:27 +0200462 item_set_tag(':');
463 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 }
465 }
466 } else
467 doint = 0;
468 goto conf_childs;
469 }
470
471 type = sym_get_type(sym);
472 if (sym_is_choice(sym)) {
473 struct symbol *def_sym = sym_get_choice_value(sym);
474 struct menu *def_menu = NULL;
475
476 child_count++;
477 for (child = menu->list; child; child = child->next) {
478 if (menu_is_visible(child) && child->sym == def_sym)
479 def_menu = child;
480 }
481
482 val = sym_get_tristate_value(sym);
483 if (sym_is_changable(sym)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 switch (type) {
485 case S_BOOLEAN:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200486 item_make("[%c]", val == no ? ' ' : '*');
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 break;
488 case S_TRISTATE:
489 switch (val) {
490 case yes: ch = '*'; break;
491 case mod: ch = 'M'; break;
492 default: ch = ' '; break;
493 }
Sam Ravnborg2982de62006-07-27 22:10:27 +0200494 item_make("<%c>", ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 break;
496 }
Sam Ravnborg2982de62006-07-27 22:10:27 +0200497 item_set_tag('t');
498 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 } else {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200500 item_make(" ");
501 item_set_tag(def_menu ? 't' : ':');
502 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 }
504
EGRY Gabor413f0062008-01-11 23:50:37 +0100505 item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 if (val == yes) {
507 if (def_menu) {
EGRY Gabor413f0062008-01-11 23:50:37 +0100508 item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
Sam Ravnborg2982de62006-07-27 22:10:27 +0200509 item_add_str(" --->");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 if (def_menu->list) {
511 indent += 2;
512 build_conf(def_menu);
513 indent -= 2;
514 }
Sam Ravnborg2982de62006-07-27 22:10:27 +0200515 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 return;
517 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 } else {
519 if (menu == current_menu) {
EGRY Gabor413f0062008-01-11 23:50:37 +0100520 item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
Sam Ravnborg2982de62006-07-27 22:10:27 +0200521 item_set_tag(':');
522 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 goto conf_childs;
524 }
525 child_count++;
526 val = sym_get_tristate_value(sym);
527 if (sym_is_choice_value(sym) && val == yes) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200528 item_make(" ");
529 item_set_tag(':');
530 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 } else {
532 switch (type) {
533 case S_BOOLEAN:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 if (sym_is_changable(sym))
Sam Ravnborg2982de62006-07-27 22:10:27 +0200535 item_make("[%c]", val == no ? ' ' : '*');
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 else
Matej Laitlb5d609d2007-10-02 13:46:50 -0700537 item_make("-%c-", val == no ? ' ' : '*');
Sam Ravnborg2982de62006-07-27 22:10:27 +0200538 item_set_tag('t');
539 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 break;
541 case S_TRISTATE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 switch (val) {
543 case yes: ch = '*'; break;
544 case mod: ch = 'M'; break;
545 default: ch = ' '; break;
546 }
Matej Laitlb5d609d2007-10-02 13:46:50 -0700547 if (sym_is_changable(sym)) {
548 if (sym->rev_dep.tri == mod)
549 item_make("{%c}", ch);
550 else
551 item_make("<%c>", ch);
552 } else
553 item_make("-%c-", ch);
Sam Ravnborg2982de62006-07-27 22:10:27 +0200554 item_set_tag('t');
555 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 break;
557 default:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200558 tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
559 item_make("(%s)", sym_get_string_value(sym));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 tmp = indent - tmp + 4;
561 if (tmp < 0)
562 tmp = 0;
EGRY Gabor413f0062008-01-11 23:50:37 +0100563 item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
Sam Ravnborg2982de62006-07-27 22:10:27 +0200564 (sym_has_value(sym) || !sym_is_changable(sym)) ?
EGRY Gabor413f0062008-01-11 23:50:37 +0100565 "" : _(" (NEW)"));
Sam Ravnborg2982de62006-07-27 22:10:27 +0200566 item_set_tag('s');
567 item_set_data(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 goto conf_childs;
569 }
570 }
EGRY Gabor413f0062008-01-11 23:50:37 +0100571 item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
Sam Ravnborg2982de62006-07-27 22:10:27 +0200572 (sym_has_value(sym) || !sym_is_changable(sym)) ?
EGRY Gabor413f0062008-01-11 23:50:37 +0100573 "" : _(" (NEW)"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (menu->prompt->type == P_MENU) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200575 item_add_str(" --->");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 return;
577 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 }
579
580conf_childs:
581 indent += doint;
582 for (child = menu->list; child; child = child->next)
583 build_conf(child);
584 indent -= doint;
585}
586
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400587static void conf(struct menu *menu, struct menu *active_menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588{
589 struct menu *submenu;
590 const char *prompt = menu_get_prompt(menu);
591 struct symbol *sym;
Sam Ravnborg2982de62006-07-27 22:10:27 +0200592 int res;
593 int s_scroll = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 while (1) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200596 item_reset();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 current_menu = menu;
598 build_conf(menu);
599 if (!child_count)
600 break;
601 if (menu == &rootmenu) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200602 item_make("--- ");
603 item_set_tag(':');
604 item_make(_(" Load an Alternate Configuration File"));
605 item_set_tag('L');
606 item_make(_(" Save an Alternate Configuration File"));
607 item_set_tag('S');
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 }
Sam Ravnborge94c5bd2006-09-25 17:35:43 +0200609 dialog_clear();
EGRY Gabor413f0062008-01-11 23:50:37 +0100610 res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
Sam Ravnborg2982de62006-07-27 22:10:27 +0200611 _(menu_instructions),
Sam Ravnborg2982de62006-07-27 22:10:27 +0200612 active_menu, &s_scroll);
Sam Ravnborgc8dc68a2006-07-29 22:48:57 +0200613 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 break;
Sam Ravnborg2982de62006-07-27 22:10:27 +0200615 if (!item_activate_selected())
616 continue;
617 if (!item_tag())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 continue;
619
Sam Ravnborg2982de62006-07-27 22:10:27 +0200620 submenu = item_data();
621 active_menu = item_data();
Sam Ravnborgc8dc68a2006-07-29 22:48:57 +0200622 if (submenu)
623 sym = submenu->sym;
624 else
625 sym = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626
Sam Ravnborg2982de62006-07-27 22:10:27 +0200627 switch (res) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 case 0:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200629 switch (item_tag()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 case 'm':
631 if (single_menu_mode)
632 submenu->data = (void *) (long) !submenu->data;
633 else
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400634 conf(submenu, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 break;
636 case 't':
637 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
638 conf_choice(submenu);
639 else if (submenu->prompt->type == P_MENU)
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400640 conf(submenu, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 break;
642 case 's':
643 conf_string(submenu);
644 break;
645 case 'L':
646 conf_load();
647 break;
648 case 'S':
649 conf_save();
650 break;
651 }
652 break;
653 case 2:
654 if (sym)
655 show_help(submenu);
656 else
EGRY Gabor413f0062008-01-11 23:50:37 +0100657 show_helptext(_("README"), _(mconf_readme));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 break;
659 case 3:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200660 if (item_is_tag('t')) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 if (sym_set_tristate_value(sym, yes))
662 break;
663 if (sym_set_tristate_value(sym, mod))
664 show_textbox(NULL, setmod_text, 6, 74);
665 }
666 break;
667 case 4:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200668 if (item_is_tag('t'))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 sym_set_tristate_value(sym, no);
670 break;
671 case 5:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200672 if (item_is_tag('t'))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 sym_set_tristate_value(sym, mod);
674 break;
675 case 6:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200676 if (item_is_tag('t'))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 sym_toggle_tristate_value(sym);
Sam Ravnborg2982de62006-07-27 22:10:27 +0200678 else if (item_is_tag('m'))
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400679 conf(submenu, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 break;
681 case 7:
682 search_conf();
683 break;
Li Zefan22c7eca2010-04-14 11:46:02 +0800684 case 8:
685 show_all_options = !show_all_options;
686 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 }
688 }
689}
690
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400691static int show_textbox_ext(const char *title, char *text, int r, int c, int
692 *keys, int *vscroll, int *hscroll, update_text_fn
693 update_text, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694{
Sam Ravnborge94c5bd2006-09-25 17:35:43 +0200695 dialog_clear();
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400696 return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
697 update_text, data);
Benjamin Poirier537ddae2012-08-23 14:55:04 -0400698}
699
700static void show_textbox(const char *title, const char *text, int r, int c)
701{
Benjamin Poirier95ac9b32012-08-23 14:55:08 -0400702 show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
703 NULL, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704}
705
706static void show_helptext(const char *title, const char *text)
707{
708 show_textbox(title, text, 0, 0);
709}
710
711static void show_help(struct menu *menu)
712{
713 struct gstr help = str_new();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714
Vadim Bendebury (вб)da60fbb2009-12-20 00:29:49 -0800715 help.max_width = getmaxx(stdscr) - 10;
Cheng Renquan1d525e72009-07-12 16:11:45 +0800716 menu_get_ext_help(menu, &help);
717
EGRY Gabor413f0062008-01-11 23:50:37 +0100718 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 str_free(&help);
720}
721
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722static void conf_choice(struct menu *menu)
723{
EGRY Gabor413f0062008-01-11 23:50:37 +0100724 const char *prompt = _(menu_get_prompt(menu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 struct menu *child;
726 struct symbol *active;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727
728 active = sym_get_choice_value(menu->sym);
729 while (1) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200730 int res;
731 int selected;
732 item_reset();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733
734 current_menu = menu;
735 for (child = menu->list; child; child = child->next) {
736 if (!menu_is_visible(child))
737 continue;
Peter Korsgaardaf6c1592009-02-15 22:15:16 +0100738 if (child->sym)
739 item_make("%s", _(menu_get_prompt(child)));
740 else {
741 item_make("*** %s ***", _(menu_get_prompt(child)));
742 item_set_tag(':');
743 }
Sam Ravnborg2982de62006-07-27 22:10:27 +0200744 item_set_data(child);
745 if (child->sym == active)
746 item_set_selected(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 if (child->sym == sym_get_choice_value(menu->sym))
Sam Ravnborg2982de62006-07-27 22:10:27 +0200748 item_set_tag('X');
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 }
Sam Ravnborge94c5bd2006-09-25 17:35:43 +0200750 dialog_clear();
EGRY Gabor413f0062008-01-11 23:50:37 +0100751 res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
Sam Ravnborg2982de62006-07-27 22:10:27 +0200752 _(radiolist_instructions),
753 15, 70, 6);
754 selected = item_activate_selected();
755 switch (res) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 case 0:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200757 if (selected) {
758 child = item_data();
Peter Korsgaardaf6c1592009-02-15 22:15:16 +0100759 if (!child->sym)
760 break;
761
Sam Ravnborg2982de62006-07-27 22:10:27 +0200762 sym_set_tristate_value(child->sym, yes);
763 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 return;
765 case 1:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200766 if (selected) {
767 child = item_data();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 show_help(child);
769 active = child->sym;
770 } else
771 show_help(menu);
772 break;
Sam Ravnborgf3cbcdc2006-07-28 23:57:48 +0200773 case KEY_ESC:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 return;
Sam Ravnborgc8dc68a2006-07-29 22:48:57 +0200775 case -ERRDISPLAYTOOSMALL:
776 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 }
778 }
779}
780
781static void conf_string(struct menu *menu)
782{
783 const char *prompt = menu_get_prompt(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
785 while (1) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200786 int res;
Sam Ravnborgc4143a82008-05-04 21:03:20 +0200787 const char *heading;
Sam Ravnborg2982de62006-07-27 22:10:27 +0200788
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 switch (sym_get_type(menu->sym)) {
790 case S_INT:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200791 heading = _(inputbox_instructions_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 break;
793 case S_HEX:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200794 heading = _(inputbox_instructions_hex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 break;
796 case S_STRING:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200797 heading = _(inputbox_instructions_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 break;
799 default:
EGRY Gabor413f0062008-01-11 23:50:37 +0100800 heading = _("Internal mconf error!");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 }
Sam Ravnborge94c5bd2006-09-25 17:35:43 +0200802 dialog_clear();
EGRY Gabor413f0062008-01-11 23:50:37 +0100803 res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
Sam Ravnborg2982de62006-07-27 22:10:27 +0200804 heading, 10, 75,
805 sym_get_string_value(menu->sym));
806 switch (res) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 case 0:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200808 if (sym_set_string_value(menu->sym, dialog_input_result))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700810 show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 break;
812 case 1:
813 show_help(menu);
814 break;
Sam Ravnborgf3cbcdc2006-07-28 23:57:48 +0200815 case KEY_ESC:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 return;
817 }
818 }
819}
820
821static void conf_load(void)
822{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
824 while (1) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200825 int res;
Sam Ravnborge94c5bd2006-09-25 17:35:43 +0200826 dialog_clear();
Sam Ravnborg2982de62006-07-27 22:10:27 +0200827 res = dialog_inputbox(NULL, load_config_text,
828 11, 55, filename);
829 switch(res) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 case 0:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200831 if (!dialog_input_result[0])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 return;
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100833 if (!conf_read(dialog_input_result)) {
834 set_config_filename(dialog_input_result);
Sam Ravnborg36ef8052008-02-02 20:44:09 +0100835 sym_set_change_count(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 return;
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100837 }
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700838 show_textbox(NULL, _("File does not exist!"), 5, 38);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 break;
840 case 1:
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700841 show_helptext(_("Load Alternate Configuration"), load_config_help);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 break;
Sam Ravnborgf3cbcdc2006-07-28 23:57:48 +0200843 case KEY_ESC:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 return;
845 }
846 }
847}
848
849static void conf_save(void)
850{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 while (1) {
Sam Ravnborg2982de62006-07-27 22:10:27 +0200852 int res;
Sam Ravnborge94c5bd2006-09-25 17:35:43 +0200853 dialog_clear();
Sam Ravnborg2982de62006-07-27 22:10:27 +0200854 res = dialog_inputbox(NULL, save_config_text,
855 11, 55, filename);
856 switch(res) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 case 0:
Sam Ravnborg2982de62006-07-27 22:10:27 +0200858 if (!dialog_input_result[0])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 return;
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100860 if (!conf_write(dialog_input_result)) {
861 set_config_filename(dialog_input_result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 return;
Sam Ravnborg95e30f92007-03-18 10:48:46 +0100863 }
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700864 show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 break;
866 case 1:
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700867 show_helptext(_("Save Alternate Configuration"), save_config_help);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 break;
Sam Ravnborgf3cbcdc2006-07-28 23:57:48 +0200869 case KEY_ESC:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 return;
871 }
872 }
873}
874
Davidlohr Bueso564899f2011-08-21 22:04:09 -0300875static int handle_exit(void)
876{
877 int res;
878
879 dialog_clear();
880 if (conf_get_changed())
881 res = dialog_yesno(NULL,
882 _("Do you wish to save your new configuration ?\n"
883 "<ESC><ESC> to continue."),
884 6, 60);
885 else
886 res = -1;
887
888 end_dialog(saved_x, saved_y);
889
890 switch (res) {
891 case 0:
892 if (conf_write(filename)) {
893 fprintf(stderr, _("\n\n"
894 "Error while writing of the configuration.\n"
895 "Your configuration changes were NOT saved."
896 "\n\n"));
897 return 1;
898 }
899 /* fall through */
900 case -1:
901 printf(_("\n\n"
902 "*** End of the configuration.\n"
903 "*** Execute 'make' to start the build or try 'make help'."
904 "\n\n"));
905 res = 0;
906 break;
907 default:
908 fprintf(stderr, _("\n\n"
909 "Your configuration changes were NOT saved."
910 "\n\n"));
Li Zefan30c4eaa2012-01-16 15:57:39 +0800911 if (res != KEY_ESC)
912 res = 0;
Davidlohr Bueso564899f2011-08-21 22:04:09 -0300913 }
914
915 return res;
916}
917
918static void sig_handler(int signo)
919{
920 exit(handle_exit());
921}
922
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923int main(int ac, char **av)
924{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 char *mode;
Sam Ravnborg2982de62006-07-27 22:10:27 +0200926 int res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700928 setlocale(LC_ALL, "");
929 bindtextdomain(PACKAGE, LOCALEDIR);
930 textdomain(PACKAGE);
931
Davidlohr Bueso564899f2011-08-21 22:04:09 -0300932 signal(SIGINT, sig_handler);
933
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 conf_parse(av[1]);
935 conf_read(NULL);
936
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 mode = getenv("MENUCONFIG_MODE");
938 if (mode) {
939 if (!strcasecmp(mode, "single_menu"))
940 single_menu_mode = 1;
941 }
942
Ladislav Michl09af0912007-12-17 19:07:41 +0100943 if (init_dialog(NULL)) {
944 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
945 fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
946 return 1;
947 }
948
Sam Ravnborgd802b502007-04-01 22:29:38 +0200949 set_config_filename(conf_get_configname());
Sam Ravnborgf3cbcdc2006-07-28 23:57:48 +0200950 do {
Benjamin Poirier5e609ad2012-08-23 14:55:06 -0400951 conf(&rootmenu, NULL);
Davidlohr Bueso564899f2011-08-21 22:04:09 -0300952 res = handle_exit();
Sam Ravnborgf3cbcdc2006-07-28 23:57:48 +0200953 } while (res == KEY_ESC);
Karsten Wieseb3214292006-12-13 00:34:06 -0800954
Davidlohr Bueso564899f2011-08-21 22:04:09 -0300955 return res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956}
Sam Ravnborgc4143a82008-05-04 21:03:20 +0200957