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