xref: /rk3399_rockchip-uboot/scripts/kconfig/nconf.c (revision 0a9064fb47bb0a239c04b0b63edebfdd3a201fdc)
1*0a9064fbSMasahiro Yamada /*
2*0a9064fbSMasahiro Yamada  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3*0a9064fbSMasahiro Yamada  * Released under the terms of the GNU GPL v2.0.
4*0a9064fbSMasahiro Yamada  *
5*0a9064fbSMasahiro Yamada  * Derived from menuconfig.
6*0a9064fbSMasahiro Yamada  *
7*0a9064fbSMasahiro Yamada  */
8*0a9064fbSMasahiro Yamada #define _GNU_SOURCE
9*0a9064fbSMasahiro Yamada #include <string.h>
10*0a9064fbSMasahiro Yamada #include <stdlib.h>
11*0a9064fbSMasahiro Yamada 
12*0a9064fbSMasahiro Yamada #include "lkc.h"
13*0a9064fbSMasahiro Yamada #include "nconf.h"
14*0a9064fbSMasahiro Yamada #include <ctype.h>
15*0a9064fbSMasahiro Yamada 
16*0a9064fbSMasahiro Yamada static const char nconf_global_help[] = N_(
17*0a9064fbSMasahiro Yamada "Help windows\n"
18*0a9064fbSMasahiro Yamada "------------\n"
19*0a9064fbSMasahiro Yamada "o  Global help:  Unless in a data entry window, pressing <F1> will give \n"
20*0a9064fbSMasahiro Yamada "   you the global help window, which you are just reading.\n"
21*0a9064fbSMasahiro Yamada "\n"
22*0a9064fbSMasahiro Yamada "o  A short version of the global help is available by pressing <F3>.\n"
23*0a9064fbSMasahiro Yamada "\n"
24*0a9064fbSMasahiro Yamada "o  Local help:  To get help related to the current menu entry, use any\n"
25*0a9064fbSMasahiro Yamada "   of <?> <h>, or if in a data entry window then press <F1>.\n"
26*0a9064fbSMasahiro Yamada "\n"
27*0a9064fbSMasahiro Yamada "\n"
28*0a9064fbSMasahiro Yamada "Menu entries\n"
29*0a9064fbSMasahiro Yamada "------------\n"
30*0a9064fbSMasahiro Yamada "This interface lets you select features and parameters for the kernel\n"
31*0a9064fbSMasahiro Yamada "build.  Kernel features can either be built-in, modularized, or removed.\n"
32*0a9064fbSMasahiro Yamada "Parameters must be entered as text or decimal or hexadecimal numbers.\n"
33*0a9064fbSMasahiro Yamada "\n"
34*0a9064fbSMasahiro Yamada "Menu entries beginning with following braces represent features that\n"
35*0a9064fbSMasahiro Yamada "  [ ]  can be built in or removed\n"
36*0a9064fbSMasahiro Yamada "  < >  can be built in, modularized or removed\n"
37*0a9064fbSMasahiro Yamada "  { }  can be built in or modularized, are selected by another feature\n"
38*0a9064fbSMasahiro Yamada "  - -  are selected by another feature\n"
39*0a9064fbSMasahiro Yamada "  XXX  cannot be selected.  Symbol Info <F2> tells you why.\n"
40*0a9064fbSMasahiro Yamada "*, M or whitespace inside braces means to build in, build as a module\n"
41*0a9064fbSMasahiro Yamada "or to exclude the feature respectively.\n"
42*0a9064fbSMasahiro Yamada "\n"
43*0a9064fbSMasahiro Yamada "To change any of these features, highlight it with the movement keys\n"
44*0a9064fbSMasahiro Yamada "listed below and press <y> to build it in, <m> to make it a module or\n"
45*0a9064fbSMasahiro Yamada "<n> to remove it.  You may press the <Space> key to cycle through the\n"
46*0a9064fbSMasahiro Yamada "available options.\n"
47*0a9064fbSMasahiro Yamada "\n"
48*0a9064fbSMasahiro Yamada "A trailing \"--->\" designates a submenu, a trailing \"----\" an\n"
49*0a9064fbSMasahiro Yamada "empty submenu.\n"
50*0a9064fbSMasahiro Yamada "\n"
51*0a9064fbSMasahiro Yamada "Menu navigation keys\n"
52*0a9064fbSMasahiro Yamada "----------------------------------------------------------------------\n"
53*0a9064fbSMasahiro Yamada "Linewise up                 <Up>\n"
54*0a9064fbSMasahiro Yamada "Linewise down               <Down>\n"
55*0a9064fbSMasahiro Yamada "Pagewise up                 <Page Up>\n"
56*0a9064fbSMasahiro Yamada "Pagewise down               <Page Down>\n"
57*0a9064fbSMasahiro Yamada "First entry                 <Home>\n"
58*0a9064fbSMasahiro Yamada "Last entry                  <End>\n"
59*0a9064fbSMasahiro Yamada "Enter a submenu             <Right>  <Enter>\n"
60*0a9064fbSMasahiro Yamada "Go back to parent menu      <Left>   <Esc>  <F5>\n"
61*0a9064fbSMasahiro Yamada "Close a help window         <Enter>  <Esc>  <F5>\n"
62*0a9064fbSMasahiro Yamada "Close entry window, apply   <Enter>\n"
63*0a9064fbSMasahiro Yamada "Close entry window, forget  <Esc>  <F5>\n"
64*0a9064fbSMasahiro Yamada "Start incremental, case-insensitive search for STRING in menu entries,\n"
65*0a9064fbSMasahiro Yamada "    no regex support, STRING is displayed in upper left corner\n"
66*0a9064fbSMasahiro Yamada "                            </>STRING\n"
67*0a9064fbSMasahiro Yamada "    Remove last character   <Backspace>\n"
68*0a9064fbSMasahiro Yamada "    Jump to next hit        <Down>\n"
69*0a9064fbSMasahiro Yamada "    Jump to previous hit    <Up>\n"
70*0a9064fbSMasahiro Yamada "Exit menu search mode       </>  <Esc>\n"
71*0a9064fbSMasahiro Yamada "Search for configuration variables with or without leading CONFIG_\n"
72*0a9064fbSMasahiro Yamada "                            <F8>RegExpr<Enter>\n"
73*0a9064fbSMasahiro Yamada "Verbose search help         <F8><F1>\n"
74*0a9064fbSMasahiro Yamada "----------------------------------------------------------------------\n"
75*0a9064fbSMasahiro Yamada "\n"
76*0a9064fbSMasahiro Yamada "Unless in a data entry window, key <1> may be used instead of <F1>,\n"
77*0a9064fbSMasahiro Yamada "<2> instead of <F2>, etc.\n"
78*0a9064fbSMasahiro Yamada "\n"
79*0a9064fbSMasahiro Yamada "\n"
80*0a9064fbSMasahiro Yamada "Radiolist (Choice list)\n"
81*0a9064fbSMasahiro Yamada "-----------------------\n"
82*0a9064fbSMasahiro Yamada "Use the movement keys listed above to select the option you wish to set\n"
83*0a9064fbSMasahiro Yamada "and press <Space>.\n"
84*0a9064fbSMasahiro Yamada "\n"
85*0a9064fbSMasahiro Yamada "\n"
86*0a9064fbSMasahiro Yamada "Data entry\n"
87*0a9064fbSMasahiro Yamada "----------\n"
88*0a9064fbSMasahiro Yamada "Enter the requested information and press <Enter>.  Hexadecimal values\n"
89*0a9064fbSMasahiro Yamada "may be entered without the \"0x\" prefix.\n"
90*0a9064fbSMasahiro Yamada "\n"
91*0a9064fbSMasahiro Yamada "\n"
92*0a9064fbSMasahiro Yamada "Text Box (Help Window)\n"
93*0a9064fbSMasahiro Yamada "----------------------\n"
94*0a9064fbSMasahiro Yamada "Use movement keys as listed in table above.\n"
95*0a9064fbSMasahiro Yamada "\n"
96*0a9064fbSMasahiro Yamada "Press any of <Enter> <Esc> <q> <F5> <F9> to exit.\n"
97*0a9064fbSMasahiro Yamada "\n"
98*0a9064fbSMasahiro Yamada "\n"
99*0a9064fbSMasahiro Yamada "Alternate configuration files\n"
100*0a9064fbSMasahiro Yamada "-----------------------------\n"
101*0a9064fbSMasahiro Yamada "nconfig supports switching between different configurations.\n"
102*0a9064fbSMasahiro Yamada "Press <F6> to save your current configuration.  Press <F7> and enter\n"
103*0a9064fbSMasahiro Yamada "a file name to load a previously saved configuration.\n"
104*0a9064fbSMasahiro Yamada "\n"
105*0a9064fbSMasahiro Yamada "\n"
106*0a9064fbSMasahiro Yamada "Terminal configuration\n"
107*0a9064fbSMasahiro Yamada "----------------------\n"
108*0a9064fbSMasahiro Yamada "If you use nconfig in a xterm window, make sure your TERM environment\n"
109*0a9064fbSMasahiro Yamada "variable specifies a terminal configuration which supports at least\n"
110*0a9064fbSMasahiro Yamada "16 colors.  Otherwise nconfig will look rather bad.\n"
111*0a9064fbSMasahiro Yamada "\n"
112*0a9064fbSMasahiro Yamada "If the \"stty size\" command reports the current terminalsize correctly,\n"
113*0a9064fbSMasahiro Yamada "nconfig will adapt to sizes larger than the traditional 80x25 \"standard\"\n"
114*0a9064fbSMasahiro Yamada "and display longer menus properly.\n"
115*0a9064fbSMasahiro Yamada "\n"
116*0a9064fbSMasahiro Yamada "\n"
117*0a9064fbSMasahiro Yamada "Single menu mode\n"
118*0a9064fbSMasahiro Yamada "----------------\n"
119*0a9064fbSMasahiro Yamada "If you prefer to have all of the menu entries listed in a single menu,\n"
120*0a9064fbSMasahiro Yamada "rather than the default multimenu hierarchy, run nconfig with\n"
121*0a9064fbSMasahiro Yamada "NCONFIG_MODE environment variable set to single_menu.  Example:\n"
122*0a9064fbSMasahiro Yamada "\n"
123*0a9064fbSMasahiro Yamada "make NCONFIG_MODE=single_menu nconfig\n"
124*0a9064fbSMasahiro Yamada "\n"
125*0a9064fbSMasahiro Yamada "<Enter> will then unfold the appropriate category, or fold it if it\n"
126*0a9064fbSMasahiro Yamada "is already unfolded.  Folded menu entries will be designated by a\n"
127*0a9064fbSMasahiro Yamada "leading \"++>\" and unfolded entries by a leading \"-->\".\n"
128*0a9064fbSMasahiro Yamada "\n"
129*0a9064fbSMasahiro Yamada "Note that this mode can eventually be a little more CPU expensive than\n"
130*0a9064fbSMasahiro Yamada "the default mode, especially with a larger number of unfolded submenus.\n"
131*0a9064fbSMasahiro Yamada "\n"),
132*0a9064fbSMasahiro Yamada menu_no_f_instructions[] = N_(
133*0a9064fbSMasahiro Yamada "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
134*0a9064fbSMasahiro Yamada "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
135*0a9064fbSMasahiro Yamada "\n"
136*0a9064fbSMasahiro Yamada "Use the following keys to navigate the menus:\n"
137*0a9064fbSMasahiro Yamada "Move up or down with <Up> and <Down>.\n"
138*0a9064fbSMasahiro Yamada "Enter a submenu with <Enter> or <Right>.\n"
139*0a9064fbSMasahiro Yamada "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
140*0a9064fbSMasahiro Yamada "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
141*0a9064fbSMasahiro Yamada "Pressing <Space> cycles through the available options.\n"
142*0a9064fbSMasahiro Yamada "To search for menu entries press </>.\n"
143*0a9064fbSMasahiro Yamada "<Esc> always leaves the current window.\n"
144*0a9064fbSMasahiro Yamada "\n"
145*0a9064fbSMasahiro Yamada "You do not have function keys support.\n"
146*0a9064fbSMasahiro Yamada "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
147*0a9064fbSMasahiro Yamada "For verbose global help use key <1>.\n"
148*0a9064fbSMasahiro Yamada "For help related to the current menu entry press <?> or <h>.\n"),
149*0a9064fbSMasahiro Yamada menu_instructions[] = N_(
150*0a9064fbSMasahiro Yamada "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
151*0a9064fbSMasahiro Yamada "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
152*0a9064fbSMasahiro Yamada "\n"
153*0a9064fbSMasahiro Yamada "Use the following keys to navigate the menus:\n"
154*0a9064fbSMasahiro Yamada "Move up or down with <Up> or <Down>.\n"
155*0a9064fbSMasahiro Yamada "Enter a submenu with <Enter> or <Right>.\n"
156*0a9064fbSMasahiro Yamada "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
157*0a9064fbSMasahiro Yamada "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
158*0a9064fbSMasahiro Yamada "Pressing <Space> cycles through the available options.\n"
159*0a9064fbSMasahiro Yamada "To search for menu entries press </>.\n"
160*0a9064fbSMasahiro Yamada "<Esc> always leaves the current window.\n"
161*0a9064fbSMasahiro Yamada "\n"
162*0a9064fbSMasahiro Yamada "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
163*0a9064fbSMasahiro Yamada "For verbose global help press <F1>.\n"
164*0a9064fbSMasahiro Yamada "For help related to the current menu entry press <?> or <h>.\n"),
165*0a9064fbSMasahiro Yamada radiolist_instructions[] = N_(
166*0a9064fbSMasahiro Yamada "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
167*0a9064fbSMasahiro Yamada "with <Space>.\n"
168*0a9064fbSMasahiro Yamada "For help related to the current entry press <?> or <h>.\n"
169*0a9064fbSMasahiro Yamada "For global help press <F1>.\n"),
170*0a9064fbSMasahiro Yamada inputbox_instructions_int[] = N_(
171*0a9064fbSMasahiro Yamada "Please enter a decimal value.\n"
172*0a9064fbSMasahiro Yamada "Fractions will not be accepted.\n"
173*0a9064fbSMasahiro Yamada "Press <Enter> to apply, <Esc> to cancel."),
174*0a9064fbSMasahiro Yamada inputbox_instructions_hex[] = N_(
175*0a9064fbSMasahiro Yamada "Please enter a hexadecimal value.\n"
176*0a9064fbSMasahiro Yamada "Press <Enter> to apply, <Esc> to cancel."),
177*0a9064fbSMasahiro Yamada inputbox_instructions_string[] = N_(
178*0a9064fbSMasahiro Yamada "Please enter a string value.\n"
179*0a9064fbSMasahiro Yamada "Press <Enter> to apply, <Esc> to cancel."),
180*0a9064fbSMasahiro Yamada setmod_text[] = N_(
181*0a9064fbSMasahiro Yamada "This feature depends on another feature which has been configured as a\n"
182*0a9064fbSMasahiro Yamada "module.  As a result, the current feature will be built as a module too."),
183*0a9064fbSMasahiro Yamada load_config_text[] = N_(
184*0a9064fbSMasahiro Yamada "Enter the name of the configuration file you wish to load.\n"
185*0a9064fbSMasahiro Yamada "Accept the name shown to restore the configuration you last\n"
186*0a9064fbSMasahiro Yamada "retrieved.  Leave empty to abort."),
187*0a9064fbSMasahiro Yamada load_config_help[] = N_(
188*0a9064fbSMasahiro Yamada "For various reasons, one may wish to keep several different\n"
189*0a9064fbSMasahiro Yamada "configurations available on a single machine.\n"
190*0a9064fbSMasahiro Yamada "\n"
191*0a9064fbSMasahiro Yamada "If you have saved a previous configuration in a file other than the\n"
192*0a9064fbSMasahiro Yamada "default one, entering its name here will allow you to load and modify\n"
193*0a9064fbSMasahiro Yamada "that configuration.\n"
194*0a9064fbSMasahiro Yamada "\n"
195*0a9064fbSMasahiro Yamada "Leave empty to abort.\n"),
196*0a9064fbSMasahiro Yamada save_config_text[] = N_(
197*0a9064fbSMasahiro Yamada "Enter a filename to which this configuration should be saved\n"
198*0a9064fbSMasahiro Yamada "as an alternate.  Leave empty to abort."),
199*0a9064fbSMasahiro Yamada save_config_help[] = N_(
200*0a9064fbSMasahiro Yamada "For various reasons, one may wish to keep several different\n"
201*0a9064fbSMasahiro Yamada "configurations available on a single machine.\n"
202*0a9064fbSMasahiro Yamada "\n"
203*0a9064fbSMasahiro Yamada "Entering a file name here will allow you to later retrieve, modify\n"
204*0a9064fbSMasahiro Yamada "and use the current configuration as an alternate to whatever\n"
205*0a9064fbSMasahiro Yamada "configuration options you have selected at that time.\n"
206*0a9064fbSMasahiro Yamada "\n"
207*0a9064fbSMasahiro Yamada "Leave empty to abort.\n"),
208*0a9064fbSMasahiro Yamada search_help[] = N_(
209*0a9064fbSMasahiro Yamada "Search for symbols (configuration variable names CONFIG_*) and display\n"
210*0a9064fbSMasahiro Yamada "their relations.  Regular expressions are supported.\n"
211*0a9064fbSMasahiro Yamada "Example:  Search for \"^FOO\".\n"
212*0a9064fbSMasahiro Yamada "Result:\n"
213*0a9064fbSMasahiro Yamada "-----------------------------------------------------------------\n"
214*0a9064fbSMasahiro Yamada "Symbol: FOO [ = m]\n"
215*0a9064fbSMasahiro Yamada "Prompt: Foo bus is used to drive the bar HW\n"
216*0a9064fbSMasahiro Yamada "Defined at drivers/pci/Kconfig:47\n"
217*0a9064fbSMasahiro Yamada "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
218*0a9064fbSMasahiro Yamada "Location:\n"
219*0a9064fbSMasahiro Yamada "  -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
220*0a9064fbSMasahiro Yamada "    -> PCI support (PCI [ = y])\n"
221*0a9064fbSMasahiro Yamada "      -> PCI access mode (<choice> [ = y])\n"
222*0a9064fbSMasahiro Yamada "Selects: LIBCRC32\n"
223*0a9064fbSMasahiro Yamada "Selected by: BAR\n"
224*0a9064fbSMasahiro Yamada "-----------------------------------------------------------------\n"
225*0a9064fbSMasahiro Yamada "o  The line 'Prompt:' shows the text displayed for this symbol in\n"
226*0a9064fbSMasahiro Yamada "   the menu hierarchy.\n"
227*0a9064fbSMasahiro Yamada "o  The 'Defined at' line tells at what file / line number the symbol is\n"
228*0a9064fbSMasahiro Yamada "   defined.\n"
229*0a9064fbSMasahiro Yamada "o  The 'Depends on:' line lists symbols that need to be defined for\n"
230*0a9064fbSMasahiro Yamada "   this symbol to be visible and selectable in the menu.\n"
231*0a9064fbSMasahiro Yamada "o  The 'Location:' lines tell, where in the menu structure this symbol\n"
232*0a9064fbSMasahiro Yamada "   is located.  A location followed by a [ = y] indicates that this is\n"
233*0a9064fbSMasahiro Yamada "   a selectable menu item, and the current value is displayed inside\n"
234*0a9064fbSMasahiro Yamada "   brackets.\n"
235*0a9064fbSMasahiro Yamada "o  The 'Selects:' line tells, what symbol will be automatically selected\n"
236*0a9064fbSMasahiro Yamada "   if this symbol is selected (y or m).\n"
237*0a9064fbSMasahiro Yamada "o  The 'Selected by' line tells what symbol has selected this symbol.\n"
238*0a9064fbSMasahiro Yamada "\n"
239*0a9064fbSMasahiro Yamada "Only relevant lines are shown.\n"
240*0a9064fbSMasahiro Yamada "\n\n"
241*0a9064fbSMasahiro Yamada "Search examples:\n"
242*0a9064fbSMasahiro Yamada "USB  => find all symbols containing USB\n"
243*0a9064fbSMasahiro Yamada "^USB => find all symbols starting with USB\n"
244*0a9064fbSMasahiro Yamada "USB$ => find all symbols ending with USB\n"
245*0a9064fbSMasahiro Yamada "\n");
246*0a9064fbSMasahiro Yamada 
247*0a9064fbSMasahiro Yamada struct mitem {
248*0a9064fbSMasahiro Yamada 	char str[256];
249*0a9064fbSMasahiro Yamada 	char tag;
250*0a9064fbSMasahiro Yamada 	void *usrptr;
251*0a9064fbSMasahiro Yamada 	int is_visible;
252*0a9064fbSMasahiro Yamada };
253*0a9064fbSMasahiro Yamada 
254*0a9064fbSMasahiro Yamada #define MAX_MENU_ITEMS 4096
255*0a9064fbSMasahiro Yamada static int show_all_items;
256*0a9064fbSMasahiro Yamada static int indent;
257*0a9064fbSMasahiro Yamada static struct menu *current_menu;
258*0a9064fbSMasahiro Yamada static int child_count;
259*0a9064fbSMasahiro Yamada static int single_menu_mode;
260*0a9064fbSMasahiro Yamada /* the window in which all information appears */
261*0a9064fbSMasahiro Yamada static WINDOW *main_window;
262*0a9064fbSMasahiro Yamada /* the largest size of the menu window */
263*0a9064fbSMasahiro Yamada static int mwin_max_lines;
264*0a9064fbSMasahiro Yamada static int mwin_max_cols;
265*0a9064fbSMasahiro Yamada /* the window in which we show option buttons */
266*0a9064fbSMasahiro Yamada static MENU *curses_menu;
267*0a9064fbSMasahiro Yamada static ITEM *curses_menu_items[MAX_MENU_ITEMS];
268*0a9064fbSMasahiro Yamada static struct mitem k_menu_items[MAX_MENU_ITEMS];
269*0a9064fbSMasahiro Yamada static int items_num;
270*0a9064fbSMasahiro Yamada static int global_exit;
271*0a9064fbSMasahiro Yamada /* the currently selected button */
272*0a9064fbSMasahiro Yamada const char *current_instructions = menu_instructions;
273*0a9064fbSMasahiro Yamada 
274*0a9064fbSMasahiro Yamada static char *dialog_input_result;
275*0a9064fbSMasahiro Yamada static int dialog_input_result_len;
276*0a9064fbSMasahiro Yamada 
277*0a9064fbSMasahiro Yamada static void conf(struct menu *menu);
278*0a9064fbSMasahiro Yamada static void conf_choice(struct menu *menu);
279*0a9064fbSMasahiro Yamada static void conf_string(struct menu *menu);
280*0a9064fbSMasahiro Yamada static void conf_load(void);
281*0a9064fbSMasahiro Yamada static void conf_save(void);
282*0a9064fbSMasahiro Yamada static void show_help(struct menu *menu);
283*0a9064fbSMasahiro Yamada static int do_exit(void);
284*0a9064fbSMasahiro Yamada static void setup_windows(void);
285*0a9064fbSMasahiro Yamada static void search_conf(void);
286*0a9064fbSMasahiro Yamada 
287*0a9064fbSMasahiro Yamada typedef void (*function_key_handler_t)(int *key, struct menu *menu);
288*0a9064fbSMasahiro Yamada static void handle_f1(int *key, struct menu *current_item);
289*0a9064fbSMasahiro Yamada static void handle_f2(int *key, struct menu *current_item);
290*0a9064fbSMasahiro Yamada static void handle_f3(int *key, struct menu *current_item);
291*0a9064fbSMasahiro Yamada static void handle_f4(int *key, struct menu *current_item);
292*0a9064fbSMasahiro Yamada static void handle_f5(int *key, struct menu *current_item);
293*0a9064fbSMasahiro Yamada static void handle_f6(int *key, struct menu *current_item);
294*0a9064fbSMasahiro Yamada static void handle_f7(int *key, struct menu *current_item);
295*0a9064fbSMasahiro Yamada static void handle_f8(int *key, struct menu *current_item);
296*0a9064fbSMasahiro Yamada static void handle_f9(int *key, struct menu *current_item);
297*0a9064fbSMasahiro Yamada 
298*0a9064fbSMasahiro Yamada struct function_keys {
299*0a9064fbSMasahiro Yamada 	const char *key_str;
300*0a9064fbSMasahiro Yamada 	const char *func;
301*0a9064fbSMasahiro Yamada 	function_key key;
302*0a9064fbSMasahiro Yamada 	function_key_handler_t handler;
303*0a9064fbSMasahiro Yamada };
304*0a9064fbSMasahiro Yamada 
305*0a9064fbSMasahiro Yamada static const int function_keys_num = 9;
306*0a9064fbSMasahiro Yamada struct function_keys function_keys[] = {
307*0a9064fbSMasahiro Yamada 	{
308*0a9064fbSMasahiro Yamada 		.key_str = "F1",
309*0a9064fbSMasahiro Yamada 		.func = "Help",
310*0a9064fbSMasahiro Yamada 		.key = F_HELP,
311*0a9064fbSMasahiro Yamada 		.handler = handle_f1,
312*0a9064fbSMasahiro Yamada 	},
313*0a9064fbSMasahiro Yamada 	{
314*0a9064fbSMasahiro Yamada 		.key_str = "F2",
315*0a9064fbSMasahiro Yamada 		.func = "SymInfo",
316*0a9064fbSMasahiro Yamada 		.key = F_SYMBOL,
317*0a9064fbSMasahiro Yamada 		.handler = handle_f2,
318*0a9064fbSMasahiro Yamada 	},
319*0a9064fbSMasahiro Yamada 	{
320*0a9064fbSMasahiro Yamada 		.key_str = "F3",
321*0a9064fbSMasahiro Yamada 		.func = "Help 2",
322*0a9064fbSMasahiro Yamada 		.key = F_INSTS,
323*0a9064fbSMasahiro Yamada 		.handler = handle_f3,
324*0a9064fbSMasahiro Yamada 	},
325*0a9064fbSMasahiro Yamada 	{
326*0a9064fbSMasahiro Yamada 		.key_str = "F4",
327*0a9064fbSMasahiro Yamada 		.func = "ShowAll",
328*0a9064fbSMasahiro Yamada 		.key = F_CONF,
329*0a9064fbSMasahiro Yamada 		.handler = handle_f4,
330*0a9064fbSMasahiro Yamada 	},
331*0a9064fbSMasahiro Yamada 	{
332*0a9064fbSMasahiro Yamada 		.key_str = "F5",
333*0a9064fbSMasahiro Yamada 		.func = "Back",
334*0a9064fbSMasahiro Yamada 		.key = F_BACK,
335*0a9064fbSMasahiro Yamada 		.handler = handle_f5,
336*0a9064fbSMasahiro Yamada 	},
337*0a9064fbSMasahiro Yamada 	{
338*0a9064fbSMasahiro Yamada 		.key_str = "F6",
339*0a9064fbSMasahiro Yamada 		.func = "Save",
340*0a9064fbSMasahiro Yamada 		.key = F_SAVE,
341*0a9064fbSMasahiro Yamada 		.handler = handle_f6,
342*0a9064fbSMasahiro Yamada 	},
343*0a9064fbSMasahiro Yamada 	{
344*0a9064fbSMasahiro Yamada 		.key_str = "F7",
345*0a9064fbSMasahiro Yamada 		.func = "Load",
346*0a9064fbSMasahiro Yamada 		.key = F_LOAD,
347*0a9064fbSMasahiro Yamada 		.handler = handle_f7,
348*0a9064fbSMasahiro Yamada 	},
349*0a9064fbSMasahiro Yamada 	{
350*0a9064fbSMasahiro Yamada 		.key_str = "F8",
351*0a9064fbSMasahiro Yamada 		.func = "SymSearch",
352*0a9064fbSMasahiro Yamada 		.key = F_SEARCH,
353*0a9064fbSMasahiro Yamada 		.handler = handle_f8,
354*0a9064fbSMasahiro Yamada 	},
355*0a9064fbSMasahiro Yamada 	{
356*0a9064fbSMasahiro Yamada 		.key_str = "F9",
357*0a9064fbSMasahiro Yamada 		.func = "Exit",
358*0a9064fbSMasahiro Yamada 		.key = F_EXIT,
359*0a9064fbSMasahiro Yamada 		.handler = handle_f9,
360*0a9064fbSMasahiro Yamada 	},
361*0a9064fbSMasahiro Yamada };
362*0a9064fbSMasahiro Yamada 
363*0a9064fbSMasahiro Yamada static void print_function_line(void)
364*0a9064fbSMasahiro Yamada {
365*0a9064fbSMasahiro Yamada 	int i;
366*0a9064fbSMasahiro Yamada 	int offset = 1;
367*0a9064fbSMasahiro Yamada 	const int skip = 1;
368*0a9064fbSMasahiro Yamada 	int lines = getmaxy(stdscr);
369*0a9064fbSMasahiro Yamada 
370*0a9064fbSMasahiro Yamada 	for (i = 0; i < function_keys_num; i++) {
371*0a9064fbSMasahiro Yamada 		(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
372*0a9064fbSMasahiro Yamada 		mvwprintw(main_window, lines-3, offset,
373*0a9064fbSMasahiro Yamada 				"%s",
374*0a9064fbSMasahiro Yamada 				function_keys[i].key_str);
375*0a9064fbSMasahiro Yamada 		(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
376*0a9064fbSMasahiro Yamada 		offset += strlen(function_keys[i].key_str);
377*0a9064fbSMasahiro Yamada 		mvwprintw(main_window, lines-3,
378*0a9064fbSMasahiro Yamada 				offset, "%s",
379*0a9064fbSMasahiro Yamada 				function_keys[i].func);
380*0a9064fbSMasahiro Yamada 		offset += strlen(function_keys[i].func) + skip;
381*0a9064fbSMasahiro Yamada 	}
382*0a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[NORMAL]);
383*0a9064fbSMasahiro Yamada }
384*0a9064fbSMasahiro Yamada 
385*0a9064fbSMasahiro Yamada /* help */
386*0a9064fbSMasahiro Yamada static void handle_f1(int *key, struct menu *current_item)
387*0a9064fbSMasahiro Yamada {
388*0a9064fbSMasahiro Yamada 	show_scroll_win(main_window,
389*0a9064fbSMasahiro Yamada 			_("Global help"), _(nconf_global_help));
390*0a9064fbSMasahiro Yamada 	return;
391*0a9064fbSMasahiro Yamada }
392*0a9064fbSMasahiro Yamada 
393*0a9064fbSMasahiro Yamada /* symbole help */
394*0a9064fbSMasahiro Yamada static void handle_f2(int *key, struct menu *current_item)
395*0a9064fbSMasahiro Yamada {
396*0a9064fbSMasahiro Yamada 	show_help(current_item);
397*0a9064fbSMasahiro Yamada 	return;
398*0a9064fbSMasahiro Yamada }
399*0a9064fbSMasahiro Yamada 
400*0a9064fbSMasahiro Yamada /* instructions */
401*0a9064fbSMasahiro Yamada static void handle_f3(int *key, struct menu *current_item)
402*0a9064fbSMasahiro Yamada {
403*0a9064fbSMasahiro Yamada 	show_scroll_win(main_window,
404*0a9064fbSMasahiro Yamada 			_("Short help"),
405*0a9064fbSMasahiro Yamada 			_(current_instructions));
406*0a9064fbSMasahiro Yamada 	return;
407*0a9064fbSMasahiro Yamada }
408*0a9064fbSMasahiro Yamada 
409*0a9064fbSMasahiro Yamada /* config */
410*0a9064fbSMasahiro Yamada static void handle_f4(int *key, struct menu *current_item)
411*0a9064fbSMasahiro Yamada {
412*0a9064fbSMasahiro Yamada 	int res = btn_dialog(main_window,
413*0a9064fbSMasahiro Yamada 			_("Show all symbols?"),
414*0a9064fbSMasahiro Yamada 			2,
415*0a9064fbSMasahiro Yamada 			"   <Show All>   ",
416*0a9064fbSMasahiro Yamada 			"<Don't show all>");
417*0a9064fbSMasahiro Yamada 	if (res == 0)
418*0a9064fbSMasahiro Yamada 		show_all_items = 1;
419*0a9064fbSMasahiro Yamada 	else if (res == 1)
420*0a9064fbSMasahiro Yamada 		show_all_items = 0;
421*0a9064fbSMasahiro Yamada 
422*0a9064fbSMasahiro Yamada 	return;
423*0a9064fbSMasahiro Yamada }
424*0a9064fbSMasahiro Yamada 
425*0a9064fbSMasahiro Yamada /* back */
426*0a9064fbSMasahiro Yamada static void handle_f5(int *key, struct menu *current_item)
427*0a9064fbSMasahiro Yamada {
428*0a9064fbSMasahiro Yamada 	*key = KEY_LEFT;
429*0a9064fbSMasahiro Yamada 	return;
430*0a9064fbSMasahiro Yamada }
431*0a9064fbSMasahiro Yamada 
432*0a9064fbSMasahiro Yamada /* save */
433*0a9064fbSMasahiro Yamada static void handle_f6(int *key, struct menu *current_item)
434*0a9064fbSMasahiro Yamada {
435*0a9064fbSMasahiro Yamada 	conf_save();
436*0a9064fbSMasahiro Yamada 	return;
437*0a9064fbSMasahiro Yamada }
438*0a9064fbSMasahiro Yamada 
439*0a9064fbSMasahiro Yamada /* load */
440*0a9064fbSMasahiro Yamada static void handle_f7(int *key, struct menu *current_item)
441*0a9064fbSMasahiro Yamada {
442*0a9064fbSMasahiro Yamada 	conf_load();
443*0a9064fbSMasahiro Yamada 	return;
444*0a9064fbSMasahiro Yamada }
445*0a9064fbSMasahiro Yamada 
446*0a9064fbSMasahiro Yamada /* search */
447*0a9064fbSMasahiro Yamada static void handle_f8(int *key, struct menu *current_item)
448*0a9064fbSMasahiro Yamada {
449*0a9064fbSMasahiro Yamada 	search_conf();
450*0a9064fbSMasahiro Yamada 	return;
451*0a9064fbSMasahiro Yamada }
452*0a9064fbSMasahiro Yamada 
453*0a9064fbSMasahiro Yamada /* exit */
454*0a9064fbSMasahiro Yamada static void handle_f9(int *key, struct menu *current_item)
455*0a9064fbSMasahiro Yamada {
456*0a9064fbSMasahiro Yamada 	do_exit();
457*0a9064fbSMasahiro Yamada 	return;
458*0a9064fbSMasahiro Yamada }
459*0a9064fbSMasahiro Yamada 
460*0a9064fbSMasahiro Yamada /* return != 0 to indicate the key was handles */
461*0a9064fbSMasahiro Yamada static int process_special_keys(int *key, struct menu *menu)
462*0a9064fbSMasahiro Yamada {
463*0a9064fbSMasahiro Yamada 	int i;
464*0a9064fbSMasahiro Yamada 
465*0a9064fbSMasahiro Yamada 	if (*key == KEY_RESIZE) {
466*0a9064fbSMasahiro Yamada 		setup_windows();
467*0a9064fbSMasahiro Yamada 		return 1;
468*0a9064fbSMasahiro Yamada 	}
469*0a9064fbSMasahiro Yamada 
470*0a9064fbSMasahiro Yamada 	for (i = 0; i < function_keys_num; i++) {
471*0a9064fbSMasahiro Yamada 		if (*key == KEY_F(function_keys[i].key) ||
472*0a9064fbSMasahiro Yamada 		    *key == '0' + function_keys[i].key){
473*0a9064fbSMasahiro Yamada 			function_keys[i].handler(key, menu);
474*0a9064fbSMasahiro Yamada 			return 1;
475*0a9064fbSMasahiro Yamada 		}
476*0a9064fbSMasahiro Yamada 	}
477*0a9064fbSMasahiro Yamada 
478*0a9064fbSMasahiro Yamada 	return 0;
479*0a9064fbSMasahiro Yamada }
480*0a9064fbSMasahiro Yamada 
481*0a9064fbSMasahiro Yamada static void clean_items(void)
482*0a9064fbSMasahiro Yamada {
483*0a9064fbSMasahiro Yamada 	int i;
484*0a9064fbSMasahiro Yamada 	for (i = 0; curses_menu_items[i]; i++)
485*0a9064fbSMasahiro Yamada 		free_item(curses_menu_items[i]);
486*0a9064fbSMasahiro Yamada 	bzero(curses_menu_items, sizeof(curses_menu_items));
487*0a9064fbSMasahiro Yamada 	bzero(k_menu_items, sizeof(k_menu_items));
488*0a9064fbSMasahiro Yamada 	items_num = 0;
489*0a9064fbSMasahiro Yamada }
490*0a9064fbSMasahiro Yamada 
491*0a9064fbSMasahiro Yamada typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
492*0a9064fbSMasahiro Yamada 	FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
493*0a9064fbSMasahiro Yamada 
494*0a9064fbSMasahiro Yamada /* return the index of the matched item, or -1 if no such item exists */
495*0a9064fbSMasahiro Yamada static int get_mext_match(const char *match_str, match_f flag)
496*0a9064fbSMasahiro Yamada {
497*0a9064fbSMasahiro Yamada 	int match_start = item_index(current_item(curses_menu));
498*0a9064fbSMasahiro Yamada 	int index;
499*0a9064fbSMasahiro Yamada 
500*0a9064fbSMasahiro Yamada 	if (flag == FIND_NEXT_MATCH_DOWN)
501*0a9064fbSMasahiro Yamada 		++match_start;
502*0a9064fbSMasahiro Yamada 	else if (flag == FIND_NEXT_MATCH_UP)
503*0a9064fbSMasahiro Yamada 		--match_start;
504*0a9064fbSMasahiro Yamada 
505*0a9064fbSMasahiro Yamada 	index = match_start;
506*0a9064fbSMasahiro Yamada 	index = (index + items_num) % items_num;
507*0a9064fbSMasahiro Yamada 	while (true) {
508*0a9064fbSMasahiro Yamada 		char *str = k_menu_items[index].str;
509*0a9064fbSMasahiro Yamada 		if (strcasestr(str, match_str) != 0)
510*0a9064fbSMasahiro Yamada 			return index;
511*0a9064fbSMasahiro Yamada 		if (flag == FIND_NEXT_MATCH_UP ||
512*0a9064fbSMasahiro Yamada 		    flag == MATCH_TINKER_PATTERN_UP)
513*0a9064fbSMasahiro Yamada 			--index;
514*0a9064fbSMasahiro Yamada 		else
515*0a9064fbSMasahiro Yamada 			++index;
516*0a9064fbSMasahiro Yamada 		index = (index + items_num) % items_num;
517*0a9064fbSMasahiro Yamada 		if (index == match_start)
518*0a9064fbSMasahiro Yamada 			return -1;
519*0a9064fbSMasahiro Yamada 	}
520*0a9064fbSMasahiro Yamada }
521*0a9064fbSMasahiro Yamada 
522*0a9064fbSMasahiro Yamada /* Make a new item. */
523*0a9064fbSMasahiro Yamada static void item_make(struct menu *menu, char tag, const char *fmt, ...)
524*0a9064fbSMasahiro Yamada {
525*0a9064fbSMasahiro Yamada 	va_list ap;
526*0a9064fbSMasahiro Yamada 
527*0a9064fbSMasahiro Yamada 	if (items_num > MAX_MENU_ITEMS-1)
528*0a9064fbSMasahiro Yamada 		return;
529*0a9064fbSMasahiro Yamada 
530*0a9064fbSMasahiro Yamada 	bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
531*0a9064fbSMasahiro Yamada 	k_menu_items[items_num].tag = tag;
532*0a9064fbSMasahiro Yamada 	k_menu_items[items_num].usrptr = menu;
533*0a9064fbSMasahiro Yamada 	if (menu != NULL)
534*0a9064fbSMasahiro Yamada 		k_menu_items[items_num].is_visible =
535*0a9064fbSMasahiro Yamada 			menu_is_visible(menu);
536*0a9064fbSMasahiro Yamada 	else
537*0a9064fbSMasahiro Yamada 		k_menu_items[items_num].is_visible = 1;
538*0a9064fbSMasahiro Yamada 
539*0a9064fbSMasahiro Yamada 	va_start(ap, fmt);
540*0a9064fbSMasahiro Yamada 	vsnprintf(k_menu_items[items_num].str,
541*0a9064fbSMasahiro Yamada 		  sizeof(k_menu_items[items_num].str),
542*0a9064fbSMasahiro Yamada 		  fmt, ap);
543*0a9064fbSMasahiro Yamada 	va_end(ap);
544*0a9064fbSMasahiro Yamada 
545*0a9064fbSMasahiro Yamada 	if (!k_menu_items[items_num].is_visible)
546*0a9064fbSMasahiro Yamada 		memcpy(k_menu_items[items_num].str, "XXX", 3);
547*0a9064fbSMasahiro Yamada 
548*0a9064fbSMasahiro Yamada 	curses_menu_items[items_num] = new_item(
549*0a9064fbSMasahiro Yamada 			k_menu_items[items_num].str,
550*0a9064fbSMasahiro Yamada 			k_menu_items[items_num].str);
551*0a9064fbSMasahiro Yamada 	set_item_userptr(curses_menu_items[items_num],
552*0a9064fbSMasahiro Yamada 			&k_menu_items[items_num]);
553*0a9064fbSMasahiro Yamada 	/*
554*0a9064fbSMasahiro Yamada 	if (!k_menu_items[items_num].is_visible)
555*0a9064fbSMasahiro Yamada 		item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
556*0a9064fbSMasahiro Yamada 	*/
557*0a9064fbSMasahiro Yamada 
558*0a9064fbSMasahiro Yamada 	items_num++;
559*0a9064fbSMasahiro Yamada 	curses_menu_items[items_num] = NULL;
560*0a9064fbSMasahiro Yamada }
561*0a9064fbSMasahiro Yamada 
562*0a9064fbSMasahiro Yamada /* very hackish. adds a string to the last item added */
563*0a9064fbSMasahiro Yamada static void item_add_str(const char *fmt, ...)
564*0a9064fbSMasahiro Yamada {
565*0a9064fbSMasahiro Yamada 	va_list ap;
566*0a9064fbSMasahiro Yamada 	int index = items_num-1;
567*0a9064fbSMasahiro Yamada 	char new_str[256];
568*0a9064fbSMasahiro Yamada 	char tmp_str[256];
569*0a9064fbSMasahiro Yamada 
570*0a9064fbSMasahiro Yamada 	if (index < 0)
571*0a9064fbSMasahiro Yamada 		return;
572*0a9064fbSMasahiro Yamada 
573*0a9064fbSMasahiro Yamada 	va_start(ap, fmt);
574*0a9064fbSMasahiro Yamada 	vsnprintf(new_str, sizeof(new_str), fmt, ap);
575*0a9064fbSMasahiro Yamada 	va_end(ap);
576*0a9064fbSMasahiro Yamada 	snprintf(tmp_str, sizeof(tmp_str), "%s%s",
577*0a9064fbSMasahiro Yamada 			k_menu_items[index].str, new_str);
578*0a9064fbSMasahiro Yamada 	strncpy(k_menu_items[index].str,
579*0a9064fbSMasahiro Yamada 		tmp_str,
580*0a9064fbSMasahiro Yamada 		sizeof(k_menu_items[index].str));
581*0a9064fbSMasahiro Yamada 
582*0a9064fbSMasahiro Yamada 	free_item(curses_menu_items[index]);
583*0a9064fbSMasahiro Yamada 	curses_menu_items[index] = new_item(
584*0a9064fbSMasahiro Yamada 			k_menu_items[index].str,
585*0a9064fbSMasahiro Yamada 			k_menu_items[index].str);
586*0a9064fbSMasahiro Yamada 	set_item_userptr(curses_menu_items[index],
587*0a9064fbSMasahiro Yamada 			&k_menu_items[index]);
588*0a9064fbSMasahiro Yamada }
589*0a9064fbSMasahiro Yamada 
590*0a9064fbSMasahiro Yamada /* get the tag of the currently selected item */
591*0a9064fbSMasahiro Yamada static char item_tag(void)
592*0a9064fbSMasahiro Yamada {
593*0a9064fbSMasahiro Yamada 	ITEM *cur;
594*0a9064fbSMasahiro Yamada 	struct mitem *mcur;
595*0a9064fbSMasahiro Yamada 
596*0a9064fbSMasahiro Yamada 	cur = current_item(curses_menu);
597*0a9064fbSMasahiro Yamada 	if (cur == NULL)
598*0a9064fbSMasahiro Yamada 		return 0;
599*0a9064fbSMasahiro Yamada 	mcur = (struct mitem *) item_userptr(cur);
600*0a9064fbSMasahiro Yamada 	return mcur->tag;
601*0a9064fbSMasahiro Yamada }
602*0a9064fbSMasahiro Yamada 
603*0a9064fbSMasahiro Yamada static int curses_item_index(void)
604*0a9064fbSMasahiro Yamada {
605*0a9064fbSMasahiro Yamada 	return  item_index(current_item(curses_menu));
606*0a9064fbSMasahiro Yamada }
607*0a9064fbSMasahiro Yamada 
608*0a9064fbSMasahiro Yamada static void *item_data(void)
609*0a9064fbSMasahiro Yamada {
610*0a9064fbSMasahiro Yamada 	ITEM *cur;
611*0a9064fbSMasahiro Yamada 	struct mitem *mcur;
612*0a9064fbSMasahiro Yamada 
613*0a9064fbSMasahiro Yamada 	cur = current_item(curses_menu);
614*0a9064fbSMasahiro Yamada 	if (!cur)
615*0a9064fbSMasahiro Yamada 		return NULL;
616*0a9064fbSMasahiro Yamada 	mcur = (struct mitem *) item_userptr(cur);
617*0a9064fbSMasahiro Yamada 	return mcur->usrptr;
618*0a9064fbSMasahiro Yamada 
619*0a9064fbSMasahiro Yamada }
620*0a9064fbSMasahiro Yamada 
621*0a9064fbSMasahiro Yamada static int item_is_tag(char tag)
622*0a9064fbSMasahiro Yamada {
623*0a9064fbSMasahiro Yamada 	return item_tag() == tag;
624*0a9064fbSMasahiro Yamada }
625*0a9064fbSMasahiro Yamada 
626*0a9064fbSMasahiro Yamada static char filename[PATH_MAX+1];
627*0a9064fbSMasahiro Yamada static char menu_backtitle[PATH_MAX+128];
628*0a9064fbSMasahiro Yamada static const char *set_config_filename(const char *config_filename)
629*0a9064fbSMasahiro Yamada {
630*0a9064fbSMasahiro Yamada 	int size;
631*0a9064fbSMasahiro Yamada 
632*0a9064fbSMasahiro Yamada 	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
633*0a9064fbSMasahiro Yamada 			"%s - %s", config_filename, rootmenu.prompt->text);
634*0a9064fbSMasahiro Yamada 	if (size >= sizeof(menu_backtitle))
635*0a9064fbSMasahiro Yamada 		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
636*0a9064fbSMasahiro Yamada 
637*0a9064fbSMasahiro Yamada 	size = snprintf(filename, sizeof(filename), "%s", config_filename);
638*0a9064fbSMasahiro Yamada 	if (size >= sizeof(filename))
639*0a9064fbSMasahiro Yamada 		filename[sizeof(filename)-1] = '\0';
640*0a9064fbSMasahiro Yamada 	return menu_backtitle;
641*0a9064fbSMasahiro Yamada }
642*0a9064fbSMasahiro Yamada 
643*0a9064fbSMasahiro Yamada /* return = 0 means we are successful.
644*0a9064fbSMasahiro Yamada  * -1 means go on doing what you were doing
645*0a9064fbSMasahiro Yamada  */
646*0a9064fbSMasahiro Yamada static int do_exit(void)
647*0a9064fbSMasahiro Yamada {
648*0a9064fbSMasahiro Yamada 	int res;
649*0a9064fbSMasahiro Yamada 	if (!conf_get_changed()) {
650*0a9064fbSMasahiro Yamada 		global_exit = 1;
651*0a9064fbSMasahiro Yamada 		return 0;
652*0a9064fbSMasahiro Yamada 	}
653*0a9064fbSMasahiro Yamada 	res = btn_dialog(main_window,
654*0a9064fbSMasahiro Yamada 			_("Do you wish to save your new configuration?\n"
655*0a9064fbSMasahiro Yamada 				"<ESC> to cancel and resume nconfig."),
656*0a9064fbSMasahiro Yamada 			2,
657*0a9064fbSMasahiro Yamada 			"   <save>   ",
658*0a9064fbSMasahiro Yamada 			"<don't save>");
659*0a9064fbSMasahiro Yamada 	if (res == KEY_EXIT) {
660*0a9064fbSMasahiro Yamada 		global_exit = 0;
661*0a9064fbSMasahiro Yamada 		return -1;
662*0a9064fbSMasahiro Yamada 	}
663*0a9064fbSMasahiro Yamada 
664*0a9064fbSMasahiro Yamada 	/* if we got here, the user really wants to exit */
665*0a9064fbSMasahiro Yamada 	switch (res) {
666*0a9064fbSMasahiro Yamada 	case 0:
667*0a9064fbSMasahiro Yamada 		res = conf_write(filename);
668*0a9064fbSMasahiro Yamada 		if (res)
669*0a9064fbSMasahiro Yamada 			btn_dialog(
670*0a9064fbSMasahiro Yamada 				main_window,
671*0a9064fbSMasahiro Yamada 				_("Error during writing of configuration.\n"
672*0a9064fbSMasahiro Yamada 				  "Your configuration changes were NOT saved."),
673*0a9064fbSMasahiro Yamada 				  1,
674*0a9064fbSMasahiro Yamada 				  "<OK>");
675*0a9064fbSMasahiro Yamada 		break;
676*0a9064fbSMasahiro Yamada 	default:
677*0a9064fbSMasahiro Yamada 		btn_dialog(
678*0a9064fbSMasahiro Yamada 			main_window,
679*0a9064fbSMasahiro Yamada 			_("Your configuration changes were NOT saved."),
680*0a9064fbSMasahiro Yamada 			1,
681*0a9064fbSMasahiro Yamada 			"<OK>");
682*0a9064fbSMasahiro Yamada 		break;
683*0a9064fbSMasahiro Yamada 	}
684*0a9064fbSMasahiro Yamada 	global_exit = 1;
685*0a9064fbSMasahiro Yamada 	return 0;
686*0a9064fbSMasahiro Yamada }
687*0a9064fbSMasahiro Yamada 
688*0a9064fbSMasahiro Yamada 
689*0a9064fbSMasahiro Yamada static void search_conf(void)
690*0a9064fbSMasahiro Yamada {
691*0a9064fbSMasahiro Yamada 	struct symbol **sym_arr;
692*0a9064fbSMasahiro Yamada 	struct gstr res;
693*0a9064fbSMasahiro Yamada 	struct gstr title;
694*0a9064fbSMasahiro Yamada 	char *dialog_input;
695*0a9064fbSMasahiro Yamada 	int dres;
696*0a9064fbSMasahiro Yamada 
697*0a9064fbSMasahiro Yamada 	title = str_new();
698*0a9064fbSMasahiro Yamada 	str_printf( &title, _("Enter (sub)string or regexp to search for "
699*0a9064fbSMasahiro Yamada 			      "(with or without \"%s\")"), CONFIG_);
700*0a9064fbSMasahiro Yamada 
701*0a9064fbSMasahiro Yamada again:
702*0a9064fbSMasahiro Yamada 	dres = dialog_inputbox(main_window,
703*0a9064fbSMasahiro Yamada 			_("Search Configuration Parameter"),
704*0a9064fbSMasahiro Yamada 			str_get(&title),
705*0a9064fbSMasahiro Yamada 			"", &dialog_input_result, &dialog_input_result_len);
706*0a9064fbSMasahiro Yamada 	switch (dres) {
707*0a9064fbSMasahiro Yamada 	case 0:
708*0a9064fbSMasahiro Yamada 		break;
709*0a9064fbSMasahiro Yamada 	case 1:
710*0a9064fbSMasahiro Yamada 		show_scroll_win(main_window,
711*0a9064fbSMasahiro Yamada 				_("Search Configuration"), search_help);
712*0a9064fbSMasahiro Yamada 		goto again;
713*0a9064fbSMasahiro Yamada 	default:
714*0a9064fbSMasahiro Yamada 		str_free(&title);
715*0a9064fbSMasahiro Yamada 		return;
716*0a9064fbSMasahiro Yamada 	}
717*0a9064fbSMasahiro Yamada 
718*0a9064fbSMasahiro Yamada 	/* strip the prefix if necessary */
719*0a9064fbSMasahiro Yamada 	dialog_input = dialog_input_result;
720*0a9064fbSMasahiro Yamada 	if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
721*0a9064fbSMasahiro Yamada 		dialog_input += strlen(CONFIG_);
722*0a9064fbSMasahiro Yamada 
723*0a9064fbSMasahiro Yamada 	sym_arr = sym_re_search(dialog_input);
724*0a9064fbSMasahiro Yamada 	res = get_relations_str(sym_arr, NULL);
725*0a9064fbSMasahiro Yamada 	free(sym_arr);
726*0a9064fbSMasahiro Yamada 	show_scroll_win(main_window,
727*0a9064fbSMasahiro Yamada 			_("Search Results"), str_get(&res));
728*0a9064fbSMasahiro Yamada 	str_free(&res);
729*0a9064fbSMasahiro Yamada 	str_free(&title);
730*0a9064fbSMasahiro Yamada }
731*0a9064fbSMasahiro Yamada 
732*0a9064fbSMasahiro Yamada 
733*0a9064fbSMasahiro Yamada static void build_conf(struct menu *menu)
734*0a9064fbSMasahiro Yamada {
735*0a9064fbSMasahiro Yamada 	struct symbol *sym;
736*0a9064fbSMasahiro Yamada 	struct property *prop;
737*0a9064fbSMasahiro Yamada 	struct menu *child;
738*0a9064fbSMasahiro Yamada 	int type, tmp, doint = 2;
739*0a9064fbSMasahiro Yamada 	tristate val;
740*0a9064fbSMasahiro Yamada 	char ch;
741*0a9064fbSMasahiro Yamada 
742*0a9064fbSMasahiro Yamada 	if (!menu || (!show_all_items && !menu_is_visible(menu)))
743*0a9064fbSMasahiro Yamada 		return;
744*0a9064fbSMasahiro Yamada 
745*0a9064fbSMasahiro Yamada 	sym = menu->sym;
746*0a9064fbSMasahiro Yamada 	prop = menu->prompt;
747*0a9064fbSMasahiro Yamada 	if (!sym) {
748*0a9064fbSMasahiro Yamada 		if (prop && menu != current_menu) {
749*0a9064fbSMasahiro Yamada 			const char *prompt = menu_get_prompt(menu);
750*0a9064fbSMasahiro Yamada 			enum prop_type ptype;
751*0a9064fbSMasahiro Yamada 			ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
752*0a9064fbSMasahiro Yamada 			switch (ptype) {
753*0a9064fbSMasahiro Yamada 			case P_MENU:
754*0a9064fbSMasahiro Yamada 				child_count++;
755*0a9064fbSMasahiro Yamada 				prompt = _(prompt);
756*0a9064fbSMasahiro Yamada 				if (single_menu_mode) {
757*0a9064fbSMasahiro Yamada 					item_make(menu, 'm',
758*0a9064fbSMasahiro Yamada 						"%s%*c%s",
759*0a9064fbSMasahiro Yamada 						menu->data ? "-->" : "++>",
760*0a9064fbSMasahiro Yamada 						indent + 1, ' ', prompt);
761*0a9064fbSMasahiro Yamada 				} else
762*0a9064fbSMasahiro Yamada 					item_make(menu, 'm',
763*0a9064fbSMasahiro Yamada 						  "   %*c%s  %s",
764*0a9064fbSMasahiro Yamada 						  indent + 1, ' ', prompt,
765*0a9064fbSMasahiro Yamada 						  menu_is_empty(menu) ? "----" : "--->");
766*0a9064fbSMasahiro Yamada 
767*0a9064fbSMasahiro Yamada 				if (single_menu_mode && menu->data)
768*0a9064fbSMasahiro Yamada 					goto conf_childs;
769*0a9064fbSMasahiro Yamada 				return;
770*0a9064fbSMasahiro Yamada 			case P_COMMENT:
771*0a9064fbSMasahiro Yamada 				if (prompt) {
772*0a9064fbSMasahiro Yamada 					child_count++;
773*0a9064fbSMasahiro Yamada 					item_make(menu, ':',
774*0a9064fbSMasahiro Yamada 						"   %*c*** %s ***",
775*0a9064fbSMasahiro Yamada 						indent + 1, ' ',
776*0a9064fbSMasahiro Yamada 						_(prompt));
777*0a9064fbSMasahiro Yamada 				}
778*0a9064fbSMasahiro Yamada 				break;
779*0a9064fbSMasahiro Yamada 			default:
780*0a9064fbSMasahiro Yamada 				if (prompt) {
781*0a9064fbSMasahiro Yamada 					child_count++;
782*0a9064fbSMasahiro Yamada 					item_make(menu, ':', "---%*c%s",
783*0a9064fbSMasahiro Yamada 						indent + 1, ' ',
784*0a9064fbSMasahiro Yamada 						_(prompt));
785*0a9064fbSMasahiro Yamada 				}
786*0a9064fbSMasahiro Yamada 			}
787*0a9064fbSMasahiro Yamada 		} else
788*0a9064fbSMasahiro Yamada 			doint = 0;
789*0a9064fbSMasahiro Yamada 		goto conf_childs;
790*0a9064fbSMasahiro Yamada 	}
791*0a9064fbSMasahiro Yamada 
792*0a9064fbSMasahiro Yamada 	type = sym_get_type(sym);
793*0a9064fbSMasahiro Yamada 	if (sym_is_choice(sym)) {
794*0a9064fbSMasahiro Yamada 		struct symbol *def_sym = sym_get_choice_value(sym);
795*0a9064fbSMasahiro Yamada 		struct menu *def_menu = NULL;
796*0a9064fbSMasahiro Yamada 
797*0a9064fbSMasahiro Yamada 		child_count++;
798*0a9064fbSMasahiro Yamada 		for (child = menu->list; child; child = child->next) {
799*0a9064fbSMasahiro Yamada 			if (menu_is_visible(child) && child->sym == def_sym)
800*0a9064fbSMasahiro Yamada 				def_menu = child;
801*0a9064fbSMasahiro Yamada 		}
802*0a9064fbSMasahiro Yamada 
803*0a9064fbSMasahiro Yamada 		val = sym_get_tristate_value(sym);
804*0a9064fbSMasahiro Yamada 		if (sym_is_changable(sym)) {
805*0a9064fbSMasahiro Yamada 			switch (type) {
806*0a9064fbSMasahiro Yamada 			case S_BOOLEAN:
807*0a9064fbSMasahiro Yamada 				item_make(menu, 't', "[%c]",
808*0a9064fbSMasahiro Yamada 						val == no ? ' ' : '*');
809*0a9064fbSMasahiro Yamada 				break;
810*0a9064fbSMasahiro Yamada 			case S_TRISTATE:
811*0a9064fbSMasahiro Yamada 				switch (val) {
812*0a9064fbSMasahiro Yamada 				case yes:
813*0a9064fbSMasahiro Yamada 					ch = '*';
814*0a9064fbSMasahiro Yamada 					break;
815*0a9064fbSMasahiro Yamada 				case mod:
816*0a9064fbSMasahiro Yamada 					ch = 'M';
817*0a9064fbSMasahiro Yamada 					break;
818*0a9064fbSMasahiro Yamada 				default:
819*0a9064fbSMasahiro Yamada 					ch = ' ';
820*0a9064fbSMasahiro Yamada 					break;
821*0a9064fbSMasahiro Yamada 				}
822*0a9064fbSMasahiro Yamada 				item_make(menu, 't', "<%c>", ch);
823*0a9064fbSMasahiro Yamada 				break;
824*0a9064fbSMasahiro Yamada 			}
825*0a9064fbSMasahiro Yamada 		} else {
826*0a9064fbSMasahiro Yamada 			item_make(menu, def_menu ? 't' : ':', "   ");
827*0a9064fbSMasahiro Yamada 		}
828*0a9064fbSMasahiro Yamada 
829*0a9064fbSMasahiro Yamada 		item_add_str("%*c%s", indent + 1,
830*0a9064fbSMasahiro Yamada 				' ', _(menu_get_prompt(menu)));
831*0a9064fbSMasahiro Yamada 		if (val == yes) {
832*0a9064fbSMasahiro Yamada 			if (def_menu) {
833*0a9064fbSMasahiro Yamada 				item_add_str(" (%s)",
834*0a9064fbSMasahiro Yamada 					_(menu_get_prompt(def_menu)));
835*0a9064fbSMasahiro Yamada 				item_add_str("  --->");
836*0a9064fbSMasahiro Yamada 				if (def_menu->list) {
837*0a9064fbSMasahiro Yamada 					indent += 2;
838*0a9064fbSMasahiro Yamada 					build_conf(def_menu);
839*0a9064fbSMasahiro Yamada 					indent -= 2;
840*0a9064fbSMasahiro Yamada 				}
841*0a9064fbSMasahiro Yamada 			}
842*0a9064fbSMasahiro Yamada 			return;
843*0a9064fbSMasahiro Yamada 		}
844*0a9064fbSMasahiro Yamada 	} else {
845*0a9064fbSMasahiro Yamada 		if (menu == current_menu) {
846*0a9064fbSMasahiro Yamada 			item_make(menu, ':',
847*0a9064fbSMasahiro Yamada 				"---%*c%s", indent + 1,
848*0a9064fbSMasahiro Yamada 				' ', _(menu_get_prompt(menu)));
849*0a9064fbSMasahiro Yamada 			goto conf_childs;
850*0a9064fbSMasahiro Yamada 		}
851*0a9064fbSMasahiro Yamada 		child_count++;
852*0a9064fbSMasahiro Yamada 		val = sym_get_tristate_value(sym);
853*0a9064fbSMasahiro Yamada 		if (sym_is_choice_value(sym) && val == yes) {
854*0a9064fbSMasahiro Yamada 			item_make(menu, ':', "   ");
855*0a9064fbSMasahiro Yamada 		} else {
856*0a9064fbSMasahiro Yamada 			switch (type) {
857*0a9064fbSMasahiro Yamada 			case S_BOOLEAN:
858*0a9064fbSMasahiro Yamada 				if (sym_is_changable(sym))
859*0a9064fbSMasahiro Yamada 					item_make(menu, 't', "[%c]",
860*0a9064fbSMasahiro Yamada 						val == no ? ' ' : '*');
861*0a9064fbSMasahiro Yamada 				else
862*0a9064fbSMasahiro Yamada 					item_make(menu, 't', "-%c-",
863*0a9064fbSMasahiro Yamada 						val == no ? ' ' : '*');
864*0a9064fbSMasahiro Yamada 				break;
865*0a9064fbSMasahiro Yamada 			case S_TRISTATE:
866*0a9064fbSMasahiro Yamada 				switch (val) {
867*0a9064fbSMasahiro Yamada 				case yes:
868*0a9064fbSMasahiro Yamada 					ch = '*';
869*0a9064fbSMasahiro Yamada 					break;
870*0a9064fbSMasahiro Yamada 				case mod:
871*0a9064fbSMasahiro Yamada 					ch = 'M';
872*0a9064fbSMasahiro Yamada 					break;
873*0a9064fbSMasahiro Yamada 				default:
874*0a9064fbSMasahiro Yamada 					ch = ' ';
875*0a9064fbSMasahiro Yamada 					break;
876*0a9064fbSMasahiro Yamada 				}
877*0a9064fbSMasahiro Yamada 				if (sym_is_changable(sym)) {
878*0a9064fbSMasahiro Yamada 					if (sym->rev_dep.tri == mod)
879*0a9064fbSMasahiro Yamada 						item_make(menu,
880*0a9064fbSMasahiro Yamada 							't', "{%c}", ch);
881*0a9064fbSMasahiro Yamada 					else
882*0a9064fbSMasahiro Yamada 						item_make(menu,
883*0a9064fbSMasahiro Yamada 							't', "<%c>", ch);
884*0a9064fbSMasahiro Yamada 				} else
885*0a9064fbSMasahiro Yamada 					item_make(menu, 't', "-%c-", ch);
886*0a9064fbSMasahiro Yamada 				break;
887*0a9064fbSMasahiro Yamada 			default:
888*0a9064fbSMasahiro Yamada 				tmp = 2 + strlen(sym_get_string_value(sym));
889*0a9064fbSMasahiro Yamada 				item_make(menu, 's', "    (%s)",
890*0a9064fbSMasahiro Yamada 						sym_get_string_value(sym));
891*0a9064fbSMasahiro Yamada 				tmp = indent - tmp + 4;
892*0a9064fbSMasahiro Yamada 				if (tmp < 0)
893*0a9064fbSMasahiro Yamada 					tmp = 0;
894*0a9064fbSMasahiro Yamada 				item_add_str("%*c%s%s", tmp, ' ',
895*0a9064fbSMasahiro Yamada 						_(menu_get_prompt(menu)),
896*0a9064fbSMasahiro Yamada 						(sym_has_value(sym) ||
897*0a9064fbSMasahiro Yamada 						 !sym_is_changable(sym)) ? "" :
898*0a9064fbSMasahiro Yamada 						_(" (NEW)"));
899*0a9064fbSMasahiro Yamada 				goto conf_childs;
900*0a9064fbSMasahiro Yamada 			}
901*0a9064fbSMasahiro Yamada 		}
902*0a9064fbSMasahiro Yamada 		item_add_str("%*c%s%s", indent + 1, ' ',
903*0a9064fbSMasahiro Yamada 				_(menu_get_prompt(menu)),
904*0a9064fbSMasahiro Yamada 				(sym_has_value(sym) || !sym_is_changable(sym)) ?
905*0a9064fbSMasahiro Yamada 				"" : _(" (NEW)"));
906*0a9064fbSMasahiro Yamada 		if (menu->prompt && menu->prompt->type == P_MENU) {
907*0a9064fbSMasahiro Yamada 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");
908*0a9064fbSMasahiro Yamada 			return;
909*0a9064fbSMasahiro Yamada 		}
910*0a9064fbSMasahiro Yamada 	}
911*0a9064fbSMasahiro Yamada 
912*0a9064fbSMasahiro Yamada conf_childs:
913*0a9064fbSMasahiro Yamada 	indent += doint;
914*0a9064fbSMasahiro Yamada 	for (child = menu->list; child; child = child->next)
915*0a9064fbSMasahiro Yamada 		build_conf(child);
916*0a9064fbSMasahiro Yamada 	indent -= doint;
917*0a9064fbSMasahiro Yamada }
918*0a9064fbSMasahiro Yamada 
919*0a9064fbSMasahiro Yamada static void reset_menu(void)
920*0a9064fbSMasahiro Yamada {
921*0a9064fbSMasahiro Yamada 	unpost_menu(curses_menu);
922*0a9064fbSMasahiro Yamada 	clean_items();
923*0a9064fbSMasahiro Yamada }
924*0a9064fbSMasahiro Yamada 
925*0a9064fbSMasahiro Yamada /* adjust the menu to show this item.
926*0a9064fbSMasahiro Yamada  * prefer not to scroll the menu if possible*/
927*0a9064fbSMasahiro Yamada static void center_item(int selected_index, int *last_top_row)
928*0a9064fbSMasahiro Yamada {
929*0a9064fbSMasahiro Yamada 	int toprow;
930*0a9064fbSMasahiro Yamada 
931*0a9064fbSMasahiro Yamada 	set_top_row(curses_menu, *last_top_row);
932*0a9064fbSMasahiro Yamada 	toprow = top_row(curses_menu);
933*0a9064fbSMasahiro Yamada 	if (selected_index < toprow ||
934*0a9064fbSMasahiro Yamada 	    selected_index >= toprow+mwin_max_lines) {
935*0a9064fbSMasahiro Yamada 		toprow = max(selected_index-mwin_max_lines/2, 0);
936*0a9064fbSMasahiro Yamada 		if (toprow >= item_count(curses_menu)-mwin_max_lines)
937*0a9064fbSMasahiro Yamada 			toprow = item_count(curses_menu)-mwin_max_lines;
938*0a9064fbSMasahiro Yamada 		set_top_row(curses_menu, toprow);
939*0a9064fbSMasahiro Yamada 	}
940*0a9064fbSMasahiro Yamada 	set_current_item(curses_menu,
941*0a9064fbSMasahiro Yamada 			curses_menu_items[selected_index]);
942*0a9064fbSMasahiro Yamada 	*last_top_row = toprow;
943*0a9064fbSMasahiro Yamada 	post_menu(curses_menu);
944*0a9064fbSMasahiro Yamada 	refresh_all_windows(main_window);
945*0a9064fbSMasahiro Yamada }
946*0a9064fbSMasahiro Yamada 
947*0a9064fbSMasahiro Yamada /* this function assumes reset_menu has been called before */
948*0a9064fbSMasahiro Yamada static void show_menu(const char *prompt, const char *instructions,
949*0a9064fbSMasahiro Yamada 		int selected_index, int *last_top_row)
950*0a9064fbSMasahiro Yamada {
951*0a9064fbSMasahiro Yamada 	int maxx, maxy;
952*0a9064fbSMasahiro Yamada 	WINDOW *menu_window;
953*0a9064fbSMasahiro Yamada 
954*0a9064fbSMasahiro Yamada 	current_instructions = instructions;
955*0a9064fbSMasahiro Yamada 
956*0a9064fbSMasahiro Yamada 	clear();
957*0a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[NORMAL]);
958*0a9064fbSMasahiro Yamada 	print_in_middle(stdscr, 1, 0, getmaxx(stdscr),
959*0a9064fbSMasahiro Yamada 			menu_backtitle,
960*0a9064fbSMasahiro Yamada 			attributes[MAIN_HEADING]);
961*0a9064fbSMasahiro Yamada 
962*0a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
963*0a9064fbSMasahiro Yamada 	box(main_window, 0, 0);
964*0a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
965*0a9064fbSMasahiro Yamada 	mvwprintw(main_window, 0, 3, " %s ", prompt);
966*0a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[NORMAL]);
967*0a9064fbSMasahiro Yamada 
968*0a9064fbSMasahiro Yamada 	set_menu_items(curses_menu, curses_menu_items);
969*0a9064fbSMasahiro Yamada 
970*0a9064fbSMasahiro Yamada 	/* position the menu at the middle of the screen */
971*0a9064fbSMasahiro Yamada 	scale_menu(curses_menu, &maxy, &maxx);
972*0a9064fbSMasahiro Yamada 	maxx = min(maxx, mwin_max_cols-2);
973*0a9064fbSMasahiro Yamada 	maxy = mwin_max_lines;
974*0a9064fbSMasahiro Yamada 	menu_window = derwin(main_window,
975*0a9064fbSMasahiro Yamada 			maxy,
976*0a9064fbSMasahiro Yamada 			maxx,
977*0a9064fbSMasahiro Yamada 			2,
978*0a9064fbSMasahiro Yamada 			(mwin_max_cols-maxx)/2);
979*0a9064fbSMasahiro Yamada 	keypad(menu_window, TRUE);
980*0a9064fbSMasahiro Yamada 	set_menu_win(curses_menu, menu_window);
981*0a9064fbSMasahiro Yamada 	set_menu_sub(curses_menu, menu_window);
982*0a9064fbSMasahiro Yamada 
983*0a9064fbSMasahiro Yamada 	/* must reassert this after changing items, otherwise returns to a
984*0a9064fbSMasahiro Yamada 	 * default of 16
985*0a9064fbSMasahiro Yamada 	 */
986*0a9064fbSMasahiro Yamada 	set_menu_format(curses_menu, maxy, 1);
987*0a9064fbSMasahiro Yamada 	center_item(selected_index, last_top_row);
988*0a9064fbSMasahiro Yamada 	set_menu_format(curses_menu, maxy, 1);
989*0a9064fbSMasahiro Yamada 
990*0a9064fbSMasahiro Yamada 	print_function_line();
991*0a9064fbSMasahiro Yamada 
992*0a9064fbSMasahiro Yamada 	/* Post the menu */
993*0a9064fbSMasahiro Yamada 	post_menu(curses_menu);
994*0a9064fbSMasahiro Yamada 	refresh_all_windows(main_window);
995*0a9064fbSMasahiro Yamada }
996*0a9064fbSMasahiro Yamada 
997*0a9064fbSMasahiro Yamada static void adj_match_dir(match_f *match_direction)
998*0a9064fbSMasahiro Yamada {
999*0a9064fbSMasahiro Yamada 	if (*match_direction == FIND_NEXT_MATCH_DOWN)
1000*0a9064fbSMasahiro Yamada 		*match_direction =
1001*0a9064fbSMasahiro Yamada 			MATCH_TINKER_PATTERN_DOWN;
1002*0a9064fbSMasahiro Yamada 	else if (*match_direction == FIND_NEXT_MATCH_UP)
1003*0a9064fbSMasahiro Yamada 		*match_direction =
1004*0a9064fbSMasahiro Yamada 			MATCH_TINKER_PATTERN_UP;
1005*0a9064fbSMasahiro Yamada 	/* else, do no change.. */
1006*0a9064fbSMasahiro Yamada }
1007*0a9064fbSMasahiro Yamada 
1008*0a9064fbSMasahiro Yamada struct match_state
1009*0a9064fbSMasahiro Yamada {
1010*0a9064fbSMasahiro Yamada 	int in_search;
1011*0a9064fbSMasahiro Yamada 	match_f match_direction;
1012*0a9064fbSMasahiro Yamada 	char pattern[256];
1013*0a9064fbSMasahiro Yamada };
1014*0a9064fbSMasahiro Yamada 
1015*0a9064fbSMasahiro Yamada /* Return 0 means I have handled the key. In such a case, ans should hold the
1016*0a9064fbSMasahiro Yamada  * item to center, or -1 otherwise.
1017*0a9064fbSMasahiro Yamada  * Else return -1 .
1018*0a9064fbSMasahiro Yamada  */
1019*0a9064fbSMasahiro Yamada static int do_match(int key, struct match_state *state, int *ans)
1020*0a9064fbSMasahiro Yamada {
1021*0a9064fbSMasahiro Yamada 	char c = (char) key;
1022*0a9064fbSMasahiro Yamada 	int terminate_search = 0;
1023*0a9064fbSMasahiro Yamada 	*ans = -1;
1024*0a9064fbSMasahiro Yamada 	if (key == '/' || (state->in_search && key == 27)) {
1025*0a9064fbSMasahiro Yamada 		move(0, 0);
1026*0a9064fbSMasahiro Yamada 		refresh();
1027*0a9064fbSMasahiro Yamada 		clrtoeol();
1028*0a9064fbSMasahiro Yamada 		state->in_search = 1-state->in_search;
1029*0a9064fbSMasahiro Yamada 		bzero(state->pattern, sizeof(state->pattern));
1030*0a9064fbSMasahiro Yamada 		state->match_direction = MATCH_TINKER_PATTERN_DOWN;
1031*0a9064fbSMasahiro Yamada 		return 0;
1032*0a9064fbSMasahiro Yamada 	} else if (!state->in_search)
1033*0a9064fbSMasahiro Yamada 		return 1;
1034*0a9064fbSMasahiro Yamada 
1035*0a9064fbSMasahiro Yamada 	if (isalnum(c) || isgraph(c) || c == ' ') {
1036*0a9064fbSMasahiro Yamada 		state->pattern[strlen(state->pattern)] = c;
1037*0a9064fbSMasahiro Yamada 		state->pattern[strlen(state->pattern)] = '\0';
1038*0a9064fbSMasahiro Yamada 		adj_match_dir(&state->match_direction);
1039*0a9064fbSMasahiro Yamada 		*ans = get_mext_match(state->pattern,
1040*0a9064fbSMasahiro Yamada 				state->match_direction);
1041*0a9064fbSMasahiro Yamada 	} else if (key == KEY_DOWN) {
1042*0a9064fbSMasahiro Yamada 		state->match_direction = FIND_NEXT_MATCH_DOWN;
1043*0a9064fbSMasahiro Yamada 		*ans = get_mext_match(state->pattern,
1044*0a9064fbSMasahiro Yamada 				state->match_direction);
1045*0a9064fbSMasahiro Yamada 	} else if (key == KEY_UP) {
1046*0a9064fbSMasahiro Yamada 		state->match_direction = FIND_NEXT_MATCH_UP;
1047*0a9064fbSMasahiro Yamada 		*ans = get_mext_match(state->pattern,
1048*0a9064fbSMasahiro Yamada 				state->match_direction);
1049*0a9064fbSMasahiro Yamada 	} else if (key == KEY_BACKSPACE || key == 127) {
1050*0a9064fbSMasahiro Yamada 		state->pattern[strlen(state->pattern)-1] = '\0';
1051*0a9064fbSMasahiro Yamada 		adj_match_dir(&state->match_direction);
1052*0a9064fbSMasahiro Yamada 	} else
1053*0a9064fbSMasahiro Yamada 		terminate_search = 1;
1054*0a9064fbSMasahiro Yamada 
1055*0a9064fbSMasahiro Yamada 	if (terminate_search) {
1056*0a9064fbSMasahiro Yamada 		state->in_search = 0;
1057*0a9064fbSMasahiro Yamada 		bzero(state->pattern, sizeof(state->pattern));
1058*0a9064fbSMasahiro Yamada 		move(0, 0);
1059*0a9064fbSMasahiro Yamada 		refresh();
1060*0a9064fbSMasahiro Yamada 		clrtoeol();
1061*0a9064fbSMasahiro Yamada 		return -1;
1062*0a9064fbSMasahiro Yamada 	}
1063*0a9064fbSMasahiro Yamada 	return 0;
1064*0a9064fbSMasahiro Yamada }
1065*0a9064fbSMasahiro Yamada 
1066*0a9064fbSMasahiro Yamada static void conf(struct menu *menu)
1067*0a9064fbSMasahiro Yamada {
1068*0a9064fbSMasahiro Yamada 	struct menu *submenu = 0;
1069*0a9064fbSMasahiro Yamada 	const char *prompt = menu_get_prompt(menu);
1070*0a9064fbSMasahiro Yamada 	struct symbol *sym;
1071*0a9064fbSMasahiro Yamada 	int res;
1072*0a9064fbSMasahiro Yamada 	int current_index = 0;
1073*0a9064fbSMasahiro Yamada 	int last_top_row = 0;
1074*0a9064fbSMasahiro Yamada 	struct match_state match_state = {
1075*0a9064fbSMasahiro Yamada 		.in_search = 0,
1076*0a9064fbSMasahiro Yamada 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1077*0a9064fbSMasahiro Yamada 		.pattern = "",
1078*0a9064fbSMasahiro Yamada 	};
1079*0a9064fbSMasahiro Yamada 
1080*0a9064fbSMasahiro Yamada 	while (!global_exit) {
1081*0a9064fbSMasahiro Yamada 		reset_menu();
1082*0a9064fbSMasahiro Yamada 		current_menu = menu;
1083*0a9064fbSMasahiro Yamada 		build_conf(menu);
1084*0a9064fbSMasahiro Yamada 		if (!child_count)
1085*0a9064fbSMasahiro Yamada 			break;
1086*0a9064fbSMasahiro Yamada 
1087*0a9064fbSMasahiro Yamada 		show_menu(prompt ? _(prompt) : _("Main Menu"),
1088*0a9064fbSMasahiro Yamada 				_(menu_instructions),
1089*0a9064fbSMasahiro Yamada 				current_index, &last_top_row);
1090*0a9064fbSMasahiro Yamada 		keypad((menu_win(curses_menu)), TRUE);
1091*0a9064fbSMasahiro Yamada 		while (!global_exit) {
1092*0a9064fbSMasahiro Yamada 			if (match_state.in_search) {
1093*0a9064fbSMasahiro Yamada 				mvprintw(0, 0,
1094*0a9064fbSMasahiro Yamada 					"searching: %s", match_state.pattern);
1095*0a9064fbSMasahiro Yamada 				clrtoeol();
1096*0a9064fbSMasahiro Yamada 			}
1097*0a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
1098*0a9064fbSMasahiro Yamada 			res = wgetch(menu_win(curses_menu));
1099*0a9064fbSMasahiro Yamada 			if (!res)
1100*0a9064fbSMasahiro Yamada 				break;
1101*0a9064fbSMasahiro Yamada 			if (do_match(res, &match_state, &current_index) == 0) {
1102*0a9064fbSMasahiro Yamada 				if (current_index != -1)
1103*0a9064fbSMasahiro Yamada 					center_item(current_index,
1104*0a9064fbSMasahiro Yamada 						    &last_top_row);
1105*0a9064fbSMasahiro Yamada 				continue;
1106*0a9064fbSMasahiro Yamada 			}
1107*0a9064fbSMasahiro Yamada 			if (process_special_keys(&res,
1108*0a9064fbSMasahiro Yamada 						(struct menu *) item_data()))
1109*0a9064fbSMasahiro Yamada 				break;
1110*0a9064fbSMasahiro Yamada 			switch (res) {
1111*0a9064fbSMasahiro Yamada 			case KEY_DOWN:
1112*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1113*0a9064fbSMasahiro Yamada 				break;
1114*0a9064fbSMasahiro Yamada 			case KEY_UP:
1115*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_UP_ITEM);
1116*0a9064fbSMasahiro Yamada 				break;
1117*0a9064fbSMasahiro Yamada 			case KEY_NPAGE:
1118*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1119*0a9064fbSMasahiro Yamada 				break;
1120*0a9064fbSMasahiro Yamada 			case KEY_PPAGE:
1121*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1122*0a9064fbSMasahiro Yamada 				break;
1123*0a9064fbSMasahiro Yamada 			case KEY_HOME:
1124*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1125*0a9064fbSMasahiro Yamada 				break;
1126*0a9064fbSMasahiro Yamada 			case KEY_END:
1127*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_LAST_ITEM);
1128*0a9064fbSMasahiro Yamada 				break;
1129*0a9064fbSMasahiro Yamada 			case 'h':
1130*0a9064fbSMasahiro Yamada 			case '?':
1131*0a9064fbSMasahiro Yamada 				show_help((struct menu *) item_data());
1132*0a9064fbSMasahiro Yamada 				break;
1133*0a9064fbSMasahiro Yamada 			}
1134*0a9064fbSMasahiro Yamada 			if (res == 10 || res == 27 ||
1135*0a9064fbSMasahiro Yamada 				res == 32 || res == 'n' || res == 'y' ||
1136*0a9064fbSMasahiro Yamada 				res == KEY_LEFT || res == KEY_RIGHT ||
1137*0a9064fbSMasahiro Yamada 				res == 'm')
1138*0a9064fbSMasahiro Yamada 				break;
1139*0a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
1140*0a9064fbSMasahiro Yamada 		}
1141*0a9064fbSMasahiro Yamada 
1142*0a9064fbSMasahiro Yamada 		refresh_all_windows(main_window);
1143*0a9064fbSMasahiro Yamada 		/* if ESC or left*/
1144*0a9064fbSMasahiro Yamada 		if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1145*0a9064fbSMasahiro Yamada 			break;
1146*0a9064fbSMasahiro Yamada 
1147*0a9064fbSMasahiro Yamada 		/* remember location in the menu */
1148*0a9064fbSMasahiro Yamada 		last_top_row = top_row(curses_menu);
1149*0a9064fbSMasahiro Yamada 		current_index = curses_item_index();
1150*0a9064fbSMasahiro Yamada 
1151*0a9064fbSMasahiro Yamada 		if (!item_tag())
1152*0a9064fbSMasahiro Yamada 			continue;
1153*0a9064fbSMasahiro Yamada 
1154*0a9064fbSMasahiro Yamada 		submenu = (struct menu *) item_data();
1155*0a9064fbSMasahiro Yamada 		if (!submenu || !menu_is_visible(submenu))
1156*0a9064fbSMasahiro Yamada 			continue;
1157*0a9064fbSMasahiro Yamada 		sym = submenu->sym;
1158*0a9064fbSMasahiro Yamada 
1159*0a9064fbSMasahiro Yamada 		switch (res) {
1160*0a9064fbSMasahiro Yamada 		case ' ':
1161*0a9064fbSMasahiro Yamada 			if (item_is_tag('t'))
1162*0a9064fbSMasahiro Yamada 				sym_toggle_tristate_value(sym);
1163*0a9064fbSMasahiro Yamada 			else if (item_is_tag('m'))
1164*0a9064fbSMasahiro Yamada 				conf(submenu);
1165*0a9064fbSMasahiro Yamada 			break;
1166*0a9064fbSMasahiro Yamada 		case KEY_RIGHT:
1167*0a9064fbSMasahiro Yamada 		case 10: /* ENTER WAS PRESSED */
1168*0a9064fbSMasahiro Yamada 			switch (item_tag()) {
1169*0a9064fbSMasahiro Yamada 			case 'm':
1170*0a9064fbSMasahiro Yamada 				if (single_menu_mode)
1171*0a9064fbSMasahiro Yamada 					submenu->data =
1172*0a9064fbSMasahiro Yamada 						(void *) (long) !submenu->data;
1173*0a9064fbSMasahiro Yamada 				else
1174*0a9064fbSMasahiro Yamada 					conf(submenu);
1175*0a9064fbSMasahiro Yamada 				break;
1176*0a9064fbSMasahiro Yamada 			case 't':
1177*0a9064fbSMasahiro Yamada 				if (sym_is_choice(sym) &&
1178*0a9064fbSMasahiro Yamada 				    sym_get_tristate_value(sym) == yes)
1179*0a9064fbSMasahiro Yamada 					conf_choice(submenu);
1180*0a9064fbSMasahiro Yamada 				else if (submenu->prompt &&
1181*0a9064fbSMasahiro Yamada 					 submenu->prompt->type == P_MENU)
1182*0a9064fbSMasahiro Yamada 					conf(submenu);
1183*0a9064fbSMasahiro Yamada 				else if (res == 10)
1184*0a9064fbSMasahiro Yamada 					sym_toggle_tristate_value(sym);
1185*0a9064fbSMasahiro Yamada 				break;
1186*0a9064fbSMasahiro Yamada 			case 's':
1187*0a9064fbSMasahiro Yamada 				conf_string(submenu);
1188*0a9064fbSMasahiro Yamada 				break;
1189*0a9064fbSMasahiro Yamada 			}
1190*0a9064fbSMasahiro Yamada 			break;
1191*0a9064fbSMasahiro Yamada 		case 'y':
1192*0a9064fbSMasahiro Yamada 			if (item_is_tag('t')) {
1193*0a9064fbSMasahiro Yamada 				if (sym_set_tristate_value(sym, yes))
1194*0a9064fbSMasahiro Yamada 					break;
1195*0a9064fbSMasahiro Yamada 				if (sym_set_tristate_value(sym, mod))
1196*0a9064fbSMasahiro Yamada 					btn_dialog(main_window, setmod_text, 0);
1197*0a9064fbSMasahiro Yamada 			}
1198*0a9064fbSMasahiro Yamada 			break;
1199*0a9064fbSMasahiro Yamada 		case 'n':
1200*0a9064fbSMasahiro Yamada 			if (item_is_tag('t'))
1201*0a9064fbSMasahiro Yamada 				sym_set_tristate_value(sym, no);
1202*0a9064fbSMasahiro Yamada 			break;
1203*0a9064fbSMasahiro Yamada 		case 'm':
1204*0a9064fbSMasahiro Yamada 			if (item_is_tag('t'))
1205*0a9064fbSMasahiro Yamada 				sym_set_tristate_value(sym, mod);
1206*0a9064fbSMasahiro Yamada 			break;
1207*0a9064fbSMasahiro Yamada 		}
1208*0a9064fbSMasahiro Yamada 	}
1209*0a9064fbSMasahiro Yamada }
1210*0a9064fbSMasahiro Yamada 
1211*0a9064fbSMasahiro Yamada static void conf_message_callback(const char *fmt, va_list ap)
1212*0a9064fbSMasahiro Yamada {
1213*0a9064fbSMasahiro Yamada 	char buf[1024];
1214*0a9064fbSMasahiro Yamada 
1215*0a9064fbSMasahiro Yamada 	vsnprintf(buf, sizeof(buf), fmt, ap);
1216*0a9064fbSMasahiro Yamada 	btn_dialog(main_window, buf, 1, "<OK>");
1217*0a9064fbSMasahiro Yamada }
1218*0a9064fbSMasahiro Yamada 
1219*0a9064fbSMasahiro Yamada static void show_help(struct menu *menu)
1220*0a9064fbSMasahiro Yamada {
1221*0a9064fbSMasahiro Yamada 	struct gstr help;
1222*0a9064fbSMasahiro Yamada 
1223*0a9064fbSMasahiro Yamada 	if (!menu)
1224*0a9064fbSMasahiro Yamada 		return;
1225*0a9064fbSMasahiro Yamada 
1226*0a9064fbSMasahiro Yamada 	help = str_new();
1227*0a9064fbSMasahiro Yamada 	menu_get_ext_help(menu, &help);
1228*0a9064fbSMasahiro Yamada 	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1229*0a9064fbSMasahiro Yamada 	str_free(&help);
1230*0a9064fbSMasahiro Yamada }
1231*0a9064fbSMasahiro Yamada 
1232*0a9064fbSMasahiro Yamada static void conf_choice(struct menu *menu)
1233*0a9064fbSMasahiro Yamada {
1234*0a9064fbSMasahiro Yamada 	const char *prompt = _(menu_get_prompt(menu));
1235*0a9064fbSMasahiro Yamada 	struct menu *child = 0;
1236*0a9064fbSMasahiro Yamada 	struct symbol *active;
1237*0a9064fbSMasahiro Yamada 	int selected_index = 0;
1238*0a9064fbSMasahiro Yamada 	int last_top_row = 0;
1239*0a9064fbSMasahiro Yamada 	int res, i = 0;
1240*0a9064fbSMasahiro Yamada 	struct match_state match_state = {
1241*0a9064fbSMasahiro Yamada 		.in_search = 0,
1242*0a9064fbSMasahiro Yamada 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1243*0a9064fbSMasahiro Yamada 		.pattern = "",
1244*0a9064fbSMasahiro Yamada 	};
1245*0a9064fbSMasahiro Yamada 
1246*0a9064fbSMasahiro Yamada 	active = sym_get_choice_value(menu->sym);
1247*0a9064fbSMasahiro Yamada 	/* this is mostly duplicated from the conf() function. */
1248*0a9064fbSMasahiro Yamada 	while (!global_exit) {
1249*0a9064fbSMasahiro Yamada 		reset_menu();
1250*0a9064fbSMasahiro Yamada 
1251*0a9064fbSMasahiro Yamada 		for (i = 0, child = menu->list; child; child = child->next) {
1252*0a9064fbSMasahiro Yamada 			if (!show_all_items && !menu_is_visible(child))
1253*0a9064fbSMasahiro Yamada 				continue;
1254*0a9064fbSMasahiro Yamada 
1255*0a9064fbSMasahiro Yamada 			if (child->sym == sym_get_choice_value(menu->sym))
1256*0a9064fbSMasahiro Yamada 				item_make(child, ':', "<X> %s",
1257*0a9064fbSMasahiro Yamada 						_(menu_get_prompt(child)));
1258*0a9064fbSMasahiro Yamada 			else if (child->sym)
1259*0a9064fbSMasahiro Yamada 				item_make(child, ':', "    %s",
1260*0a9064fbSMasahiro Yamada 						_(menu_get_prompt(child)));
1261*0a9064fbSMasahiro Yamada 			else
1262*0a9064fbSMasahiro Yamada 				item_make(child, ':', "*** %s ***",
1263*0a9064fbSMasahiro Yamada 						_(menu_get_prompt(child)));
1264*0a9064fbSMasahiro Yamada 
1265*0a9064fbSMasahiro Yamada 			if (child->sym == active){
1266*0a9064fbSMasahiro Yamada 				last_top_row = top_row(curses_menu);
1267*0a9064fbSMasahiro Yamada 				selected_index = i;
1268*0a9064fbSMasahiro Yamada 			}
1269*0a9064fbSMasahiro Yamada 			i++;
1270*0a9064fbSMasahiro Yamada 		}
1271*0a9064fbSMasahiro Yamada 		show_menu(prompt ? _(prompt) : _("Choice Menu"),
1272*0a9064fbSMasahiro Yamada 				_(radiolist_instructions),
1273*0a9064fbSMasahiro Yamada 				selected_index,
1274*0a9064fbSMasahiro Yamada 				&last_top_row);
1275*0a9064fbSMasahiro Yamada 		while (!global_exit) {
1276*0a9064fbSMasahiro Yamada 			if (match_state.in_search) {
1277*0a9064fbSMasahiro Yamada 				mvprintw(0, 0, "searching: %s",
1278*0a9064fbSMasahiro Yamada 					 match_state.pattern);
1279*0a9064fbSMasahiro Yamada 				clrtoeol();
1280*0a9064fbSMasahiro Yamada 			}
1281*0a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
1282*0a9064fbSMasahiro Yamada 			res = wgetch(menu_win(curses_menu));
1283*0a9064fbSMasahiro Yamada 			if (!res)
1284*0a9064fbSMasahiro Yamada 				break;
1285*0a9064fbSMasahiro Yamada 			if (do_match(res, &match_state, &selected_index) == 0) {
1286*0a9064fbSMasahiro Yamada 				if (selected_index != -1)
1287*0a9064fbSMasahiro Yamada 					center_item(selected_index,
1288*0a9064fbSMasahiro Yamada 						    &last_top_row);
1289*0a9064fbSMasahiro Yamada 				continue;
1290*0a9064fbSMasahiro Yamada 			}
1291*0a9064fbSMasahiro Yamada 			if (process_special_keys(
1292*0a9064fbSMasahiro Yamada 						&res,
1293*0a9064fbSMasahiro Yamada 						(struct menu *) item_data()))
1294*0a9064fbSMasahiro Yamada 				break;
1295*0a9064fbSMasahiro Yamada 			switch (res) {
1296*0a9064fbSMasahiro Yamada 			case KEY_DOWN:
1297*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1298*0a9064fbSMasahiro Yamada 				break;
1299*0a9064fbSMasahiro Yamada 			case KEY_UP:
1300*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_UP_ITEM);
1301*0a9064fbSMasahiro Yamada 				break;
1302*0a9064fbSMasahiro Yamada 			case KEY_NPAGE:
1303*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1304*0a9064fbSMasahiro Yamada 				break;
1305*0a9064fbSMasahiro Yamada 			case KEY_PPAGE:
1306*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1307*0a9064fbSMasahiro Yamada 				break;
1308*0a9064fbSMasahiro Yamada 			case KEY_HOME:
1309*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1310*0a9064fbSMasahiro Yamada 				break;
1311*0a9064fbSMasahiro Yamada 			case KEY_END:
1312*0a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_LAST_ITEM);
1313*0a9064fbSMasahiro Yamada 				break;
1314*0a9064fbSMasahiro Yamada 			case 'h':
1315*0a9064fbSMasahiro Yamada 			case '?':
1316*0a9064fbSMasahiro Yamada 				show_help((struct menu *) item_data());
1317*0a9064fbSMasahiro Yamada 				break;
1318*0a9064fbSMasahiro Yamada 			}
1319*0a9064fbSMasahiro Yamada 			if (res == 10 || res == 27 || res == ' ' ||
1320*0a9064fbSMasahiro Yamada 					res == KEY_LEFT){
1321*0a9064fbSMasahiro Yamada 				break;
1322*0a9064fbSMasahiro Yamada 			}
1323*0a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
1324*0a9064fbSMasahiro Yamada 		}
1325*0a9064fbSMasahiro Yamada 		/* if ESC or left */
1326*0a9064fbSMasahiro Yamada 		if (res == 27 || res == KEY_LEFT)
1327*0a9064fbSMasahiro Yamada 			break;
1328*0a9064fbSMasahiro Yamada 
1329*0a9064fbSMasahiro Yamada 		child = item_data();
1330*0a9064fbSMasahiro Yamada 		if (!child || !menu_is_visible(child) || !child->sym)
1331*0a9064fbSMasahiro Yamada 			continue;
1332*0a9064fbSMasahiro Yamada 		switch (res) {
1333*0a9064fbSMasahiro Yamada 		case ' ':
1334*0a9064fbSMasahiro Yamada 		case  10:
1335*0a9064fbSMasahiro Yamada 		case KEY_RIGHT:
1336*0a9064fbSMasahiro Yamada 			sym_set_tristate_value(child->sym, yes);
1337*0a9064fbSMasahiro Yamada 			return;
1338*0a9064fbSMasahiro Yamada 		case 'h':
1339*0a9064fbSMasahiro Yamada 		case '?':
1340*0a9064fbSMasahiro Yamada 			show_help(child);
1341*0a9064fbSMasahiro Yamada 			active = child->sym;
1342*0a9064fbSMasahiro Yamada 			break;
1343*0a9064fbSMasahiro Yamada 		case KEY_EXIT:
1344*0a9064fbSMasahiro Yamada 			return;
1345*0a9064fbSMasahiro Yamada 		}
1346*0a9064fbSMasahiro Yamada 	}
1347*0a9064fbSMasahiro Yamada }
1348*0a9064fbSMasahiro Yamada 
1349*0a9064fbSMasahiro Yamada static void conf_string(struct menu *menu)
1350*0a9064fbSMasahiro Yamada {
1351*0a9064fbSMasahiro Yamada 	const char *prompt = menu_get_prompt(menu);
1352*0a9064fbSMasahiro Yamada 
1353*0a9064fbSMasahiro Yamada 	while (1) {
1354*0a9064fbSMasahiro Yamada 		int res;
1355*0a9064fbSMasahiro Yamada 		const char *heading;
1356*0a9064fbSMasahiro Yamada 
1357*0a9064fbSMasahiro Yamada 		switch (sym_get_type(menu->sym)) {
1358*0a9064fbSMasahiro Yamada 		case S_INT:
1359*0a9064fbSMasahiro Yamada 			heading = _(inputbox_instructions_int);
1360*0a9064fbSMasahiro Yamada 			break;
1361*0a9064fbSMasahiro Yamada 		case S_HEX:
1362*0a9064fbSMasahiro Yamada 			heading = _(inputbox_instructions_hex);
1363*0a9064fbSMasahiro Yamada 			break;
1364*0a9064fbSMasahiro Yamada 		case S_STRING:
1365*0a9064fbSMasahiro Yamada 			heading = _(inputbox_instructions_string);
1366*0a9064fbSMasahiro Yamada 			break;
1367*0a9064fbSMasahiro Yamada 		default:
1368*0a9064fbSMasahiro Yamada 			heading = _("Internal nconf error!");
1369*0a9064fbSMasahiro Yamada 		}
1370*0a9064fbSMasahiro Yamada 		res = dialog_inputbox(main_window,
1371*0a9064fbSMasahiro Yamada 				prompt ? _(prompt) : _("Main Menu"),
1372*0a9064fbSMasahiro Yamada 				heading,
1373*0a9064fbSMasahiro Yamada 				sym_get_string_value(menu->sym),
1374*0a9064fbSMasahiro Yamada 				&dialog_input_result,
1375*0a9064fbSMasahiro Yamada 				&dialog_input_result_len);
1376*0a9064fbSMasahiro Yamada 		switch (res) {
1377*0a9064fbSMasahiro Yamada 		case 0:
1378*0a9064fbSMasahiro Yamada 			if (sym_set_string_value(menu->sym,
1379*0a9064fbSMasahiro Yamada 						dialog_input_result))
1380*0a9064fbSMasahiro Yamada 				return;
1381*0a9064fbSMasahiro Yamada 			btn_dialog(main_window,
1382*0a9064fbSMasahiro Yamada 				_("You have made an invalid entry."), 0);
1383*0a9064fbSMasahiro Yamada 			break;
1384*0a9064fbSMasahiro Yamada 		case 1:
1385*0a9064fbSMasahiro Yamada 			show_help(menu);
1386*0a9064fbSMasahiro Yamada 			break;
1387*0a9064fbSMasahiro Yamada 		case KEY_EXIT:
1388*0a9064fbSMasahiro Yamada 			return;
1389*0a9064fbSMasahiro Yamada 		}
1390*0a9064fbSMasahiro Yamada 	}
1391*0a9064fbSMasahiro Yamada }
1392*0a9064fbSMasahiro Yamada 
1393*0a9064fbSMasahiro Yamada static void conf_load(void)
1394*0a9064fbSMasahiro Yamada {
1395*0a9064fbSMasahiro Yamada 	while (1) {
1396*0a9064fbSMasahiro Yamada 		int res;
1397*0a9064fbSMasahiro Yamada 		res = dialog_inputbox(main_window,
1398*0a9064fbSMasahiro Yamada 				NULL, load_config_text,
1399*0a9064fbSMasahiro Yamada 				filename,
1400*0a9064fbSMasahiro Yamada 				&dialog_input_result,
1401*0a9064fbSMasahiro Yamada 				&dialog_input_result_len);
1402*0a9064fbSMasahiro Yamada 		switch (res) {
1403*0a9064fbSMasahiro Yamada 		case 0:
1404*0a9064fbSMasahiro Yamada 			if (!dialog_input_result[0])
1405*0a9064fbSMasahiro Yamada 				return;
1406*0a9064fbSMasahiro Yamada 			if (!conf_read(dialog_input_result)) {
1407*0a9064fbSMasahiro Yamada 				set_config_filename(dialog_input_result);
1408*0a9064fbSMasahiro Yamada 				sym_set_change_count(1);
1409*0a9064fbSMasahiro Yamada 				return;
1410*0a9064fbSMasahiro Yamada 			}
1411*0a9064fbSMasahiro Yamada 			btn_dialog(main_window, _("File does not exist!"), 0);
1412*0a9064fbSMasahiro Yamada 			break;
1413*0a9064fbSMasahiro Yamada 		case 1:
1414*0a9064fbSMasahiro Yamada 			show_scroll_win(main_window,
1415*0a9064fbSMasahiro Yamada 					_("Load Alternate Configuration"),
1416*0a9064fbSMasahiro Yamada 					load_config_help);
1417*0a9064fbSMasahiro Yamada 			break;
1418*0a9064fbSMasahiro Yamada 		case KEY_EXIT:
1419*0a9064fbSMasahiro Yamada 			return;
1420*0a9064fbSMasahiro Yamada 		}
1421*0a9064fbSMasahiro Yamada 	}
1422*0a9064fbSMasahiro Yamada }
1423*0a9064fbSMasahiro Yamada 
1424*0a9064fbSMasahiro Yamada static void conf_save(void)
1425*0a9064fbSMasahiro Yamada {
1426*0a9064fbSMasahiro Yamada 	while (1) {
1427*0a9064fbSMasahiro Yamada 		int res;
1428*0a9064fbSMasahiro Yamada 		res = dialog_inputbox(main_window,
1429*0a9064fbSMasahiro Yamada 				NULL, save_config_text,
1430*0a9064fbSMasahiro Yamada 				filename,
1431*0a9064fbSMasahiro Yamada 				&dialog_input_result,
1432*0a9064fbSMasahiro Yamada 				&dialog_input_result_len);
1433*0a9064fbSMasahiro Yamada 		switch (res) {
1434*0a9064fbSMasahiro Yamada 		case 0:
1435*0a9064fbSMasahiro Yamada 			if (!dialog_input_result[0])
1436*0a9064fbSMasahiro Yamada 				return;
1437*0a9064fbSMasahiro Yamada 			res = conf_write(dialog_input_result);
1438*0a9064fbSMasahiro Yamada 			if (!res) {
1439*0a9064fbSMasahiro Yamada 				set_config_filename(dialog_input_result);
1440*0a9064fbSMasahiro Yamada 				return;
1441*0a9064fbSMasahiro Yamada 			}
1442*0a9064fbSMasahiro Yamada 			btn_dialog(main_window, _("Can't create file! "
1443*0a9064fbSMasahiro Yamada 				"Probably a nonexistent directory."),
1444*0a9064fbSMasahiro Yamada 				1, "<OK>");
1445*0a9064fbSMasahiro Yamada 			break;
1446*0a9064fbSMasahiro Yamada 		case 1:
1447*0a9064fbSMasahiro Yamada 			show_scroll_win(main_window,
1448*0a9064fbSMasahiro Yamada 				_("Save Alternate Configuration"),
1449*0a9064fbSMasahiro Yamada 				save_config_help);
1450*0a9064fbSMasahiro Yamada 			break;
1451*0a9064fbSMasahiro Yamada 		case KEY_EXIT:
1452*0a9064fbSMasahiro Yamada 			return;
1453*0a9064fbSMasahiro Yamada 		}
1454*0a9064fbSMasahiro Yamada 	}
1455*0a9064fbSMasahiro Yamada }
1456*0a9064fbSMasahiro Yamada 
1457*0a9064fbSMasahiro Yamada void setup_windows(void)
1458*0a9064fbSMasahiro Yamada {
1459*0a9064fbSMasahiro Yamada 	int lines, columns;
1460*0a9064fbSMasahiro Yamada 
1461*0a9064fbSMasahiro Yamada 	getmaxyx(stdscr, lines, columns);
1462*0a9064fbSMasahiro Yamada 
1463*0a9064fbSMasahiro Yamada 	if (main_window != NULL)
1464*0a9064fbSMasahiro Yamada 		delwin(main_window);
1465*0a9064fbSMasahiro Yamada 
1466*0a9064fbSMasahiro Yamada 	/* set up the menu and menu window */
1467*0a9064fbSMasahiro Yamada 	main_window = newwin(lines-2, columns-2, 2, 1);
1468*0a9064fbSMasahiro Yamada 	keypad(main_window, TRUE);
1469*0a9064fbSMasahiro Yamada 	mwin_max_lines = lines-7;
1470*0a9064fbSMasahiro Yamada 	mwin_max_cols = columns-6;
1471*0a9064fbSMasahiro Yamada 
1472*0a9064fbSMasahiro Yamada 	/* panels order is from bottom to top */
1473*0a9064fbSMasahiro Yamada 	new_panel(main_window);
1474*0a9064fbSMasahiro Yamada }
1475*0a9064fbSMasahiro Yamada 
1476*0a9064fbSMasahiro Yamada int main(int ac, char **av)
1477*0a9064fbSMasahiro Yamada {
1478*0a9064fbSMasahiro Yamada 	int lines, columns;
1479*0a9064fbSMasahiro Yamada 	char *mode;
1480*0a9064fbSMasahiro Yamada 
1481*0a9064fbSMasahiro Yamada 	setlocale(LC_ALL, "");
1482*0a9064fbSMasahiro Yamada 	bindtextdomain(PACKAGE, LOCALEDIR);
1483*0a9064fbSMasahiro Yamada 	textdomain(PACKAGE);
1484*0a9064fbSMasahiro Yamada 
1485*0a9064fbSMasahiro Yamada 	conf_parse(av[1]);
1486*0a9064fbSMasahiro Yamada 	conf_read(NULL);
1487*0a9064fbSMasahiro Yamada 
1488*0a9064fbSMasahiro Yamada 	mode = getenv("NCONFIG_MODE");
1489*0a9064fbSMasahiro Yamada 	if (mode) {
1490*0a9064fbSMasahiro Yamada 		if (!strcasecmp(mode, "single_menu"))
1491*0a9064fbSMasahiro Yamada 			single_menu_mode = 1;
1492*0a9064fbSMasahiro Yamada 	}
1493*0a9064fbSMasahiro Yamada 
1494*0a9064fbSMasahiro Yamada 	/* Initialize curses */
1495*0a9064fbSMasahiro Yamada 	initscr();
1496*0a9064fbSMasahiro Yamada 	/* set color theme */
1497*0a9064fbSMasahiro Yamada 	set_colors();
1498*0a9064fbSMasahiro Yamada 
1499*0a9064fbSMasahiro Yamada 	cbreak();
1500*0a9064fbSMasahiro Yamada 	noecho();
1501*0a9064fbSMasahiro Yamada 	keypad(stdscr, TRUE);
1502*0a9064fbSMasahiro Yamada 	curs_set(0);
1503*0a9064fbSMasahiro Yamada 
1504*0a9064fbSMasahiro Yamada 	getmaxyx(stdscr, lines, columns);
1505*0a9064fbSMasahiro Yamada 	if (columns < 75 || lines < 20) {
1506*0a9064fbSMasahiro Yamada 		endwin();
1507*0a9064fbSMasahiro Yamada 		printf("Your terminal should have at "
1508*0a9064fbSMasahiro Yamada 			"least 20 lines and 75 columns\n");
1509*0a9064fbSMasahiro Yamada 		return 1;
1510*0a9064fbSMasahiro Yamada 	}
1511*0a9064fbSMasahiro Yamada 
1512*0a9064fbSMasahiro Yamada 	notimeout(stdscr, FALSE);
1513*0a9064fbSMasahiro Yamada #if NCURSES_REENTRANT
1514*0a9064fbSMasahiro Yamada 	set_escdelay(1);
1515*0a9064fbSMasahiro Yamada #else
1516*0a9064fbSMasahiro Yamada 	ESCDELAY = 1;
1517*0a9064fbSMasahiro Yamada #endif
1518*0a9064fbSMasahiro Yamada 
1519*0a9064fbSMasahiro Yamada 	/* set btns menu */
1520*0a9064fbSMasahiro Yamada 	curses_menu = new_menu(curses_menu_items);
1521*0a9064fbSMasahiro Yamada 	menu_opts_off(curses_menu, O_SHOWDESC);
1522*0a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_SHOWMATCH);
1523*0a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_ONEVALUE);
1524*0a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_NONCYCLIC);
1525*0a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_IGNORECASE);
1526*0a9064fbSMasahiro Yamada 	set_menu_mark(curses_menu, " ");
1527*0a9064fbSMasahiro Yamada 	set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1528*0a9064fbSMasahiro Yamada 	set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1529*0a9064fbSMasahiro Yamada 	set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1530*0a9064fbSMasahiro Yamada 
1531*0a9064fbSMasahiro Yamada 	set_config_filename(conf_get_configname());
1532*0a9064fbSMasahiro Yamada 	setup_windows();
1533*0a9064fbSMasahiro Yamada 
1534*0a9064fbSMasahiro Yamada 	/* check for KEY_FUNC(1) */
1535*0a9064fbSMasahiro Yamada 	if (has_key(KEY_F(1)) == FALSE) {
1536*0a9064fbSMasahiro Yamada 		show_scroll_win(main_window,
1537*0a9064fbSMasahiro Yamada 				_("Instructions"),
1538*0a9064fbSMasahiro Yamada 				_(menu_no_f_instructions));
1539*0a9064fbSMasahiro Yamada 	}
1540*0a9064fbSMasahiro Yamada 
1541*0a9064fbSMasahiro Yamada 	conf_set_message_callback(conf_message_callback);
1542*0a9064fbSMasahiro Yamada 	/* do the work */
1543*0a9064fbSMasahiro Yamada 	while (!global_exit) {
1544*0a9064fbSMasahiro Yamada 		conf(&rootmenu);
1545*0a9064fbSMasahiro Yamada 		if (!global_exit && do_exit() == 0)
1546*0a9064fbSMasahiro Yamada 			break;
1547*0a9064fbSMasahiro Yamada 	}
1548*0a9064fbSMasahiro Yamada 	/* ok, we are done */
1549*0a9064fbSMasahiro Yamada 	unpost_menu(curses_menu);
1550*0a9064fbSMasahiro Yamada 	free_menu(curses_menu);
1551*0a9064fbSMasahiro Yamada 	delwin(main_window);
1552*0a9064fbSMasahiro Yamada 	clear();
1553*0a9064fbSMasahiro Yamada 	refresh();
1554*0a9064fbSMasahiro Yamada 	endwin();
1555*0a9064fbSMasahiro Yamada 	return 0;
1556*0a9064fbSMasahiro Yamada }
1557