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