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