xref: /nrf52832-nimble/rt-thread/tools/kconfig-frontends/frontends/mconf/mconf.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (C) 2002 Roman Zippel <[email protected]>
3*10465441SEvalZero  * Released under the terms of the GNU GPL v2.0.
4*10465441SEvalZero  *
5*10465441SEvalZero  * Introduced single menu mode (show all sub-menus in one large tree).
6*10465441SEvalZero  * 2002-11-06 Petr Baudis <[email protected]>
7*10465441SEvalZero  *
8*10465441SEvalZero  * i18n, 2005, Arnaldo Carvalho de Melo <[email protected]>
9*10465441SEvalZero  */
10*10465441SEvalZero 
11*10465441SEvalZero #include <ctype.h>
12*10465441SEvalZero #include <errno.h>
13*10465441SEvalZero #include <fcntl.h>
14*10465441SEvalZero #include <limits.h>
15*10465441SEvalZero #include <stdarg.h>
16*10465441SEvalZero #include <stdlib.h>
17*10465441SEvalZero #include <string.h>
18*10465441SEvalZero #include <signal.h>
19*10465441SEvalZero #include <unistd.h>
20*10465441SEvalZero #include <locale.h>
21*10465441SEvalZero 
22*10465441SEvalZero #include "lkc.h"
23*10465441SEvalZero #include "lxdialog/dialog.h"
24*10465441SEvalZero 
25*10465441SEvalZero static const char mconf_readme[] = N_(
26*10465441SEvalZero "Overview\n"
27*10465441SEvalZero "--------\n"
28*10465441SEvalZero "This interface lets you select features and parameters for the build.\n"
29*10465441SEvalZero "Features can either be built-in, modularized, or ignored. Parameters\n"
30*10465441SEvalZero "must be entered in as decimal or hexadecimal numbers or text.\n"
31*10465441SEvalZero "\n"
32*10465441SEvalZero "Menu items beginning with following braces represent features that\n"
33*10465441SEvalZero "  [ ] can be built in or removed\n"
34*10465441SEvalZero "  < > can be built in, modularized or removed\n"
35*10465441SEvalZero "  { } can be built in or modularized (selected by other feature)\n"
36*10465441SEvalZero "  - - are selected by other feature,\n"
37*10465441SEvalZero "while *, M or whitespace inside braces means to build in, build as\n"
38*10465441SEvalZero "a module or to exclude the feature respectively.\n"
39*10465441SEvalZero "\n"
40*10465441SEvalZero "To change any of these features, highlight it with the cursor\n"
41*10465441SEvalZero "keys and press <Y> to build it in, <M> to make it a module or\n"
42*10465441SEvalZero "<N> to remove it.  You may also press the <Space Bar> to cycle\n"
43*10465441SEvalZero "through the available options (i.e. Y->N->M->Y).\n"
44*10465441SEvalZero "\n"
45*10465441SEvalZero "Some additional keyboard hints:\n"
46*10465441SEvalZero "\n"
47*10465441SEvalZero "Menus\n"
48*10465441SEvalZero "----------\n"
49*10465441SEvalZero "o  Use the Up/Down arrow keys (cursor keys) to highlight the item you\n"
50*10465441SEvalZero "   wish to change or the submenu you wish to select and press <Enter>.\n"
51*10465441SEvalZero "   Submenus are designated by \"--->\", empty ones by \"----\".\n"
52*10465441SEvalZero "\n"
53*10465441SEvalZero "   Shortcut: Press the option's highlighted letter (hotkey).\n"
54*10465441SEvalZero "             Pressing a hotkey more than once will sequence\n"
55*10465441SEvalZero "             through all visible items which use that hotkey.\n"
56*10465441SEvalZero "\n"
57*10465441SEvalZero "   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
58*10465441SEvalZero "   unseen options into view.\n"
59*10465441SEvalZero "\n"
60*10465441SEvalZero "o  To exit a menu use the cursor keys to highlight the <Exit> button\n"
61*10465441SEvalZero "   and press <ENTER>.\n"
62*10465441SEvalZero "\n"
63*10465441SEvalZero "   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
64*10465441SEvalZero "             using those letters.  You may press a single <ESC>, but\n"
65*10465441SEvalZero "             there is a delayed response which you may find annoying.\n"
66*10465441SEvalZero "\n"
67*10465441SEvalZero "   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
68*10465441SEvalZero "   <Exit>, <Help>, <Save>, and <Load>.\n"
69*10465441SEvalZero "\n"
70*10465441SEvalZero "o  To get help with an item, use the cursor keys to highlight <Help>\n"
71*10465441SEvalZero "   and press <ENTER>.\n"
72*10465441SEvalZero "\n"
73*10465441SEvalZero "   Shortcut: Press <H> or <?>.\n"
74*10465441SEvalZero "\n"
75*10465441SEvalZero "o  To toggle the display of hidden options, press <Z>.\n"
76*10465441SEvalZero "\n"
77*10465441SEvalZero "\n"
78*10465441SEvalZero "Radiolists  (Choice lists)\n"
79*10465441SEvalZero "-----------\n"
80*10465441SEvalZero "o  Use the cursor keys to select the option you wish to set and press\n"
81*10465441SEvalZero "   <S> or the <SPACE BAR>.\n"
82*10465441SEvalZero "\n"
83*10465441SEvalZero "   Shortcut: Press the first letter of the option you wish to set then\n"
84*10465441SEvalZero "             press <S> or <SPACE BAR>.\n"
85*10465441SEvalZero "\n"
86*10465441SEvalZero "o  To see available help for the item, use the cursor keys to highlight\n"
87*10465441SEvalZero "   <Help> and Press <ENTER>.\n"
88*10465441SEvalZero "\n"
89*10465441SEvalZero "   Shortcut: Press <H> or <?>.\n"
90*10465441SEvalZero "\n"
91*10465441SEvalZero "   Also, the <TAB> and cursor keys will cycle between <Select> and\n"
92*10465441SEvalZero "   <Help>\n"
93*10465441SEvalZero "\n"
94*10465441SEvalZero "\n"
95*10465441SEvalZero "Data Entry\n"
96*10465441SEvalZero "-----------\n"
97*10465441SEvalZero "o  Enter the requested information and press <ENTER>\n"
98*10465441SEvalZero "   If you are entering hexadecimal values, it is not necessary to\n"
99*10465441SEvalZero "   add the '0x' prefix to the entry.\n"
100*10465441SEvalZero "\n"
101*10465441SEvalZero "o  For help, use the <TAB> or cursor keys to highlight the help option\n"
102*10465441SEvalZero "   and press <ENTER>.  You can try <TAB><H> as well.\n"
103*10465441SEvalZero "\n"
104*10465441SEvalZero "\n"
105*10465441SEvalZero "Text Box    (Help Window)\n"
106*10465441SEvalZero "--------\n"
107*10465441SEvalZero "o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
108*10465441SEvalZero "   keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for\n"
109*10465441SEvalZero "   those who are familiar with less and lynx.\n"
110*10465441SEvalZero "\n"
111*10465441SEvalZero "o  Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n"
112*10465441SEvalZero "\n"
113*10465441SEvalZero "\n"
114*10465441SEvalZero "Alternate Configuration Files\n"
115*10465441SEvalZero "-----------------------------\n"
116*10465441SEvalZero "Menuconfig supports the use of alternate configuration files for\n"
117*10465441SEvalZero "those who, for various reasons, find it necessary to switch\n"
118*10465441SEvalZero "between different configurations.\n"
119*10465441SEvalZero "\n"
120*10465441SEvalZero "The <Save> button will let you save the current configuration to\n"
121*10465441SEvalZero "a file of your choosing.  Use the <Load> button to load a previously\n"
122*10465441SEvalZero "saved alternate configuration.\n"
123*10465441SEvalZero "\n"
124*10465441SEvalZero "Even if you don't use alternate configuration files, but you find\n"
125*10465441SEvalZero "during a Menuconfig session that you have completely messed up your\n"
126*10465441SEvalZero "settings, you may use the <Load> button to restore your previously\n"
127*10465441SEvalZero "saved settings from \".config\" without restarting Menuconfig.\n"
128*10465441SEvalZero "\n"
129*10465441SEvalZero "Other information\n"
130*10465441SEvalZero "-----------------\n"
131*10465441SEvalZero "If you use Menuconfig in an XTERM window, make sure you have your\n"
132*10465441SEvalZero "$TERM variable set to point to an xterm definition which supports\n"
133*10465441SEvalZero "color.  Otherwise, Menuconfig will look rather bad.  Menuconfig will\n"
134*10465441SEvalZero "not display correctly in an RXVT window because rxvt displays only one\n"
135*10465441SEvalZero "intensity of color, bright.\n"
136*10465441SEvalZero "\n"
137*10465441SEvalZero "Menuconfig will display larger menus on screens or xterms which are\n"
138*10465441SEvalZero "set to display more than the standard 25 row by 80 column geometry.\n"
139*10465441SEvalZero "In order for this to work, the \"stty size\" command must be able to\n"
140*10465441SEvalZero "display the screen's current row and column geometry.  I STRONGLY\n"
141*10465441SEvalZero "RECOMMEND that you make sure you do NOT have the shell variables\n"
142*10465441SEvalZero "LINES and COLUMNS exported into your environment.  Some distributions\n"
143*10465441SEvalZero "export those variables via /etc/profile.  Some ncurses programs can\n"
144*10465441SEvalZero "become confused when those variables (LINES & COLUMNS) don't reflect\n"
145*10465441SEvalZero "the true screen size.\n"
146*10465441SEvalZero "\n"
147*10465441SEvalZero "Optional personality available\n"
148*10465441SEvalZero "------------------------------\n"
149*10465441SEvalZero "If you prefer to have all of the options listed in a single menu,\n"
150*10465441SEvalZero "rather than the default multimenu hierarchy, run the menuconfig with\n"
151*10465441SEvalZero "MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
152*10465441SEvalZero "\n"
153*10465441SEvalZero "make MENUCONFIG_MODE=single_menu menuconfig\n"
154*10465441SEvalZero "\n"
155*10465441SEvalZero "<Enter> will then unroll the appropriate category, or enfold it if it\n"
156*10465441SEvalZero "is already unrolled.\n"
157*10465441SEvalZero "\n"
158*10465441SEvalZero "Note that this mode can eventually be a little more CPU expensive\n"
159*10465441SEvalZero "(especially with a larger number of unrolled categories) than the\n"
160*10465441SEvalZero "default mode.\n"
161*10465441SEvalZero "\n"
162*10465441SEvalZero "Different color themes available\n"
163*10465441SEvalZero "--------------------------------\n"
164*10465441SEvalZero "It is possible to select different color themes using the variable\n"
165*10465441SEvalZero "MENUCONFIG_COLOR. To select a theme use:\n"
166*10465441SEvalZero "\n"
167*10465441SEvalZero "make MENUCONFIG_COLOR=<theme> menuconfig\n"
168*10465441SEvalZero "\n"
169*10465441SEvalZero "Available themes are\n"
170*10465441SEvalZero " mono       => selects colors suitable for monochrome displays\n"
171*10465441SEvalZero " blackbg    => selects a color scheme with black background\n"
172*10465441SEvalZero " classic    => theme with blue background. The classic look\n"
173*10465441SEvalZero " bluetitle  => an LCD friendly version of classic. (default)\n"
174*10465441SEvalZero "\n"),
175*10465441SEvalZero menu_instructions[] = N_(
176*10465441SEvalZero     "Arrow keys navigate the menu.  "
177*10465441SEvalZero     "<Enter> selects submenus ---> (or empty submenus ----).  "
178*10465441SEvalZero     "Highlighted letters are hotkeys.  "
179*10465441SEvalZero     "Pressing <Y> includes, <N> excludes, <M> modularizes features.  "
180*10465441SEvalZero     "Press <Esc><Esc> to exit, <?> for Help, </> for Search.  "
181*10465441SEvalZero     "Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"),
182*10465441SEvalZero radiolist_instructions[] = N_(
183*10465441SEvalZero     "Use the arrow keys to navigate this window or "
184*10465441SEvalZero     "press the hotkey of the item you wish to select "
185*10465441SEvalZero     "followed by the <SPACE BAR>. "
186*10465441SEvalZero     "Press <?> for additional information about this option."),
187*10465441SEvalZero inputbox_instructions_int[] = N_(
188*10465441SEvalZero     "Please enter a decimal value. "
189*10465441SEvalZero     "Fractions will not be accepted.  "
190*10465441SEvalZero     "Use the <TAB> key to move from the input field to the buttons below it."),
191*10465441SEvalZero inputbox_instructions_hex[] = N_(
192*10465441SEvalZero     "Please enter a hexadecimal value. "
193*10465441SEvalZero     "Use the <TAB> key to move from the input field to the buttons below it."),
194*10465441SEvalZero inputbox_instructions_string[] = N_(
195*10465441SEvalZero     "Please enter a string value. "
196*10465441SEvalZero     "Use the <TAB> key to move from the input field to the buttons below it."),
197*10465441SEvalZero setmod_text[] = N_(
198*10465441SEvalZero     "This feature depends on another which has been configured as a module.\n"
199*10465441SEvalZero     "As a result, this feature will be built as a module."),
200*10465441SEvalZero load_config_text[] = N_(
201*10465441SEvalZero     "Enter the name of the configuration file you wish to load.  "
202*10465441SEvalZero     "Accept the name shown to restore the configuration you "
203*10465441SEvalZero     "last retrieved.  Leave blank to abort."),
204*10465441SEvalZero load_config_help[] = N_(
205*10465441SEvalZero     "\n"
206*10465441SEvalZero     "For various reasons, one may wish to keep several different\n"
207*10465441SEvalZero     "configurations available on a single machine.\n"
208*10465441SEvalZero     "\n"
209*10465441SEvalZero     "If you have saved a previous configuration in a file other than the\n"
210*10465441SEvalZero     "default one, entering its name here will allow you to modify that\n"
211*10465441SEvalZero     "configuration.\n"
212*10465441SEvalZero     "\n"
213*10465441SEvalZero     "If you are uncertain, then you have probably never used alternate\n"
214*10465441SEvalZero     "configuration files. You should therefore leave this blank to abort.\n"),
215*10465441SEvalZero save_config_text[] = N_(
216*10465441SEvalZero     "Enter a filename to which this configuration should be saved "
217*10465441SEvalZero     "as an alternate.  Leave blank to abort."),
218*10465441SEvalZero save_config_help[] = N_(
219*10465441SEvalZero     "\n"
220*10465441SEvalZero     "For various reasons, one may wish to keep different configurations\n"
221*10465441SEvalZero     "available on a single machine.\n"
222*10465441SEvalZero     "\n"
223*10465441SEvalZero     "Entering a file name here will allow you to later retrieve, modify\n"
224*10465441SEvalZero     "and use the current configuration as an alternate to whatever\n"
225*10465441SEvalZero     "configuration options you have selected at that time.\n"
226*10465441SEvalZero     "\n"
227*10465441SEvalZero     "If you are uncertain what all this means then you should probably\n"
228*10465441SEvalZero     "leave this blank.\n"),
229*10465441SEvalZero search_help[] = N_(
230*10465441SEvalZero     "\n"
231*10465441SEvalZero     "Search for symbols and display their relations.\n"
232*10465441SEvalZero     "Regular expressions are allowed.\n"
233*10465441SEvalZero     "Example: search for \"^FOO\"\n"
234*10465441SEvalZero     "Result:\n"
235*10465441SEvalZero     "-----------------------------------------------------------------\n"
236*10465441SEvalZero     "Symbol: FOO [=m]\n"
237*10465441SEvalZero     "Type  : tristate\n"
238*10465441SEvalZero     "Prompt: Foo bus is used to drive the bar HW\n"
239*10465441SEvalZero     "  Location:\n"
240*10465441SEvalZero     "    -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
241*10465441SEvalZero     "      -> PCI support (PCI [=y])\n"
242*10465441SEvalZero     "(1)     -> PCI access mode (<choice> [=y])\n"
243*10465441SEvalZero     "  Defined at drivers/pci/Kconfig:47\n"
244*10465441SEvalZero     "  Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
245*10465441SEvalZero     "  Selects: LIBCRC32\n"
246*10465441SEvalZero     "  Selected by: BAR [=n]\n"
247*10465441SEvalZero     "-----------------------------------------------------------------\n"
248*10465441SEvalZero     "o The line 'Type:' shows the type of the configuration option for\n"
249*10465441SEvalZero     "  this symbol (boolean, tristate, string, ...)\n"
250*10465441SEvalZero     "o The line 'Prompt:' shows the text used in the menu structure for\n"
251*10465441SEvalZero     "  this symbol\n"
252*10465441SEvalZero     "o The 'Defined at' line tells at what file / line number the symbol\n"
253*10465441SEvalZero     "  is defined\n"
254*10465441SEvalZero     "o The 'Depends on:' line tells what symbols need to be defined for\n"
255*10465441SEvalZero     "  this symbol to be visible in the menu (selectable)\n"
256*10465441SEvalZero     "o The 'Location:' lines tells where in the menu structure this symbol\n"
257*10465441SEvalZero     "  is located\n"
258*10465441SEvalZero     "    A location followed by a [=y] indicates that this is a\n"
259*10465441SEvalZero     "    selectable menu item - and the current value is displayed inside\n"
260*10465441SEvalZero     "    brackets.\n"
261*10465441SEvalZero     "    Press the key in the (#) prefix to jump directly to that\n"
262*10465441SEvalZero     "    location. You will be returned to the current search results\n"
263*10465441SEvalZero     "    after exiting this new menu.\n"
264*10465441SEvalZero     "o The 'Selects:' line tells what symbols will be automatically\n"
265*10465441SEvalZero     "  selected if this symbol is selected (y or m)\n"
266*10465441SEvalZero     "o The 'Selected by' line tells what symbol has selected this symbol\n"
267*10465441SEvalZero     "\n"
268*10465441SEvalZero     "Only relevant lines are shown.\n"
269*10465441SEvalZero     "\n\n"
270*10465441SEvalZero     "Search examples:\n"
271*10465441SEvalZero     "Examples: USB  => find all symbols containing USB\n"
272*10465441SEvalZero     "          ^USB => find all symbols starting with USB\n"
273*10465441SEvalZero     "          USB$ => find all symbols ending with USB\n"
274*10465441SEvalZero     "\n");
275*10465441SEvalZero 
276*10465441SEvalZero static int indent;
277*10465441SEvalZero static struct menu *current_menu;
278*10465441SEvalZero static int child_count;
279*10465441SEvalZero static int single_menu_mode;
280*10465441SEvalZero static int show_all_options;
281*10465441SEvalZero static int save_and_exit;
282*10465441SEvalZero static int silent;
283*10465441SEvalZero 
284*10465441SEvalZero static void conf(struct menu *menu, struct menu *active_menu);
285*10465441SEvalZero static void conf_choice(struct menu *menu);
286*10465441SEvalZero static void conf_string(struct menu *menu);
287*10465441SEvalZero static void conf_load(void);
288*10465441SEvalZero static void conf_save(void);
289*10465441SEvalZero static int show_textbox_ext(const char *title, char *text, int r, int c,
290*10465441SEvalZero                 int *keys, int *vscroll, int *hscroll,
291*10465441SEvalZero                 update_text_fn update_text, void *data);
292*10465441SEvalZero static void show_textbox(const char *title, const char *text, int r, int c);
293*10465441SEvalZero static void show_helptext(const char *title, const char *text);
294*10465441SEvalZero static void show_help(struct menu *menu);
295*10465441SEvalZero 
296*10465441SEvalZero static char filename[PATH_MAX+1];
set_config_filename(const char * config_filename)297*10465441SEvalZero static void set_config_filename(const char *config_filename)
298*10465441SEvalZero {
299*10465441SEvalZero     static char menu_backtitle[PATH_MAX+128];
300*10465441SEvalZero     int size;
301*10465441SEvalZero 
302*10465441SEvalZero     size = snprintf(menu_backtitle, sizeof(menu_backtitle),
303*10465441SEvalZero             "%s - %s", config_filename, rootmenu.prompt->text);
304*10465441SEvalZero     if (size >= sizeof(menu_backtitle))
305*10465441SEvalZero         menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
306*10465441SEvalZero     set_dialog_backtitle(menu_backtitle);
307*10465441SEvalZero 
308*10465441SEvalZero     size = snprintf(filename, sizeof(filename), "%s", config_filename);
309*10465441SEvalZero     if (size >= sizeof(filename))
310*10465441SEvalZero         filename[sizeof(filename)-1] = '\0';
311*10465441SEvalZero }
312*10465441SEvalZero 
313*10465441SEvalZero struct subtitle_part {
314*10465441SEvalZero     struct list_head entries;
315*10465441SEvalZero     const char *text;
316*10465441SEvalZero };
317*10465441SEvalZero static LIST_HEAD(trail);
318*10465441SEvalZero 
319*10465441SEvalZero static struct subtitle_list *subtitles;
set_subtitle(void)320*10465441SEvalZero static void set_subtitle(void)
321*10465441SEvalZero {
322*10465441SEvalZero     struct subtitle_part *sp;
323*10465441SEvalZero     struct subtitle_list *pos, *tmp;
324*10465441SEvalZero 
325*10465441SEvalZero     for (pos = subtitles; pos != NULL; pos = tmp) {
326*10465441SEvalZero         tmp = pos->next;
327*10465441SEvalZero         free(pos);
328*10465441SEvalZero     }
329*10465441SEvalZero 
330*10465441SEvalZero     subtitles = NULL;
331*10465441SEvalZero     list_for_each_entry(sp, &trail, entries) {
332*10465441SEvalZero         if (sp->text) {
333*10465441SEvalZero             if (pos) {
334*10465441SEvalZero                 pos->next = xcalloc(1, sizeof(*pos));
335*10465441SEvalZero                 pos = pos->next;
336*10465441SEvalZero             } else {
337*10465441SEvalZero                 subtitles = pos = xcalloc(1, sizeof(*pos));
338*10465441SEvalZero             }
339*10465441SEvalZero             pos->text = sp->text;
340*10465441SEvalZero         }
341*10465441SEvalZero     }
342*10465441SEvalZero 
343*10465441SEvalZero     set_dialog_subtitles(subtitles);
344*10465441SEvalZero }
345*10465441SEvalZero 
reset_subtitle(void)346*10465441SEvalZero static void reset_subtitle(void)
347*10465441SEvalZero {
348*10465441SEvalZero     struct subtitle_list *pos, *tmp;
349*10465441SEvalZero 
350*10465441SEvalZero     for (pos = subtitles; pos != NULL; pos = tmp) {
351*10465441SEvalZero         tmp = pos->next;
352*10465441SEvalZero         free(pos);
353*10465441SEvalZero     }
354*10465441SEvalZero     subtitles = NULL;
355*10465441SEvalZero     set_dialog_subtitles(subtitles);
356*10465441SEvalZero }
357*10465441SEvalZero 
358*10465441SEvalZero struct search_data {
359*10465441SEvalZero     struct list_head *head;
360*10465441SEvalZero     struct menu **targets;
361*10465441SEvalZero     int *keys;
362*10465441SEvalZero };
363*10465441SEvalZero 
update_text(char * buf,size_t start,size_t end,void * _data)364*10465441SEvalZero static void update_text(char *buf, size_t start, size_t end, void *_data)
365*10465441SEvalZero {
366*10465441SEvalZero     struct search_data *data = _data;
367*10465441SEvalZero     struct jump_key *pos;
368*10465441SEvalZero     int k = 0;
369*10465441SEvalZero 
370*10465441SEvalZero     list_for_each_entry(pos, data->head, entries) {
371*10465441SEvalZero         if (pos->offset >= start && pos->offset < end) {
372*10465441SEvalZero             char header[4];
373*10465441SEvalZero 
374*10465441SEvalZero             if (k < JUMP_NB) {
375*10465441SEvalZero                 int key = '0' + (pos->index % JUMP_NB) + 1;
376*10465441SEvalZero 
377*10465441SEvalZero                 sprintf(header, "(%c)", key);
378*10465441SEvalZero                 data->keys[k] = key;
379*10465441SEvalZero                 data->targets[k] = pos->target;
380*10465441SEvalZero                 k++;
381*10465441SEvalZero             } else {
382*10465441SEvalZero                 sprintf(header, "   ");
383*10465441SEvalZero             }
384*10465441SEvalZero 
385*10465441SEvalZero             memcpy(buf + pos->offset, header, sizeof(header) - 1);
386*10465441SEvalZero         }
387*10465441SEvalZero     }
388*10465441SEvalZero     data->keys[k] = 0;
389*10465441SEvalZero }
390*10465441SEvalZero 
search_conf(void)391*10465441SEvalZero static void search_conf(void)
392*10465441SEvalZero {
393*10465441SEvalZero     struct symbol **sym_arr;
394*10465441SEvalZero     struct gstr res;
395*10465441SEvalZero     struct gstr title;
396*10465441SEvalZero     char *dialog_input;
397*10465441SEvalZero     int dres, vscroll = 0, hscroll = 0;
398*10465441SEvalZero     bool again;
399*10465441SEvalZero     struct gstr sttext;
400*10465441SEvalZero     struct subtitle_part stpart;
401*10465441SEvalZero 
402*10465441SEvalZero     title = str_new();
403*10465441SEvalZero     str_printf( &title, _("Enter (sub)string or regexp to search for "
404*10465441SEvalZero                   "(with or without \"%s\")"), CONFIG_);
405*10465441SEvalZero 
406*10465441SEvalZero again:
407*10465441SEvalZero     dialog_clear();
408*10465441SEvalZero     dres = dialog_inputbox(_("Search Configuration Parameter"),
409*10465441SEvalZero                   str_get(&title),
410*10465441SEvalZero                   10, 75, "");
411*10465441SEvalZero     switch (dres) {
412*10465441SEvalZero     case 0:
413*10465441SEvalZero         break;
414*10465441SEvalZero     case 1:
415*10465441SEvalZero         show_helptext(_("Search Configuration"), search_help);
416*10465441SEvalZero         goto again;
417*10465441SEvalZero     default:
418*10465441SEvalZero         str_free(&title);
419*10465441SEvalZero         return;
420*10465441SEvalZero     }
421*10465441SEvalZero 
422*10465441SEvalZero     /* strip the prefix if necessary */
423*10465441SEvalZero     dialog_input = dialog_input_result;
424*10465441SEvalZero     if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
425*10465441SEvalZero         dialog_input += strlen(CONFIG_);
426*10465441SEvalZero 
427*10465441SEvalZero     sttext = str_new();
428*10465441SEvalZero     str_printf(&sttext, "Search (%s)", dialog_input_result);
429*10465441SEvalZero     stpart.text = str_get(&sttext);
430*10465441SEvalZero     list_add_tail(&stpart.entries, &trail);
431*10465441SEvalZero 
432*10465441SEvalZero     sym_arr = sym_re_search(dialog_input);
433*10465441SEvalZero     do {
434*10465441SEvalZero         LIST_HEAD(head);
435*10465441SEvalZero         struct menu *targets[JUMP_NB];
436*10465441SEvalZero         int keys[JUMP_NB + 1], i;
437*10465441SEvalZero         struct search_data data = {
438*10465441SEvalZero             .head = &head,
439*10465441SEvalZero             .targets = targets,
440*10465441SEvalZero             .keys = keys,
441*10465441SEvalZero         };
442*10465441SEvalZero         struct jump_key *pos, *tmp;
443*10465441SEvalZero 
444*10465441SEvalZero         res = get_relations_str(sym_arr, &head);
445*10465441SEvalZero         set_subtitle();
446*10465441SEvalZero         dres = show_textbox_ext(_("Search Results"), (char *)
447*10465441SEvalZero                     str_get(&res), 0, 0, keys, &vscroll,
448*10465441SEvalZero                     &hscroll, &update_text, (void *)
449*10465441SEvalZero                     &data);
450*10465441SEvalZero         again = false;
451*10465441SEvalZero         for (i = 0; i < JUMP_NB && keys[i]; i++)
452*10465441SEvalZero             if (dres == keys[i]) {
453*10465441SEvalZero                 conf(targets[i]->parent, targets[i]);
454*10465441SEvalZero                 again = true;
455*10465441SEvalZero             }
456*10465441SEvalZero         str_free(&res);
457*10465441SEvalZero         list_for_each_entry_safe(pos, tmp, &head, entries)
458*10465441SEvalZero             free(pos);
459*10465441SEvalZero     } while (again);
460*10465441SEvalZero     free(sym_arr);
461*10465441SEvalZero     str_free(&title);
462*10465441SEvalZero     list_del(trail.prev);
463*10465441SEvalZero     str_free(&sttext);
464*10465441SEvalZero }
465*10465441SEvalZero 
build_conf(struct menu * menu)466*10465441SEvalZero static void build_conf(struct menu *menu)
467*10465441SEvalZero {
468*10465441SEvalZero     struct symbol *sym;
469*10465441SEvalZero     struct property *prop;
470*10465441SEvalZero     struct menu *child;
471*10465441SEvalZero     int type, tmp, doint = 2;
472*10465441SEvalZero     tristate val;
473*10465441SEvalZero     char ch;
474*10465441SEvalZero     bool visible;
475*10465441SEvalZero 
476*10465441SEvalZero     /*
477*10465441SEvalZero      * note: menu_is_visible() has side effect that it will
478*10465441SEvalZero      * recalc the value of the symbol.
479*10465441SEvalZero      */
480*10465441SEvalZero     visible = menu_is_visible(menu);
481*10465441SEvalZero     if (show_all_options && !menu_has_prompt(menu))
482*10465441SEvalZero         return;
483*10465441SEvalZero     else if (!show_all_options && !visible)
484*10465441SEvalZero         return;
485*10465441SEvalZero 
486*10465441SEvalZero     sym = menu->sym;
487*10465441SEvalZero     prop = menu->prompt;
488*10465441SEvalZero     if (!sym) {
489*10465441SEvalZero         if (prop && menu != current_menu) {
490*10465441SEvalZero             const char *prompt = menu_get_prompt(menu);
491*10465441SEvalZero             switch (prop->type) {
492*10465441SEvalZero             case P_MENU:
493*10465441SEvalZero                 child_count++;
494*10465441SEvalZero                 prompt = _(prompt);
495*10465441SEvalZero                 if (single_menu_mode) {
496*10465441SEvalZero                     item_make("%s%*c%s",
497*10465441SEvalZero                           menu->data ? "-->" : "++>",
498*10465441SEvalZero                           indent + 1, ' ', prompt);
499*10465441SEvalZero                 } else
500*10465441SEvalZero                     item_make("   %*c%s  %s",
501*10465441SEvalZero                           indent + 1, ' ', prompt,
502*10465441SEvalZero                           menu_is_empty(menu) ? "----" : "--->");
503*10465441SEvalZero                 item_set_tag('m');
504*10465441SEvalZero                 item_set_data(menu);
505*10465441SEvalZero                 if (single_menu_mode && menu->data)
506*10465441SEvalZero                     goto conf_childs;
507*10465441SEvalZero                 return;
508*10465441SEvalZero             case P_COMMENT:
509*10465441SEvalZero                 if (prompt) {
510*10465441SEvalZero                     child_count++;
511*10465441SEvalZero                     item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt));
512*10465441SEvalZero                     item_set_tag(':');
513*10465441SEvalZero                     item_set_data(menu);
514*10465441SEvalZero                 }
515*10465441SEvalZero                 break;
516*10465441SEvalZero             default:
517*10465441SEvalZero                 if (prompt) {
518*10465441SEvalZero                     child_count++;
519*10465441SEvalZero                     item_make("---%*c%s", indent + 1, ' ', _(prompt));
520*10465441SEvalZero                     item_set_tag(':');
521*10465441SEvalZero                     item_set_data(menu);
522*10465441SEvalZero                 }
523*10465441SEvalZero             }
524*10465441SEvalZero         } else
525*10465441SEvalZero             doint = 0;
526*10465441SEvalZero         goto conf_childs;
527*10465441SEvalZero     }
528*10465441SEvalZero 
529*10465441SEvalZero     type = sym_get_type(sym);
530*10465441SEvalZero     if (sym_is_choice(sym)) {
531*10465441SEvalZero         struct symbol *def_sym = sym_get_choice_value(sym);
532*10465441SEvalZero         struct menu *def_menu = NULL;
533*10465441SEvalZero 
534*10465441SEvalZero         child_count++;
535*10465441SEvalZero         for (child = menu->list; child; child = child->next) {
536*10465441SEvalZero             if (menu_is_visible(child) && child->sym == def_sym)
537*10465441SEvalZero                 def_menu = child;
538*10465441SEvalZero         }
539*10465441SEvalZero 
540*10465441SEvalZero         val = sym_get_tristate_value(sym);
541*10465441SEvalZero         if (sym_is_changable(sym)) {
542*10465441SEvalZero             switch (type) {
543*10465441SEvalZero             case S_BOOLEAN:
544*10465441SEvalZero                 item_make("[%c]", val == no ? ' ' : '*');
545*10465441SEvalZero                 break;
546*10465441SEvalZero             case S_TRISTATE:
547*10465441SEvalZero                 switch (val) {
548*10465441SEvalZero                 case yes: ch = '*'; break;
549*10465441SEvalZero                 case mod: ch = 'M'; break;
550*10465441SEvalZero                 default:  ch = ' '; break;
551*10465441SEvalZero                 }
552*10465441SEvalZero                 item_make("<%c>", ch);
553*10465441SEvalZero                 break;
554*10465441SEvalZero             }
555*10465441SEvalZero             item_set_tag('t');
556*10465441SEvalZero             item_set_data(menu);
557*10465441SEvalZero         } else {
558*10465441SEvalZero             item_make("   ");
559*10465441SEvalZero             item_set_tag(def_menu ? 't' : ':');
560*10465441SEvalZero             item_set_data(menu);
561*10465441SEvalZero         }
562*10465441SEvalZero 
563*10465441SEvalZero         item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
564*10465441SEvalZero         if (val == yes) {
565*10465441SEvalZero             if (def_menu) {
566*10465441SEvalZero                 item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
567*10465441SEvalZero                 item_add_str("  --->");
568*10465441SEvalZero                 if (def_menu->list) {
569*10465441SEvalZero                     indent += 2;
570*10465441SEvalZero                     build_conf(def_menu);
571*10465441SEvalZero                     indent -= 2;
572*10465441SEvalZero                 }
573*10465441SEvalZero             }
574*10465441SEvalZero             return;
575*10465441SEvalZero         }
576*10465441SEvalZero     } else {
577*10465441SEvalZero         if (menu == current_menu) {
578*10465441SEvalZero             item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
579*10465441SEvalZero             item_set_tag(':');
580*10465441SEvalZero             item_set_data(menu);
581*10465441SEvalZero             goto conf_childs;
582*10465441SEvalZero         }
583*10465441SEvalZero         child_count++;
584*10465441SEvalZero         val = sym_get_tristate_value(sym);
585*10465441SEvalZero         if (sym_is_choice_value(sym) && val == yes) {
586*10465441SEvalZero             item_make("   ");
587*10465441SEvalZero             item_set_tag(':');
588*10465441SEvalZero             item_set_data(menu);
589*10465441SEvalZero         } else {
590*10465441SEvalZero             switch (type) {
591*10465441SEvalZero             case S_BOOLEAN:
592*10465441SEvalZero                 if (sym_is_changable(sym))
593*10465441SEvalZero                     item_make("[%c]", val == no ? ' ' : '*');
594*10465441SEvalZero                 else
595*10465441SEvalZero                     item_make("-%c-", val == no ? ' ' : '*');
596*10465441SEvalZero                 item_set_tag('t');
597*10465441SEvalZero                 item_set_data(menu);
598*10465441SEvalZero                 break;
599*10465441SEvalZero             case S_TRISTATE:
600*10465441SEvalZero                 switch (val) {
601*10465441SEvalZero                 case yes: ch = '*'; break;
602*10465441SEvalZero                 case mod: ch = 'M'; break;
603*10465441SEvalZero                 default:  ch = ' '; break;
604*10465441SEvalZero                 }
605*10465441SEvalZero                 if (sym_is_changable(sym)) {
606*10465441SEvalZero                     if (sym->rev_dep.tri == mod)
607*10465441SEvalZero                         item_make("{%c}", ch);
608*10465441SEvalZero                     else
609*10465441SEvalZero                         item_make("<%c>", ch);
610*10465441SEvalZero                 } else
611*10465441SEvalZero                     item_make("-%c-", ch);
612*10465441SEvalZero                 item_set_tag('t');
613*10465441SEvalZero                 item_set_data(menu);
614*10465441SEvalZero                 break;
615*10465441SEvalZero             default:
616*10465441SEvalZero                 tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
617*10465441SEvalZero                 item_make("(%s)", sym_get_string_value(sym));
618*10465441SEvalZero                 tmp = indent - tmp + 4;
619*10465441SEvalZero                 if (tmp < 0)
620*10465441SEvalZero                     tmp = 0;
621*10465441SEvalZero                 item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
622*10465441SEvalZero                          (sym_has_value(sym) || !sym_is_changable(sym)) ?
623*10465441SEvalZero                          "" : _(" (NEW)"));
624*10465441SEvalZero                 item_set_tag('s');
625*10465441SEvalZero                 item_set_data(menu);
626*10465441SEvalZero                 goto conf_childs;
627*10465441SEvalZero             }
628*10465441SEvalZero         }
629*10465441SEvalZero         item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
630*10465441SEvalZero               (sym_has_value(sym) || !sym_is_changable(sym)) ?
631*10465441SEvalZero               "" : _(" (NEW)"));
632*10465441SEvalZero         if (menu->prompt->type == P_MENU) {
633*10465441SEvalZero             item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");
634*10465441SEvalZero             return;
635*10465441SEvalZero         }
636*10465441SEvalZero     }
637*10465441SEvalZero 
638*10465441SEvalZero conf_childs:
639*10465441SEvalZero     indent += doint;
640*10465441SEvalZero     for (child = menu->list; child; child = child->next)
641*10465441SEvalZero         build_conf(child);
642*10465441SEvalZero     indent -= doint;
643*10465441SEvalZero }
644*10465441SEvalZero 
conf(struct menu * menu,struct menu * active_menu)645*10465441SEvalZero static void conf(struct menu *menu, struct menu *active_menu)
646*10465441SEvalZero {
647*10465441SEvalZero     struct menu *submenu;
648*10465441SEvalZero     const char *prompt = menu_get_prompt(menu);
649*10465441SEvalZero     struct subtitle_part stpart;
650*10465441SEvalZero     struct symbol *sym;
651*10465441SEvalZero     int res;
652*10465441SEvalZero     int s_scroll = 0;
653*10465441SEvalZero 
654*10465441SEvalZero     if (menu != &rootmenu)
655*10465441SEvalZero         stpart.text = menu_get_prompt(menu);
656*10465441SEvalZero     else
657*10465441SEvalZero         stpart.text = NULL;
658*10465441SEvalZero     list_add_tail(&stpart.entries, &trail);
659*10465441SEvalZero 
660*10465441SEvalZero     while (1) {
661*10465441SEvalZero         item_reset();
662*10465441SEvalZero         current_menu = menu;
663*10465441SEvalZero         build_conf(menu);
664*10465441SEvalZero         if (!child_count)
665*10465441SEvalZero             break;
666*10465441SEvalZero         set_subtitle();
667*10465441SEvalZero         dialog_clear();
668*10465441SEvalZero         res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
669*10465441SEvalZero                   _(menu_instructions),
670*10465441SEvalZero                   active_menu, &s_scroll);
671*10465441SEvalZero         if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
672*10465441SEvalZero             break;
673*10465441SEvalZero         if (item_count() != 0) {
674*10465441SEvalZero             if (!item_activate_selected())
675*10465441SEvalZero                 continue;
676*10465441SEvalZero             if (!item_tag())
677*10465441SEvalZero                 continue;
678*10465441SEvalZero         }
679*10465441SEvalZero         submenu = item_data();
680*10465441SEvalZero         active_menu = item_data();
681*10465441SEvalZero         if (submenu)
682*10465441SEvalZero             sym = submenu->sym;
683*10465441SEvalZero         else
684*10465441SEvalZero             sym = NULL;
685*10465441SEvalZero 
686*10465441SEvalZero         switch (res) {
687*10465441SEvalZero         case 0:
688*10465441SEvalZero             switch (item_tag()) {
689*10465441SEvalZero             case 'm':
690*10465441SEvalZero                 if (single_menu_mode)
691*10465441SEvalZero                     submenu->data = (void *) (long) !submenu->data;
692*10465441SEvalZero                 else
693*10465441SEvalZero                     conf(submenu, NULL);
694*10465441SEvalZero                 break;
695*10465441SEvalZero             case 't':
696*10465441SEvalZero                 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
697*10465441SEvalZero                     conf_choice(submenu);
698*10465441SEvalZero                 else if (submenu->prompt->type == P_MENU)
699*10465441SEvalZero                     conf(submenu, NULL);
700*10465441SEvalZero                 break;
701*10465441SEvalZero             case 's':
702*10465441SEvalZero                 conf_string(submenu);
703*10465441SEvalZero                 break;
704*10465441SEvalZero             }
705*10465441SEvalZero             break;
706*10465441SEvalZero         case 2:
707*10465441SEvalZero             if (sym)
708*10465441SEvalZero                 show_help(submenu);
709*10465441SEvalZero             else {
710*10465441SEvalZero                 reset_subtitle();
711*10465441SEvalZero                 show_helptext(_("README"), _(mconf_readme));
712*10465441SEvalZero             }
713*10465441SEvalZero             break;
714*10465441SEvalZero         case 3:
715*10465441SEvalZero             reset_subtitle();
716*10465441SEvalZero             conf_save();
717*10465441SEvalZero             break;
718*10465441SEvalZero         case 4:
719*10465441SEvalZero             reset_subtitle();
720*10465441SEvalZero             conf_load();
721*10465441SEvalZero             break;
722*10465441SEvalZero         case 5:
723*10465441SEvalZero             if (item_is_tag('t')) {
724*10465441SEvalZero                 if (sym_set_tristate_value(sym, yes))
725*10465441SEvalZero                     break;
726*10465441SEvalZero                 if (sym_set_tristate_value(sym, mod))
727*10465441SEvalZero                     show_textbox(NULL, setmod_text, 6, 74);
728*10465441SEvalZero             }
729*10465441SEvalZero             break;
730*10465441SEvalZero         case 6:
731*10465441SEvalZero             if (item_is_tag('t'))
732*10465441SEvalZero                 sym_set_tristate_value(sym, no);
733*10465441SEvalZero             break;
734*10465441SEvalZero         case 7:
735*10465441SEvalZero             if (item_is_tag('t'))
736*10465441SEvalZero                 sym_set_tristate_value(sym, mod);
737*10465441SEvalZero             break;
738*10465441SEvalZero         case 8:
739*10465441SEvalZero             if (item_is_tag('t'))
740*10465441SEvalZero                 sym_toggle_tristate_value(sym);
741*10465441SEvalZero             else if (item_is_tag('m'))
742*10465441SEvalZero                 conf(submenu, NULL);
743*10465441SEvalZero             break;
744*10465441SEvalZero         case 9:
745*10465441SEvalZero             search_conf();
746*10465441SEvalZero             break;
747*10465441SEvalZero         case 10:
748*10465441SEvalZero             show_all_options = !show_all_options;
749*10465441SEvalZero             break;
750*10465441SEvalZero         }
751*10465441SEvalZero     }
752*10465441SEvalZero 
753*10465441SEvalZero     list_del(trail.prev);
754*10465441SEvalZero }
755*10465441SEvalZero 
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)756*10465441SEvalZero static int show_textbox_ext(const char *title, char *text, int r, int c, int
757*10465441SEvalZero                 *keys, int *vscroll, int *hscroll, update_text_fn
758*10465441SEvalZero                 update_text, void *data)
759*10465441SEvalZero {
760*10465441SEvalZero     dialog_clear();
761*10465441SEvalZero     return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
762*10465441SEvalZero                   update_text, data);
763*10465441SEvalZero }
764*10465441SEvalZero 
show_textbox(const char * title,const char * text,int r,int c)765*10465441SEvalZero static void show_textbox(const char *title, const char *text, int r, int c)
766*10465441SEvalZero {
767*10465441SEvalZero     show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
768*10465441SEvalZero              NULL, NULL);
769*10465441SEvalZero }
770*10465441SEvalZero 
show_helptext(const char * title,const char * text)771*10465441SEvalZero static void show_helptext(const char *title, const char *text)
772*10465441SEvalZero {
773*10465441SEvalZero     show_textbox(title, text, 0, 0);
774*10465441SEvalZero }
775*10465441SEvalZero 
conf_message_callback(const char * fmt,va_list ap)776*10465441SEvalZero static void conf_message_callback(const char *fmt, va_list ap)
777*10465441SEvalZero {
778*10465441SEvalZero     char buf[PATH_MAX+1];
779*10465441SEvalZero 
780*10465441SEvalZero     vsnprintf(buf, sizeof(buf), fmt, ap);
781*10465441SEvalZero     if (save_and_exit) {
782*10465441SEvalZero         if (!silent)
783*10465441SEvalZero             printf("%s", buf);
784*10465441SEvalZero     } else {
785*10465441SEvalZero         show_textbox(NULL, buf, 6, 60);
786*10465441SEvalZero     }
787*10465441SEvalZero }
788*10465441SEvalZero 
show_help(struct menu * menu)789*10465441SEvalZero static void show_help(struct menu *menu)
790*10465441SEvalZero {
791*10465441SEvalZero     struct gstr help = str_new();
792*10465441SEvalZero 
793*10465441SEvalZero     help.max_width = getmaxx(stdscr) - 10;
794*10465441SEvalZero     menu_get_ext_help(menu, &help);
795*10465441SEvalZero 
796*10465441SEvalZero     show_helptext(_(menu_get_prompt(menu)), str_get(&help));
797*10465441SEvalZero     str_free(&help);
798*10465441SEvalZero }
799*10465441SEvalZero 
conf_choice(struct menu * menu)800*10465441SEvalZero static void conf_choice(struct menu *menu)
801*10465441SEvalZero {
802*10465441SEvalZero     const char *prompt = _(menu_get_prompt(menu));
803*10465441SEvalZero     struct menu *child;
804*10465441SEvalZero     struct symbol *active;
805*10465441SEvalZero 
806*10465441SEvalZero     active = sym_get_choice_value(menu->sym);
807*10465441SEvalZero     while (1) {
808*10465441SEvalZero         int res;
809*10465441SEvalZero         int selected;
810*10465441SEvalZero         item_reset();
811*10465441SEvalZero 
812*10465441SEvalZero         current_menu = menu;
813*10465441SEvalZero         for (child = menu->list; child; child = child->next) {
814*10465441SEvalZero             if (!menu_is_visible(child))
815*10465441SEvalZero                 continue;
816*10465441SEvalZero             if (child->sym)
817*10465441SEvalZero                 item_make("%s", _(menu_get_prompt(child)));
818*10465441SEvalZero             else {
819*10465441SEvalZero                 item_make("*** %s ***", _(menu_get_prompt(child)));
820*10465441SEvalZero                 item_set_tag(':');
821*10465441SEvalZero             }
822*10465441SEvalZero             item_set_data(child);
823*10465441SEvalZero             if (child->sym == active)
824*10465441SEvalZero                 item_set_selected(1);
825*10465441SEvalZero             if (child->sym == sym_get_choice_value(menu->sym))
826*10465441SEvalZero                 item_set_tag('X');
827*10465441SEvalZero         }
828*10465441SEvalZero         dialog_clear();
829*10465441SEvalZero         res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
830*10465441SEvalZero                     _(radiolist_instructions),
831*10465441SEvalZero                     MENUBOX_HEIGTH_MIN,
832*10465441SEvalZero                     MENUBOX_WIDTH_MIN,
833*10465441SEvalZero                     CHECKLIST_HEIGTH_MIN);
834*10465441SEvalZero         selected = item_activate_selected();
835*10465441SEvalZero         switch (res) {
836*10465441SEvalZero         case 0:
837*10465441SEvalZero             if (selected) {
838*10465441SEvalZero                 child = item_data();
839*10465441SEvalZero                 if (!child->sym)
840*10465441SEvalZero                     break;
841*10465441SEvalZero 
842*10465441SEvalZero                 sym_set_tristate_value(child->sym, yes);
843*10465441SEvalZero             }
844*10465441SEvalZero             return;
845*10465441SEvalZero         case 1:
846*10465441SEvalZero             if (selected) {
847*10465441SEvalZero                 child = item_data();
848*10465441SEvalZero                 show_help(child);
849*10465441SEvalZero                 active = child->sym;
850*10465441SEvalZero             } else
851*10465441SEvalZero                 show_help(menu);
852*10465441SEvalZero             break;
853*10465441SEvalZero         case KEY_ESC:
854*10465441SEvalZero             return;
855*10465441SEvalZero         case -ERRDISPLAYTOOSMALL:
856*10465441SEvalZero             return;
857*10465441SEvalZero         }
858*10465441SEvalZero     }
859*10465441SEvalZero }
860*10465441SEvalZero 
conf_string(struct menu * menu)861*10465441SEvalZero static void conf_string(struct menu *menu)
862*10465441SEvalZero {
863*10465441SEvalZero     const char *prompt = menu_get_prompt(menu);
864*10465441SEvalZero 
865*10465441SEvalZero     while (1) {
866*10465441SEvalZero         int res;
867*10465441SEvalZero         const char *heading;
868*10465441SEvalZero 
869*10465441SEvalZero         switch (sym_get_type(menu->sym)) {
870*10465441SEvalZero         case S_INT:
871*10465441SEvalZero             heading = _(inputbox_instructions_int);
872*10465441SEvalZero             break;
873*10465441SEvalZero         case S_HEX:
874*10465441SEvalZero             heading = _(inputbox_instructions_hex);
875*10465441SEvalZero             break;
876*10465441SEvalZero         case S_STRING:
877*10465441SEvalZero             heading = _(inputbox_instructions_string);
878*10465441SEvalZero             break;
879*10465441SEvalZero         default:
880*10465441SEvalZero             heading = _("Internal mconf error!");
881*10465441SEvalZero         }
882*10465441SEvalZero         dialog_clear();
883*10465441SEvalZero         res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
884*10465441SEvalZero                       heading, 10, 75,
885*10465441SEvalZero                       sym_get_string_value(menu->sym));
886*10465441SEvalZero         switch (res) {
887*10465441SEvalZero         case 0:
888*10465441SEvalZero             if (sym_set_string_value(menu->sym, dialog_input_result))
889*10465441SEvalZero                 return;
890*10465441SEvalZero             show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
891*10465441SEvalZero             break;
892*10465441SEvalZero         case 1:
893*10465441SEvalZero             show_help(menu);
894*10465441SEvalZero             break;
895*10465441SEvalZero         case KEY_ESC:
896*10465441SEvalZero             return;
897*10465441SEvalZero         }
898*10465441SEvalZero     }
899*10465441SEvalZero }
900*10465441SEvalZero 
conf_load(void)901*10465441SEvalZero static void conf_load(void)
902*10465441SEvalZero {
903*10465441SEvalZero 
904*10465441SEvalZero     while (1) {
905*10465441SEvalZero         int res;
906*10465441SEvalZero         dialog_clear();
907*10465441SEvalZero         res = dialog_inputbox(NULL, load_config_text,
908*10465441SEvalZero                       11, 55, filename);
909*10465441SEvalZero         switch(res) {
910*10465441SEvalZero         case 0:
911*10465441SEvalZero             if (!dialog_input_result[0])
912*10465441SEvalZero                 return;
913*10465441SEvalZero             if (!conf_read(dialog_input_result)) {
914*10465441SEvalZero                 set_config_filename(dialog_input_result);
915*10465441SEvalZero                 sym_set_change_count(1);
916*10465441SEvalZero                 return;
917*10465441SEvalZero             }
918*10465441SEvalZero             show_textbox(NULL, _("File does not exist!"), 5, 38);
919*10465441SEvalZero             break;
920*10465441SEvalZero         case 1:
921*10465441SEvalZero             show_helptext(_("Load Alternate Configuration"), load_config_help);
922*10465441SEvalZero             break;
923*10465441SEvalZero         case KEY_ESC:
924*10465441SEvalZero             return;
925*10465441SEvalZero         }
926*10465441SEvalZero     }
927*10465441SEvalZero }
928*10465441SEvalZero 
conf_save(void)929*10465441SEvalZero static void conf_save(void)
930*10465441SEvalZero {
931*10465441SEvalZero     while (1) {
932*10465441SEvalZero         int res;
933*10465441SEvalZero         dialog_clear();
934*10465441SEvalZero         res = dialog_inputbox(NULL, save_config_text,
935*10465441SEvalZero                       11, 55, filename);
936*10465441SEvalZero         switch(res) {
937*10465441SEvalZero         case 0:
938*10465441SEvalZero             if (!dialog_input_result[0])
939*10465441SEvalZero                 return;
940*10465441SEvalZero             if (!conf_write(dialog_input_result)) {
941*10465441SEvalZero                 set_config_filename(dialog_input_result);
942*10465441SEvalZero                 return;
943*10465441SEvalZero             }
944*10465441SEvalZero             show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
945*10465441SEvalZero             break;
946*10465441SEvalZero         case 1:
947*10465441SEvalZero             show_helptext(_("Save Alternate Configuration"), save_config_help);
948*10465441SEvalZero             break;
949*10465441SEvalZero         case KEY_ESC:
950*10465441SEvalZero             return;
951*10465441SEvalZero         }
952*10465441SEvalZero     }
953*10465441SEvalZero }
954*10465441SEvalZero 
handle_exit(void)955*10465441SEvalZero static int handle_exit(void)
956*10465441SEvalZero {
957*10465441SEvalZero     int res = 0;
958*10465441SEvalZero 
959*10465441SEvalZero     save_and_exit = 1;
960*10465441SEvalZero     reset_subtitle();
961*10465441SEvalZero     dialog_clear();
962*10465441SEvalZero     if (conf_get_changed())
963*10465441SEvalZero     {
964*10465441SEvalZero         if (silent)
965*10465441SEvalZero         {
966*10465441SEvalZero             /* save change */
967*10465441SEvalZero             res = 0;
968*10465441SEvalZero         }
969*10465441SEvalZero         else
970*10465441SEvalZero         {
971*10465441SEvalZero             res = dialog_yesno(NULL,
972*10465441SEvalZero                        _("Do you wish to save your new configuration?\n"
973*10465441SEvalZero                          "(Press <ESC><ESC> to continue kernel configuration.)"),
974*10465441SEvalZero                        6, 60);
975*10465441SEvalZero         }
976*10465441SEvalZero 
977*10465441SEvalZero     }
978*10465441SEvalZero     else
979*10465441SEvalZero         res = -1;
980*10465441SEvalZero 
981*10465441SEvalZero     if (!silent) end_dialog(saved_x, saved_y);
982*10465441SEvalZero 
983*10465441SEvalZero     switch (res) {
984*10465441SEvalZero     case 0:
985*10465441SEvalZero         if (conf_write(filename)) {
986*10465441SEvalZero             fprintf(stderr, _("\n\n"
987*10465441SEvalZero                       "Error while writing of the configuration.\n"
988*10465441SEvalZero                       "Your configuration changes were NOT saved."
989*10465441SEvalZero                       "\n\n"));
990*10465441SEvalZero             return 1;
991*10465441SEvalZero         }
992*10465441SEvalZero         /* fall through */
993*10465441SEvalZero     case -1:
994*10465441SEvalZero         if (!silent)
995*10465441SEvalZero             printf(_("\n\n"
996*10465441SEvalZero                  "*** End of the configuration.\n"
997*10465441SEvalZero                  "*** Execute 'make' to start the build or try 'make help'."
998*10465441SEvalZero                  "\n\n"));
999*10465441SEvalZero         res = 0;
1000*10465441SEvalZero         break;
1001*10465441SEvalZero     default:
1002*10465441SEvalZero         if (!silent)
1003*10465441SEvalZero             fprintf(stderr, _("\n\n"
1004*10465441SEvalZero                       "Your configuration changes were NOT saved."
1005*10465441SEvalZero                       "\n\n"));
1006*10465441SEvalZero         if (res != KEY_ESC)
1007*10465441SEvalZero             res = 0;
1008*10465441SEvalZero     }
1009*10465441SEvalZero 
1010*10465441SEvalZero     return res;
1011*10465441SEvalZero }
1012*10465441SEvalZero 
sig_handler(int signo)1013*10465441SEvalZero static void sig_handler(int signo)
1014*10465441SEvalZero {
1015*10465441SEvalZero     exit(handle_exit());
1016*10465441SEvalZero }
1017*10465441SEvalZero 
main(int ac,char ** av)1018*10465441SEvalZero int main(int ac, char **av)
1019*10465441SEvalZero {
1020*10465441SEvalZero     char *mode;
1021*10465441SEvalZero     int res;
1022*10465441SEvalZero 
1023*10465441SEvalZero     setlocale(LC_ALL, "");
1024*10465441SEvalZero     bindtextdomain(PACKAGE, LOCALEDIR);
1025*10465441SEvalZero     textdomain(PACKAGE);
1026*10465441SEvalZero 
1027*10465441SEvalZero     signal(SIGINT, sig_handler);
1028*10465441SEvalZero 
1029*10465441SEvalZero     if (ac > 1 && strcmp(av[1], "-s") == 0) {
1030*10465441SEvalZero         silent = 1;
1031*10465441SEvalZero         /* Silence conf_read() until the real callback is set up */
1032*10465441SEvalZero         conf_set_message_callback(NULL);
1033*10465441SEvalZero         av++;
1034*10465441SEvalZero     }
1035*10465441SEvalZero     conf_parse(av[1]);
1036*10465441SEvalZero     conf_read(NULL);
1037*10465441SEvalZero 
1038*10465441SEvalZero     mode = getenv("MENUCONFIG_MODE");
1039*10465441SEvalZero     if (mode) {
1040*10465441SEvalZero         if (!strcasecmp(mode, "single_menu"))
1041*10465441SEvalZero             single_menu_mode = 1;
1042*10465441SEvalZero     }
1043*10465441SEvalZero 
1044*10465441SEvalZero     if (init_dialog(NULL)) {
1045*10465441SEvalZero         fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
1046*10465441SEvalZero         fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
1047*10465441SEvalZero         return 1;
1048*10465441SEvalZero     }
1049*10465441SEvalZero 
1050*10465441SEvalZero     set_config_filename(conf_get_configname());
1051*10465441SEvalZero     conf_set_message_callback(conf_message_callback);
1052*10465441SEvalZero 
1053*10465441SEvalZero     if (ac > 2 && strcmp(av[2], "-n") == 0)
1054*10465441SEvalZero     {
1055*10465441SEvalZero         fprintf(stderr, N_("Debug mode,don't display menuconfig window.\n"));
1056*10465441SEvalZero         silent = 1;
1057*10465441SEvalZero         /* Silence conf_read() until the real callback is set up */
1058*10465441SEvalZero         conf_set_message_callback(NULL);
1059*10465441SEvalZero         av++;
1060*10465441SEvalZero         res = handle_exit();
1061*10465441SEvalZero         return res;
1062*10465441SEvalZero      }
1063*10465441SEvalZero 
1064*10465441SEvalZero     do {
1065*10465441SEvalZero         conf(&rootmenu, NULL);
1066*10465441SEvalZero         res = handle_exit();
1067*10465441SEvalZero     } while (res == KEY_ESC);
1068*10465441SEvalZero 
1069*10465441SEvalZero     return res;
1070*10465441SEvalZero }
1071