xref: /linux/scripts/kconfig/nconf.c (revision 2c68115cb3d2863004f1dd5c01e3adbd54facd4c)
1692d97c3Snir.tzachar@gmail.com /*
2692d97c3Snir.tzachar@gmail.com  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3692d97c3Snir.tzachar@gmail.com  * Released under the terms of the GNU GPL v2.0.
4692d97c3Snir.tzachar@gmail.com  *
5692d97c3Snir.tzachar@gmail.com  * Derived from menuconfig.
6692d97c3Snir.tzachar@gmail.com  *
7692d97c3Snir.tzachar@gmail.com  */
8a72f3e2bSNir Tzachar #define _GNU_SOURCE
9a72f3e2bSNir Tzachar #include <string.h>
109a926d43SYann E. MORIN #include <stdlib.h>
115a6f8d2bSArnaud Lacombe 
12692d97c3Snir.tzachar@gmail.com #include "lkc.h"
13692d97c3Snir.tzachar@gmail.com #include "nconf.h"
14a72f3e2bSNir Tzachar #include <ctype.h>
15692d97c3Snir.tzachar@gmail.com 
160b616500SRoland Eggner static const char nconf_global_help[] = N_(
170b616500SRoland Eggner "Help windows\n"
180b616500SRoland Eggner "------------\n"
190b616500SRoland Eggner "o  Global help:  Unless in a data entry window, pressing <F1> will give \n"
200b616500SRoland Eggner "   you the global help window, which you are just reading.\n"
21692d97c3Snir.tzachar@gmail.com "\n"
220b616500SRoland Eggner "o  A short version of the global help is available by pressing <F3>.\n"
230b616500SRoland Eggner "\n"
240b616500SRoland Eggner "o  Local help:  To get help related to the current menu entry, use any\n"
250b616500SRoland Eggner "   of <?> <h>, or if in a data entry window then press <F1>.\n"
260b616500SRoland Eggner "\n"
270b616500SRoland Eggner "\n"
280b616500SRoland Eggner "Menu entries\n"
290b616500SRoland Eggner "------------\n"
300b616500SRoland Eggner "This interface lets you select features and parameters for the kernel\n"
310b616500SRoland Eggner "build.  Kernel features can either be built-in, modularized, or removed.\n"
320b616500SRoland Eggner "Parameters must be entered as text or decimal or hexadecimal numbers.\n"
330b616500SRoland Eggner "\n"
340b616500SRoland Eggner "Menu entries beginning with following braces represent features that\n"
35692d97c3Snir.tzachar@gmail.com "  [ ]  can be built in or removed\n"
36692d97c3Snir.tzachar@gmail.com "  < >  can be built in, modularized or removed\n"
370b616500SRoland Eggner "  { }  can be built in or modularized, are selected by another feature\n"
380b616500SRoland Eggner "  - -  are selected by another feature\n"
390b616500SRoland Eggner "  XXX  cannot be selected.  Symbol Info <F2> tells you why.\n"
400b616500SRoland Eggner "*, M or whitespace inside braces means to build in, build as a module\n"
410b616500SRoland Eggner "or to exclude the feature respectively.\n"
42692d97c3Snir.tzachar@gmail.com "\n"
430b616500SRoland Eggner "To change any of these features, highlight it with the movement keys\n"
440b616500SRoland Eggner "listed below and press <y> to build it in, <m> to make it a module or\n"
450b616500SRoland Eggner "<n> to remove it.  You may press the <Space> key to cycle through the\n"
460b616500SRoland Eggner "available options.\n"
47692d97c3Snir.tzachar@gmail.com "\n"
480b616500SRoland Eggner "A trailing \"--->\" designates a submenu.\n"
49692d97c3Snir.tzachar@gmail.com "\n"
500b616500SRoland Eggner "\n"
510b616500SRoland Eggner "Menu navigation keys\n"
520b616500SRoland Eggner "----------------------------------------------------------------------\n"
530b616500SRoland Eggner "Linewise up                 <Up>\n"
540b616500SRoland Eggner "Linewise down               <Down>\n"
550b616500SRoland Eggner "Pagewise up                 <Page Up>\n"
560b616500SRoland Eggner "Pagewise down               <Page Down>\n"
570b616500SRoland Eggner "First entry                 <Home>\n"
580b616500SRoland Eggner "Last entry                  <End>\n"
590b616500SRoland Eggner "Enter a submenu             <Right>  <Enter>\n"
600b616500SRoland Eggner "Go back to parent menu      <Left>   <Esc>  <F5>\n"
610b616500SRoland Eggner "Close a help window         <Enter>  <Esc>  <F5>\n"
620b616500SRoland Eggner "Close entry window, apply   <Enter>\n"
630b616500SRoland Eggner "Close entry window, forget  <Esc>  <F5>\n"
640b616500SRoland Eggner "Start incremental, case-insensitive search for STRING in menu entries,\n"
650b616500SRoland Eggner "    no regex support, STRING is displayed in upper left corner\n"
660b616500SRoland Eggner "                            </>STRING\n"
670b616500SRoland Eggner "    Remove last character   <Backspace>\n"
680b616500SRoland Eggner "    Jump to next hit        <Down>\n"
690b616500SRoland Eggner "    Jump to previous hit    <Up>\n"
700b616500SRoland Eggner "Exit menu search mode       </>  <Esc>\n"
710b616500SRoland Eggner "Search for configuration variables with or without leading CONFIG_\n"
720b616500SRoland Eggner "                            <F8>RegExpr<Enter>\n"
730b616500SRoland Eggner "Verbose search help         <F8><F1>\n"
740b616500SRoland Eggner "----------------------------------------------------------------------\n"
750b616500SRoland Eggner "\n"
760b616500SRoland Eggner "Unless in a data entry window, key <1> may be used instead of <F1>,\n"
770b616500SRoland Eggner "<2> instead of <F2>, etc.\n"
780b616500SRoland Eggner "\n"
790b616500SRoland Eggner "\n"
800b616500SRoland Eggner "Radiolist (Choice list)\n"
810b616500SRoland Eggner "-----------------------\n"
820b616500SRoland Eggner "Use the movement keys listed above to select the option you wish to set\n"
830b616500SRoland Eggner "and press <Space>.\n"
840b616500SRoland Eggner "\n"
850b616500SRoland Eggner "\n"
860b616500SRoland Eggner "Data entry\n"
87692d97c3Snir.tzachar@gmail.com "----------\n"
880b616500SRoland Eggner "Enter the requested information and press <Enter>.  Hexadecimal values\n"
890b616500SRoland Eggner "may be entered without the \"0x\" prefix.\n"
90692d97c3Snir.tzachar@gmail.com "\n"
91692d97c3Snir.tzachar@gmail.com "\n"
92692d97c3Snir.tzachar@gmail.com "Text Box (Help Window)\n"
930b616500SRoland Eggner "----------------------\n"
940b616500SRoland Eggner "Use movement keys as listed in table above.\n"
95692d97c3Snir.tzachar@gmail.com "\n"
960b616500SRoland Eggner "Press any of <Enter> <Esc> <q> <F5> <F9> to exit.\n"
97692d97c3Snir.tzachar@gmail.com "\n"
98692d97c3Snir.tzachar@gmail.com "\n"
990b616500SRoland Eggner "Alternate configuration files\n"
100692d97c3Snir.tzachar@gmail.com "-----------------------------\n"
1010b616500SRoland Eggner "nconfig supports switching between different configurations.\n"
1020b616500SRoland Eggner "Press <F6> to save your current configuration.  Press <F7> and enter\n"
1030b616500SRoland Eggner "a file name to load a previously saved configuration.\n"
104692d97c3Snir.tzachar@gmail.com "\n"
105692d97c3Snir.tzachar@gmail.com "\n"
1060b616500SRoland Eggner "Terminal configuration\n"
1070b616500SRoland Eggner "----------------------\n"
1080b616500SRoland Eggner "If you use nconfig in a xterm window, make sure your TERM environment\n"
1090b616500SRoland Eggner "variable specifies a terminal configuration which supports at least\n"
1100b616500SRoland Eggner "16 colors.  Otherwise nconfig will look rather bad.\n"
111692d97c3Snir.tzachar@gmail.com "\n"
1120b616500SRoland Eggner "If the \"stty size\" command reports the current terminalsize correctly,\n"
1130b616500SRoland Eggner "nconfig will adapt to sizes larger than the traditional 80x25 \"standard\"\n"
1140b616500SRoland Eggner "and display longer menus properly.\n"
115692d97c3Snir.tzachar@gmail.com "\n"
116692d97c3Snir.tzachar@gmail.com "\n"
1170b616500SRoland Eggner "Single menu mode\n"
1180b616500SRoland Eggner "----------------\n"
1190b616500SRoland Eggner "If you prefer to have all of the menu entries listed in a single menu,\n"
1200b616500SRoland Eggner "rather than the default multimenu hierarchy, run nconfig with\n"
1210b616500SRoland Eggner "NCONFIG_MODE environment variable set to single_menu.  Example:\n"
122692d97c3Snir.tzachar@gmail.com "\n"
123692d97c3Snir.tzachar@gmail.com "make NCONFIG_MODE=single_menu nconfig\n"
124692d97c3Snir.tzachar@gmail.com "\n"
1250b616500SRoland Eggner "<Enter> will then unfold the appropriate category, or fold it if it\n"
1260b616500SRoland Eggner "is already unfolded.  Folded menu entries will be designated by a\n"
1270b616500SRoland Eggner "leading \"++>\" and unfolded entries by a leading \"-->\".\n"
128692d97c3Snir.tzachar@gmail.com "\n"
1290b616500SRoland Eggner "Note that this mode can eventually be a little more CPU expensive than\n"
1300b616500SRoland Eggner "the default mode, especially with a larger number of unfolded submenus.\n"
131692d97c3Snir.tzachar@gmail.com "\n"),
132692d97c3Snir.tzachar@gmail.com menu_no_f_instructions[] = N_(
133692d97c3Snir.tzachar@gmail.com "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1340b616500SRoland Eggner "Submenus are designated by a trailing \"--->\".\n"
1350b616500SRoland Eggner "\n"
1360b616500SRoland Eggner "Use the following keys to navigate the menus:\n"
1370b616500SRoland Eggner "Move up or down with <Up> and <Down>.\n"
1380b616500SRoland Eggner "Enter a submenu with <Enter> or <Right>.\n"
1390b616500SRoland Eggner "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1400b616500SRoland Eggner "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1410b616500SRoland Eggner "Pressing <Space> cycles through the available options.\n"
1420b616500SRoland Eggner "To search for menu entries press </>.\n"
1430b616500SRoland Eggner "<Esc> always leaves the current window.\n"
1440b616500SRoland Eggner "\n"
1450b616500SRoland Eggner "You do not have function keys support.\n"
1460b616500SRoland Eggner "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
1470b616500SRoland Eggner "For verbose global help use key <1>.\n"
1480b616500SRoland Eggner "For help related to the current menu entry press <?> or <h>.\n"),
149692d97c3Snir.tzachar@gmail.com menu_instructions[] = N_(
150692d97c3Snir.tzachar@gmail.com "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1510b616500SRoland Eggner "Submenus are designated by a trailing \"--->\".\n"
1520b616500SRoland Eggner "\n"
1530b616500SRoland Eggner "Use the following keys to navigate the menus:\n"
1540b616500SRoland Eggner "Move up or down with <Up> or <Down>.\n"
1550b616500SRoland Eggner "Enter a submenu with <Enter> or <Right>.\n"
1560b616500SRoland Eggner "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1570b616500SRoland Eggner "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1580b616500SRoland Eggner "Pressing <Space> cycles through the available options.\n"
1590b616500SRoland Eggner "To search for menu entries press </>.\n"
1600b616500SRoland Eggner "<Esc> always leaves the current window.\n"
1610b616500SRoland Eggner "\n"
1620b616500SRoland Eggner "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
1630b616500SRoland Eggner "For verbose global help press <F1>.\n"
1640b616500SRoland Eggner "For help related to the current menu entry press <?> or <h>.\n"),
165692d97c3Snir.tzachar@gmail.com radiolist_instructions[] = N_(
1660b616500SRoland Eggner "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
1670b616500SRoland Eggner "with <Space>.\n"
1680b616500SRoland Eggner "For help related to the current entry press <?> or <h>.\n"
1690b616500SRoland Eggner "For global help press <F1>.\n"),
170692d97c3Snir.tzachar@gmail.com inputbox_instructions_int[] = N_(
171692d97c3Snir.tzachar@gmail.com "Please enter a decimal value.\n"
172692d97c3Snir.tzachar@gmail.com "Fractions will not be accepted.\n"
1730b616500SRoland Eggner "Press <Enter> to apply, <Esc> to cancel."),
174692d97c3Snir.tzachar@gmail.com inputbox_instructions_hex[] = N_(
175692d97c3Snir.tzachar@gmail.com "Please enter a hexadecimal value.\n"
1760b616500SRoland Eggner "Press <Enter> to apply, <Esc> to cancel."),
177692d97c3Snir.tzachar@gmail.com inputbox_instructions_string[] = N_(
178692d97c3Snir.tzachar@gmail.com "Please enter a string value.\n"
1790b616500SRoland Eggner "Press <Enter> to apply, <Esc> to cancel."),
180692d97c3Snir.tzachar@gmail.com setmod_text[] = N_(
1810b616500SRoland Eggner "This feature depends on another feature which has been configured as a\n"
1820b616500SRoland Eggner "module.  As a result, the current feature will be built as a module too."),
183692d97c3Snir.tzachar@gmail.com load_config_text[] = N_(
184692d97c3Snir.tzachar@gmail.com "Enter the name of the configuration file you wish to load.\n"
1850b616500SRoland Eggner "Accept the name shown to restore the configuration you last\n"
1860b616500SRoland Eggner "retrieved.  Leave empty to abort."),
187692d97c3Snir.tzachar@gmail.com load_config_help[] = N_(
188652cf982SArnaud Lacombe "For various reasons, one may wish to keep several different\n"
189692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n"
190692d97c3Snir.tzachar@gmail.com "\n"
191692d97c3Snir.tzachar@gmail.com "If you have saved a previous configuration in a file other than the\n"
1920b616500SRoland Eggner "default one, entering its name here will allow you to load and modify\n"
1930b616500SRoland Eggner "that configuration.\n"
194692d97c3Snir.tzachar@gmail.com "\n"
1950b616500SRoland Eggner "Leave empty to abort.\n"),
196692d97c3Snir.tzachar@gmail.com save_config_text[] = N_(
197692d97c3Snir.tzachar@gmail.com "Enter a filename to which this configuration should be saved\n"
1980b616500SRoland Eggner "as an alternate.  Leave empty to abort."),
199692d97c3Snir.tzachar@gmail.com save_config_help[] = N_(
2000b616500SRoland Eggner "For various reasons, one may wish to keep several different\n"
2010b616500SRoland Eggner "configurations available on a single machine.\n"
202692d97c3Snir.tzachar@gmail.com "\n"
203692d97c3Snir.tzachar@gmail.com "Entering a file name here will allow you to later retrieve, modify\n"
204692d97c3Snir.tzachar@gmail.com "and use the current configuration as an alternate to whatever\n"
205692d97c3Snir.tzachar@gmail.com "configuration options you have selected at that time.\n"
206692d97c3Snir.tzachar@gmail.com "\n"
2070b616500SRoland Eggner "Leave empty to abort.\n"),
208692d97c3Snir.tzachar@gmail.com search_help[] = N_(
2090b616500SRoland Eggner "Search for symbols (configuration variable names CONFIG_*) and display\n"
2100b616500SRoland Eggner "their relations.  Regular expressions are supported.\n"
2110b616500SRoland Eggner "Example:  Search for \"^FOO\".\n"
212692d97c3Snir.tzachar@gmail.com "Result:\n"
213692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
214692d97c3Snir.tzachar@gmail.com "Symbol: FOO [ = m]\n"
215692d97c3Snir.tzachar@gmail.com "Prompt: Foo bus is used to drive the bar HW\n"
216692d97c3Snir.tzachar@gmail.com "Defined at drivers/pci/Kconfig:47\n"
217692d97c3Snir.tzachar@gmail.com "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
218692d97c3Snir.tzachar@gmail.com "Location:\n"
219bb8187d3SPaul Gortmaker "  -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
220692d97c3Snir.tzachar@gmail.com "    -> PCI support (PCI [ = y])\n"
221692d97c3Snir.tzachar@gmail.com "      -> PCI access mode (<choice> [ = y])\n"
222692d97c3Snir.tzachar@gmail.com "Selects: LIBCRC32\n"
223692d97c3Snir.tzachar@gmail.com "Selected by: BAR\n"
224692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
2250b616500SRoland Eggner "o  The line 'Prompt:' shows the text displayed for this symbol in\n"
2260b616500SRoland Eggner "   the menu hierarchy.\n"
2270b616500SRoland Eggner "o  The 'Defined at' line tells at what file / line number the symbol is\n"
2280b616500SRoland Eggner "   defined.\n"
2290b616500SRoland Eggner "o  The 'Depends on:' line lists symbols that need to be defined for\n"
2300b616500SRoland Eggner "   this symbol to be visible and selectable in the menu.\n"
2310b616500SRoland Eggner "o  The 'Location:' lines tell, where in the menu structure this symbol\n"
2320b616500SRoland Eggner "   is located.  A location followed by a [ = y] indicates that this is\n"
2330b616500SRoland Eggner "   a selectable menu item, and the current value is displayed inside\n"
2340b616500SRoland Eggner "   brackets.\n"
2350b616500SRoland Eggner "o  The 'Selects:' line tells, what symbol will be automatically selected\n"
2360b616500SRoland Eggner "   if this symbol is selected (y or m).\n"
2370b616500SRoland Eggner "o  The 'Selected by' line tells what symbol has selected this symbol.\n"
238692d97c3Snir.tzachar@gmail.com "\n"
239692d97c3Snir.tzachar@gmail.com "Only relevant lines are shown.\n"
240692d97c3Snir.tzachar@gmail.com "\n\n"
241692d97c3Snir.tzachar@gmail.com "Search examples:\n"
2420b616500SRoland Eggner "USB  => find all symbols containing USB\n"
24359dfa24dSArnaud Lacombe "^USB => find all symbols starting with USB\n"
24459dfa24dSArnaud Lacombe "USB$ => find all symbols ending with USB\n"
245692d97c3Snir.tzachar@gmail.com "\n");
246692d97c3Snir.tzachar@gmail.com 
247692d97c3Snir.tzachar@gmail.com struct mitem {
248692d97c3Snir.tzachar@gmail.com 	char str[256];
249692d97c3Snir.tzachar@gmail.com 	char tag;
250692d97c3Snir.tzachar@gmail.com 	void *usrptr;
251692d97c3Snir.tzachar@gmail.com 	int is_visible;
252692d97c3Snir.tzachar@gmail.com };
253692d97c3Snir.tzachar@gmail.com 
254692d97c3Snir.tzachar@gmail.com #define MAX_MENU_ITEMS 4096
255692d97c3Snir.tzachar@gmail.com static int show_all_items;
256692d97c3Snir.tzachar@gmail.com static int indent;
257692d97c3Snir.tzachar@gmail.com static struct menu *current_menu;
258692d97c3Snir.tzachar@gmail.com static int child_count;
259692d97c3Snir.tzachar@gmail.com static int single_menu_mode;
260692d97c3Snir.tzachar@gmail.com /* the window in which all information appears */
261692d97c3Snir.tzachar@gmail.com static WINDOW *main_window;
262692d97c3Snir.tzachar@gmail.com /* the largest size of the menu window */
263692d97c3Snir.tzachar@gmail.com static int mwin_max_lines;
264692d97c3Snir.tzachar@gmail.com static int mwin_max_cols;
265692d97c3Snir.tzachar@gmail.com /* the window in which we show option buttons */
266692d97c3Snir.tzachar@gmail.com static MENU *curses_menu;
267692d97c3Snir.tzachar@gmail.com static ITEM *curses_menu_items[MAX_MENU_ITEMS];
268692d97c3Snir.tzachar@gmail.com static struct mitem k_menu_items[MAX_MENU_ITEMS];
269692d97c3Snir.tzachar@gmail.com static int items_num;
270692d97c3Snir.tzachar@gmail.com static int global_exit;
271692d97c3Snir.tzachar@gmail.com /* the currently selected button */
272692d97c3Snir.tzachar@gmail.com const char *current_instructions = menu_instructions;
273692d97c3Snir.tzachar@gmail.com 
2745ea9f64fSCheng Renquan static char *dialog_input_result;
2755ea9f64fSCheng Renquan static int dialog_input_result_len;
2765ea9f64fSCheng Renquan 
277692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu);
278692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu);
279692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu);
280692d97c3Snir.tzachar@gmail.com static void conf_load(void);
281692d97c3Snir.tzachar@gmail.com static void conf_save(void);
282692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu);
283692d97c3Snir.tzachar@gmail.com static int do_exit(void);
284692d97c3Snir.tzachar@gmail.com static void setup_windows(void);
285a72f3e2bSNir Tzachar static void search_conf(void);
286692d97c3Snir.tzachar@gmail.com 
287692d97c3Snir.tzachar@gmail.com typedef void (*function_key_handler_t)(int *key, struct menu *menu);
288692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item);
289692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item);
290692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item);
291692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item);
292692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item);
293692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item);
294692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item);
295692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item);
296a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item);
297692d97c3Snir.tzachar@gmail.com 
298692d97c3Snir.tzachar@gmail.com struct function_keys {
299692d97c3Snir.tzachar@gmail.com 	const char *key_str;
300692d97c3Snir.tzachar@gmail.com 	const char *func;
301692d97c3Snir.tzachar@gmail.com 	function_key key;
302692d97c3Snir.tzachar@gmail.com 	function_key_handler_t handler;
303692d97c3Snir.tzachar@gmail.com };
304692d97c3Snir.tzachar@gmail.com 
305a72f3e2bSNir Tzachar static const int function_keys_num = 9;
306692d97c3Snir.tzachar@gmail.com struct function_keys function_keys[] = {
307692d97c3Snir.tzachar@gmail.com 	{
308692d97c3Snir.tzachar@gmail.com 		.key_str = "F1",
309692d97c3Snir.tzachar@gmail.com 		.func = "Help",
310692d97c3Snir.tzachar@gmail.com 		.key = F_HELP,
311692d97c3Snir.tzachar@gmail.com 		.handler = handle_f1,
312692d97c3Snir.tzachar@gmail.com 	},
313692d97c3Snir.tzachar@gmail.com 	{
314692d97c3Snir.tzachar@gmail.com 		.key_str = "F2",
315a72f3e2bSNir Tzachar 		.func = "SymInfo",
316692d97c3Snir.tzachar@gmail.com 		.key = F_SYMBOL,
317692d97c3Snir.tzachar@gmail.com 		.handler = handle_f2,
318692d97c3Snir.tzachar@gmail.com 	},
319692d97c3Snir.tzachar@gmail.com 	{
320692d97c3Snir.tzachar@gmail.com 		.key_str = "F3",
321*2c68115cSRoland Eggner 		.func = "Help 2",
322692d97c3Snir.tzachar@gmail.com 		.key = F_INSTS,
323692d97c3Snir.tzachar@gmail.com 		.handler = handle_f3,
324692d97c3Snir.tzachar@gmail.com 	},
325692d97c3Snir.tzachar@gmail.com 	{
326692d97c3Snir.tzachar@gmail.com 		.key_str = "F4",
327*2c68115cSRoland Eggner 		.func = "ShowAll",
328692d97c3Snir.tzachar@gmail.com 		.key = F_CONF,
329692d97c3Snir.tzachar@gmail.com 		.handler = handle_f4,
330692d97c3Snir.tzachar@gmail.com 	},
331692d97c3Snir.tzachar@gmail.com 	{
332692d97c3Snir.tzachar@gmail.com 		.key_str = "F5",
333692d97c3Snir.tzachar@gmail.com 		.func = "Back",
334692d97c3Snir.tzachar@gmail.com 		.key = F_BACK,
335692d97c3Snir.tzachar@gmail.com 		.handler = handle_f5,
336692d97c3Snir.tzachar@gmail.com 	},
337692d97c3Snir.tzachar@gmail.com 	{
338692d97c3Snir.tzachar@gmail.com 		.key_str = "F6",
339692d97c3Snir.tzachar@gmail.com 		.func = "Save",
340692d97c3Snir.tzachar@gmail.com 		.key = F_SAVE,
341692d97c3Snir.tzachar@gmail.com 		.handler = handle_f6,
342692d97c3Snir.tzachar@gmail.com 	},
343692d97c3Snir.tzachar@gmail.com 	{
344692d97c3Snir.tzachar@gmail.com 		.key_str = "F7",
345692d97c3Snir.tzachar@gmail.com 		.func = "Load",
346692d97c3Snir.tzachar@gmail.com 		.key = F_LOAD,
347692d97c3Snir.tzachar@gmail.com 		.handler = handle_f7,
348692d97c3Snir.tzachar@gmail.com 	},
349692d97c3Snir.tzachar@gmail.com 	{
350692d97c3Snir.tzachar@gmail.com 		.key_str = "F8",
351a72f3e2bSNir Tzachar 		.func = "SymSearch",
352a72f3e2bSNir Tzachar 		.key = F_SEARCH,
353a72f3e2bSNir Tzachar 		.handler = handle_f8,
354a72f3e2bSNir Tzachar 	},
355a72f3e2bSNir Tzachar 	{
356a72f3e2bSNir Tzachar 		.key_str = "F9",
357692d97c3Snir.tzachar@gmail.com 		.func = "Exit",
358692d97c3Snir.tzachar@gmail.com 		.key = F_EXIT,
359a72f3e2bSNir Tzachar 		.handler = handle_f9,
360692d97c3Snir.tzachar@gmail.com 	},
361692d97c3Snir.tzachar@gmail.com };
362692d97c3Snir.tzachar@gmail.com 
363692d97c3Snir.tzachar@gmail.com static void print_function_line(void)
364692d97c3Snir.tzachar@gmail.com {
365692d97c3Snir.tzachar@gmail.com 	int i;
366692d97c3Snir.tzachar@gmail.com 	int offset = 1;
367692d97c3Snir.tzachar@gmail.com 	const int skip = 1;
368692d97c3Snir.tzachar@gmail.com 
369692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
37010175ba6SStephen Boyd 		(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
371692d97c3Snir.tzachar@gmail.com 		mvwprintw(main_window, LINES-3, offset,
372692d97c3Snir.tzachar@gmail.com 				"%s",
373692d97c3Snir.tzachar@gmail.com 				function_keys[i].key_str);
37410175ba6SStephen Boyd 		(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
375692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].key_str);
376692d97c3Snir.tzachar@gmail.com 		mvwprintw(main_window, LINES-3,
377692d97c3Snir.tzachar@gmail.com 				offset, "%s",
378692d97c3Snir.tzachar@gmail.com 				function_keys[i].func);
379692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].func) + skip;
380692d97c3Snir.tzachar@gmail.com 	}
38110175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[NORMAL]);
382692d97c3Snir.tzachar@gmail.com }
383692d97c3Snir.tzachar@gmail.com 
384692d97c3Snir.tzachar@gmail.com /* help */
385692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item)
386692d97c3Snir.tzachar@gmail.com {
387692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
3880b616500SRoland Eggner 			_("Global help"), _(nconf_global_help));
389692d97c3Snir.tzachar@gmail.com 	return;
390692d97c3Snir.tzachar@gmail.com }
391692d97c3Snir.tzachar@gmail.com 
392692d97c3Snir.tzachar@gmail.com /* symbole help */
393692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item)
394692d97c3Snir.tzachar@gmail.com {
395692d97c3Snir.tzachar@gmail.com 	show_help(current_item);
396692d97c3Snir.tzachar@gmail.com 	return;
397692d97c3Snir.tzachar@gmail.com }
398692d97c3Snir.tzachar@gmail.com 
399692d97c3Snir.tzachar@gmail.com /* instructions */
400692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item)
401692d97c3Snir.tzachar@gmail.com {
402692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
4030b616500SRoland Eggner 			_("Short help"),
404692d97c3Snir.tzachar@gmail.com 			_(current_instructions));
405692d97c3Snir.tzachar@gmail.com 	return;
406692d97c3Snir.tzachar@gmail.com }
407692d97c3Snir.tzachar@gmail.com 
408692d97c3Snir.tzachar@gmail.com /* config */
409692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item)
410692d97c3Snir.tzachar@gmail.com {
411692d97c3Snir.tzachar@gmail.com 	int res = btn_dialog(main_window,
412692d97c3Snir.tzachar@gmail.com 			_("Show all symbols?"),
413692d97c3Snir.tzachar@gmail.com 			2,
414692d97c3Snir.tzachar@gmail.com 			"   <Show All>   ",
415692d97c3Snir.tzachar@gmail.com 			"<Don't show all>");
416692d97c3Snir.tzachar@gmail.com 	if (res == 0)
417692d97c3Snir.tzachar@gmail.com 		show_all_items = 1;
418692d97c3Snir.tzachar@gmail.com 	else if (res == 1)
419692d97c3Snir.tzachar@gmail.com 		show_all_items = 0;
420692d97c3Snir.tzachar@gmail.com 
421692d97c3Snir.tzachar@gmail.com 	return;
422692d97c3Snir.tzachar@gmail.com }
423692d97c3Snir.tzachar@gmail.com 
424692d97c3Snir.tzachar@gmail.com /* back */
425692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item)
426692d97c3Snir.tzachar@gmail.com {
427692d97c3Snir.tzachar@gmail.com 	*key = KEY_LEFT;
428692d97c3Snir.tzachar@gmail.com 	return;
429692d97c3Snir.tzachar@gmail.com }
430692d97c3Snir.tzachar@gmail.com 
431692d97c3Snir.tzachar@gmail.com /* save */
432692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item)
433692d97c3Snir.tzachar@gmail.com {
434692d97c3Snir.tzachar@gmail.com 	conf_save();
435692d97c3Snir.tzachar@gmail.com 	return;
436692d97c3Snir.tzachar@gmail.com }
437692d97c3Snir.tzachar@gmail.com 
438692d97c3Snir.tzachar@gmail.com /* load */
439692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item)
440692d97c3Snir.tzachar@gmail.com {
441692d97c3Snir.tzachar@gmail.com 	conf_load();
442692d97c3Snir.tzachar@gmail.com 	return;
443692d97c3Snir.tzachar@gmail.com }
444692d97c3Snir.tzachar@gmail.com 
445a72f3e2bSNir Tzachar /* search */
446692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item)
447692d97c3Snir.tzachar@gmail.com {
448a72f3e2bSNir Tzachar 	search_conf();
449a72f3e2bSNir Tzachar 	return;
450a72f3e2bSNir Tzachar }
451a72f3e2bSNir Tzachar 
452a72f3e2bSNir Tzachar /* exit */
453a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item)
454a72f3e2bSNir Tzachar {
455692d97c3Snir.tzachar@gmail.com 	do_exit();
456692d97c3Snir.tzachar@gmail.com 	return;
457692d97c3Snir.tzachar@gmail.com }
458692d97c3Snir.tzachar@gmail.com 
459692d97c3Snir.tzachar@gmail.com /* return != 0 to indicate the key was handles */
460851190c9SMichal Marek static int process_special_keys(int *key, struct menu *menu)
461692d97c3Snir.tzachar@gmail.com {
462692d97c3Snir.tzachar@gmail.com 	int i;
463692d97c3Snir.tzachar@gmail.com 
464692d97c3Snir.tzachar@gmail.com 	if (*key == KEY_RESIZE) {
465692d97c3Snir.tzachar@gmail.com 		setup_windows();
466692d97c3Snir.tzachar@gmail.com 		return 1;
467692d97c3Snir.tzachar@gmail.com 	}
468692d97c3Snir.tzachar@gmail.com 
469692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
470692d97c3Snir.tzachar@gmail.com 		if (*key == KEY_F(function_keys[i].key) ||
471692d97c3Snir.tzachar@gmail.com 		    *key == '0' + function_keys[i].key){
472692d97c3Snir.tzachar@gmail.com 			function_keys[i].handler(key, menu);
473692d97c3Snir.tzachar@gmail.com 			return 1;
474692d97c3Snir.tzachar@gmail.com 		}
475692d97c3Snir.tzachar@gmail.com 	}
476692d97c3Snir.tzachar@gmail.com 
477692d97c3Snir.tzachar@gmail.com 	return 0;
478692d97c3Snir.tzachar@gmail.com }
479692d97c3Snir.tzachar@gmail.com 
480692d97c3Snir.tzachar@gmail.com static void clean_items(void)
481692d97c3Snir.tzachar@gmail.com {
482692d97c3Snir.tzachar@gmail.com 	int i;
483692d97c3Snir.tzachar@gmail.com 	for (i = 0; curses_menu_items[i]; i++)
484692d97c3Snir.tzachar@gmail.com 		free_item(curses_menu_items[i]);
485692d97c3Snir.tzachar@gmail.com 	bzero(curses_menu_items, sizeof(curses_menu_items));
486692d97c3Snir.tzachar@gmail.com 	bzero(k_menu_items, sizeof(k_menu_items));
487692d97c3Snir.tzachar@gmail.com 	items_num = 0;
488692d97c3Snir.tzachar@gmail.com }
489692d97c3Snir.tzachar@gmail.com 
490a72f3e2bSNir Tzachar typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
491a72f3e2bSNir Tzachar 	FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
492692d97c3Snir.tzachar@gmail.com 
493a72f3e2bSNir Tzachar /* return the index of the matched item, or -1 if no such item exists */
494a72f3e2bSNir Tzachar static int get_mext_match(const char *match_str, match_f flag)
495a72f3e2bSNir Tzachar {
496a72f3e2bSNir Tzachar 	int match_start = item_index(current_item(curses_menu));
497a72f3e2bSNir Tzachar 	int index;
498a72f3e2bSNir Tzachar 
499a72f3e2bSNir Tzachar 	if (flag == FIND_NEXT_MATCH_DOWN)
500a72f3e2bSNir Tzachar 		++match_start;
501a72f3e2bSNir Tzachar 	else if (flag == FIND_NEXT_MATCH_UP)
502a72f3e2bSNir Tzachar 		--match_start;
503a72f3e2bSNir Tzachar 
504a72f3e2bSNir Tzachar 	index = match_start;
505a72f3e2bSNir Tzachar 	index = (index + items_num) % items_num;
506a72f3e2bSNir Tzachar 	while (true) {
507a72f3e2bSNir Tzachar 		char *str = k_menu_items[index].str;
508a72f3e2bSNir Tzachar 		if (strcasestr(str, match_str) != 0)
509a72f3e2bSNir Tzachar 			return index;
510a72f3e2bSNir Tzachar 		if (flag == FIND_NEXT_MATCH_UP ||
511a72f3e2bSNir Tzachar 		    flag == MATCH_TINKER_PATTERN_UP)
512a72f3e2bSNir Tzachar 			--index;
513a72f3e2bSNir Tzachar 		else
514a72f3e2bSNir Tzachar 			++index;
515a72f3e2bSNir Tzachar 		index = (index + items_num) % items_num;
516a72f3e2bSNir Tzachar 		if (index == match_start)
517692d97c3Snir.tzachar@gmail.com 			return -1;
518692d97c3Snir.tzachar@gmail.com 	}
519692d97c3Snir.tzachar@gmail.com }
520692d97c3Snir.tzachar@gmail.com 
521a72f3e2bSNir Tzachar /* Make a new item. */
522851190c9SMichal Marek static void item_make(struct menu *menu, char tag, const char *fmt, ...)
523692d97c3Snir.tzachar@gmail.com {
524692d97c3Snir.tzachar@gmail.com 	va_list ap;
525692d97c3Snir.tzachar@gmail.com 
526692d97c3Snir.tzachar@gmail.com 	if (items_num > MAX_MENU_ITEMS-1)
527692d97c3Snir.tzachar@gmail.com 		return;
528692d97c3Snir.tzachar@gmail.com 
529692d97c3Snir.tzachar@gmail.com 	bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
530692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].tag = tag;
531692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].usrptr = menu;
532692d97c3Snir.tzachar@gmail.com 	if (menu != NULL)
533692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible =
534692d97c3Snir.tzachar@gmail.com 			menu_is_visible(menu);
535692d97c3Snir.tzachar@gmail.com 	else
536692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible = 1;
537692d97c3Snir.tzachar@gmail.com 
538692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
539a72f3e2bSNir Tzachar 	vsnprintf(k_menu_items[items_num].str,
540a72f3e2bSNir Tzachar 		  sizeof(k_menu_items[items_num].str),
541a72f3e2bSNir Tzachar 		  fmt, ap);
542692d97c3Snir.tzachar@gmail.com 	va_end(ap);
543a72f3e2bSNir Tzachar 
544a72f3e2bSNir Tzachar 	if (!k_menu_items[items_num].is_visible)
545a72f3e2bSNir Tzachar 		memcpy(k_menu_items[items_num].str, "XXX", 3);
546692d97c3Snir.tzachar@gmail.com 
547692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = new_item(
548692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str,
549692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str);
550692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[items_num],
551692d97c3Snir.tzachar@gmail.com 			&k_menu_items[items_num]);
552692d97c3Snir.tzachar@gmail.com 	/*
553692d97c3Snir.tzachar@gmail.com 	if (!k_menu_items[items_num].is_visible)
554692d97c3Snir.tzachar@gmail.com 		item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
555692d97c3Snir.tzachar@gmail.com 	*/
556692d97c3Snir.tzachar@gmail.com 
557692d97c3Snir.tzachar@gmail.com 	items_num++;
558692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = NULL;
559692d97c3Snir.tzachar@gmail.com }
560692d97c3Snir.tzachar@gmail.com 
561692d97c3Snir.tzachar@gmail.com /* very hackish. adds a string to the last item added */
562851190c9SMichal Marek static void item_add_str(const char *fmt, ...)
563692d97c3Snir.tzachar@gmail.com {
564692d97c3Snir.tzachar@gmail.com 	va_list ap;
565692d97c3Snir.tzachar@gmail.com 	int index = items_num-1;
566692d97c3Snir.tzachar@gmail.com 	char new_str[256];
567692d97c3Snir.tzachar@gmail.com 	char tmp_str[256];
568692d97c3Snir.tzachar@gmail.com 
569692d97c3Snir.tzachar@gmail.com 	if (index < 0)
570692d97c3Snir.tzachar@gmail.com 		return;
571692d97c3Snir.tzachar@gmail.com 
572692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
573692d97c3Snir.tzachar@gmail.com 	vsnprintf(new_str, sizeof(new_str), fmt, ap);
574692d97c3Snir.tzachar@gmail.com 	va_end(ap);
575692d97c3Snir.tzachar@gmail.com 	snprintf(tmp_str, sizeof(tmp_str), "%s%s",
576692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str, new_str);
577692d97c3Snir.tzachar@gmail.com 	strncpy(k_menu_items[index].str,
578692d97c3Snir.tzachar@gmail.com 		tmp_str,
579692d97c3Snir.tzachar@gmail.com 		sizeof(k_menu_items[index].str));
580692d97c3Snir.tzachar@gmail.com 
581692d97c3Snir.tzachar@gmail.com 	free_item(curses_menu_items[index]);
582692d97c3Snir.tzachar@gmail.com 	curses_menu_items[index] = new_item(
583692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str,
584692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str);
585692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[index],
586692d97c3Snir.tzachar@gmail.com 			&k_menu_items[index]);
587692d97c3Snir.tzachar@gmail.com }
588692d97c3Snir.tzachar@gmail.com 
589692d97c3Snir.tzachar@gmail.com /* get the tag of the currently selected item */
590851190c9SMichal Marek static char item_tag(void)
591692d97c3Snir.tzachar@gmail.com {
592692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
593692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
594692d97c3Snir.tzachar@gmail.com 
595692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
596692d97c3Snir.tzachar@gmail.com 	if (cur == NULL)
597692d97c3Snir.tzachar@gmail.com 		return 0;
598692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
599692d97c3Snir.tzachar@gmail.com 	return mcur->tag;
600692d97c3Snir.tzachar@gmail.com }
601692d97c3Snir.tzachar@gmail.com 
602851190c9SMichal Marek static int curses_item_index(void)
603692d97c3Snir.tzachar@gmail.com {
604692d97c3Snir.tzachar@gmail.com 	return  item_index(current_item(curses_menu));
605692d97c3Snir.tzachar@gmail.com }
606692d97c3Snir.tzachar@gmail.com 
607851190c9SMichal Marek static void *item_data(void)
608692d97c3Snir.tzachar@gmail.com {
609692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
610692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
611692d97c3Snir.tzachar@gmail.com 
612692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
613866af407SAndrej Gelenberg 	if (!cur)
614866af407SAndrej Gelenberg 		return NULL;
615692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
616692d97c3Snir.tzachar@gmail.com 	return mcur->usrptr;
617692d97c3Snir.tzachar@gmail.com 
618692d97c3Snir.tzachar@gmail.com }
619692d97c3Snir.tzachar@gmail.com 
620851190c9SMichal Marek static int item_is_tag(char tag)
621692d97c3Snir.tzachar@gmail.com {
622692d97c3Snir.tzachar@gmail.com 	return item_tag() == tag;
623692d97c3Snir.tzachar@gmail.com }
624692d97c3Snir.tzachar@gmail.com 
625692d97c3Snir.tzachar@gmail.com static char filename[PATH_MAX+1];
626692d97c3Snir.tzachar@gmail.com static char menu_backtitle[PATH_MAX+128];
627851190c9SMichal Marek static const char *set_config_filename(const char *config_filename)
628692d97c3Snir.tzachar@gmail.com {
629692d97c3Snir.tzachar@gmail.com 	int size;
630692d97c3Snir.tzachar@gmail.com 
631692d97c3Snir.tzachar@gmail.com 	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
6320954828fSArnaud Lacombe 			"%s - %s", config_filename, rootmenu.prompt->text);
633692d97c3Snir.tzachar@gmail.com 	if (size >= sizeof(menu_backtitle))
634692d97c3Snir.tzachar@gmail.com 		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
635692d97c3Snir.tzachar@gmail.com 
636692d97c3Snir.tzachar@gmail.com 	size = snprintf(filename, sizeof(filename), "%s", config_filename);
637692d97c3Snir.tzachar@gmail.com 	if (size >= sizeof(filename))
638692d97c3Snir.tzachar@gmail.com 		filename[sizeof(filename)-1] = '\0';
639692d97c3Snir.tzachar@gmail.com 	return menu_backtitle;
640692d97c3Snir.tzachar@gmail.com }
641692d97c3Snir.tzachar@gmail.com 
642692d97c3Snir.tzachar@gmail.com /* return = 0 means we are successful.
643692d97c3Snir.tzachar@gmail.com  * -1 means go on doing what you were doing
644692d97c3Snir.tzachar@gmail.com  */
645692d97c3Snir.tzachar@gmail.com static int do_exit(void)
646692d97c3Snir.tzachar@gmail.com {
647692d97c3Snir.tzachar@gmail.com 	int res;
648692d97c3Snir.tzachar@gmail.com 	if (!conf_get_changed()) {
649692d97c3Snir.tzachar@gmail.com 		global_exit = 1;
650692d97c3Snir.tzachar@gmail.com 		return 0;
651692d97c3Snir.tzachar@gmail.com 	}
652692d97c3Snir.tzachar@gmail.com 	res = btn_dialog(main_window,
653652cf982SArnaud Lacombe 			_("Do you wish to save your new configuration?\n"
654692d97c3Snir.tzachar@gmail.com 				"<ESC> to cancel and resume nconfig."),
655692d97c3Snir.tzachar@gmail.com 			2,
656692d97c3Snir.tzachar@gmail.com 			"   <save>   ",
657692d97c3Snir.tzachar@gmail.com 			"<don't save>");
658692d97c3Snir.tzachar@gmail.com 	if (res == KEY_EXIT) {
659692d97c3Snir.tzachar@gmail.com 		global_exit = 0;
660692d97c3Snir.tzachar@gmail.com 		return -1;
661692d97c3Snir.tzachar@gmail.com 	}
662692d97c3Snir.tzachar@gmail.com 
663692d97c3Snir.tzachar@gmail.com 	/* if we got here, the user really wants to exit */
664692d97c3Snir.tzachar@gmail.com 	switch (res) {
665692d97c3Snir.tzachar@gmail.com 	case 0:
666692d97c3Snir.tzachar@gmail.com 		res = conf_write(filename);
667692d97c3Snir.tzachar@gmail.com 		if (res)
668692d97c3Snir.tzachar@gmail.com 			btn_dialog(
669692d97c3Snir.tzachar@gmail.com 				main_window,
670652cf982SArnaud Lacombe 				_("Error during writing of configuration.\n"
671652cf982SArnaud Lacombe 				  "Your configuration changes were NOT saved."),
672692d97c3Snir.tzachar@gmail.com 				  1,
673692d97c3Snir.tzachar@gmail.com 				  "<OK>");
674692d97c3Snir.tzachar@gmail.com 		break;
675692d97c3Snir.tzachar@gmail.com 	default:
676692d97c3Snir.tzachar@gmail.com 		btn_dialog(
677692d97c3Snir.tzachar@gmail.com 			main_window,
678652cf982SArnaud Lacombe 			_("Your configuration changes were NOT saved."),
679692d97c3Snir.tzachar@gmail.com 			1,
680692d97c3Snir.tzachar@gmail.com 			"<OK>");
681692d97c3Snir.tzachar@gmail.com 		break;
682692d97c3Snir.tzachar@gmail.com 	}
683692d97c3Snir.tzachar@gmail.com 	global_exit = 1;
684692d97c3Snir.tzachar@gmail.com 	return 0;
685692d97c3Snir.tzachar@gmail.com }
686692d97c3Snir.tzachar@gmail.com 
687692d97c3Snir.tzachar@gmail.com 
688692d97c3Snir.tzachar@gmail.com static void search_conf(void)
689692d97c3Snir.tzachar@gmail.com {
690692d97c3Snir.tzachar@gmail.com 	struct symbol **sym_arr;
691692d97c3Snir.tzachar@gmail.com 	struct gstr res;
692337a275dSYann E. MORIN 	struct gstr title;
693692d97c3Snir.tzachar@gmail.com 	char *dialog_input;
694692d97c3Snir.tzachar@gmail.com 	int dres;
695337a275dSYann E. MORIN 
696337a275dSYann E. MORIN 	title = str_new();
697337a275dSYann E. MORIN 	str_printf( &title, _("Enter %s (sub)string to search for "
698337a275dSYann E. MORIN 			      "(with or without \"%s\")"), CONFIG_, CONFIG_);
699337a275dSYann E. MORIN 
700692d97c3Snir.tzachar@gmail.com again:
701692d97c3Snir.tzachar@gmail.com 	dres = dialog_inputbox(main_window,
702692d97c3Snir.tzachar@gmail.com 			_("Search Configuration Parameter"),
703337a275dSYann E. MORIN 			str_get(&title),
7045ea9f64fSCheng Renquan 			"", &dialog_input_result, &dialog_input_result_len);
705692d97c3Snir.tzachar@gmail.com 	switch (dres) {
706692d97c3Snir.tzachar@gmail.com 	case 0:
707692d97c3Snir.tzachar@gmail.com 		break;
708692d97c3Snir.tzachar@gmail.com 	case 1:
709692d97c3Snir.tzachar@gmail.com 		show_scroll_win(main_window,
710692d97c3Snir.tzachar@gmail.com 				_("Search Configuration"), search_help);
711692d97c3Snir.tzachar@gmail.com 		goto again;
712692d97c3Snir.tzachar@gmail.com 	default:
713337a275dSYann E. MORIN 		str_free(&title);
714692d97c3Snir.tzachar@gmail.com 		return;
715692d97c3Snir.tzachar@gmail.com 	}
716692d97c3Snir.tzachar@gmail.com 
717ffb5957bSArnaud Lacombe 	/* strip the prefix if necessary */
718692d97c3Snir.tzachar@gmail.com 	dialog_input = dialog_input_result;
719ffb5957bSArnaud Lacombe 	if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
720ffb5957bSArnaud Lacombe 		dialog_input += strlen(CONFIG_);
721692d97c3Snir.tzachar@gmail.com 
722692d97c3Snir.tzachar@gmail.com 	sym_arr = sym_re_search(dialog_input);
7235e609addSBenjamin Poirier 	res = get_relations_str(sym_arr, NULL);
724692d97c3Snir.tzachar@gmail.com 	free(sym_arr);
725692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
726692d97c3Snir.tzachar@gmail.com 			_("Search Results"), str_get(&res));
727692d97c3Snir.tzachar@gmail.com 	str_free(&res);
728337a275dSYann E. MORIN 	str_free(&title);
729692d97c3Snir.tzachar@gmail.com }
730692d97c3Snir.tzachar@gmail.com 
731692d97c3Snir.tzachar@gmail.com 
732692d97c3Snir.tzachar@gmail.com static void build_conf(struct menu *menu)
733692d97c3Snir.tzachar@gmail.com {
734692d97c3Snir.tzachar@gmail.com 	struct symbol *sym;
735692d97c3Snir.tzachar@gmail.com 	struct property *prop;
736692d97c3Snir.tzachar@gmail.com 	struct menu *child;
737692d97c3Snir.tzachar@gmail.com 	int type, tmp, doint = 2;
738692d97c3Snir.tzachar@gmail.com 	tristate val;
739692d97c3Snir.tzachar@gmail.com 	char ch;
740692d97c3Snir.tzachar@gmail.com 
741692d97c3Snir.tzachar@gmail.com 	if (!menu || (!show_all_items && !menu_is_visible(menu)))
742692d97c3Snir.tzachar@gmail.com 		return;
743692d97c3Snir.tzachar@gmail.com 
744692d97c3Snir.tzachar@gmail.com 	sym = menu->sym;
745692d97c3Snir.tzachar@gmail.com 	prop = menu->prompt;
746692d97c3Snir.tzachar@gmail.com 	if (!sym) {
747692d97c3Snir.tzachar@gmail.com 		if (prop && menu != current_menu) {
748692d97c3Snir.tzachar@gmail.com 			const char *prompt = menu_get_prompt(menu);
749692d97c3Snir.tzachar@gmail.com 			enum prop_type ptype;
750692d97c3Snir.tzachar@gmail.com 			ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
751692d97c3Snir.tzachar@gmail.com 			switch (ptype) {
752692d97c3Snir.tzachar@gmail.com 			case P_MENU:
753692d97c3Snir.tzachar@gmail.com 				child_count++;
754692d97c3Snir.tzachar@gmail.com 				prompt = _(prompt);
755692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode) {
756692d97c3Snir.tzachar@gmail.com 					item_make(menu, 'm',
757692d97c3Snir.tzachar@gmail.com 						"%s%*c%s",
758692d97c3Snir.tzachar@gmail.com 						menu->data ? "-->" : "++>",
759692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ', prompt);
760692d97c3Snir.tzachar@gmail.com 				} else
761692d97c3Snir.tzachar@gmail.com 					item_make(menu, 'm',
762692d97c3Snir.tzachar@gmail.com 						"   %*c%s  --->",
763692d97c3Snir.tzachar@gmail.com 						indent + 1,
764692d97c3Snir.tzachar@gmail.com 						' ', prompt);
765692d97c3Snir.tzachar@gmail.com 
766692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode && menu->data)
767692d97c3Snir.tzachar@gmail.com 					goto conf_childs;
768692d97c3Snir.tzachar@gmail.com 				return;
769692d97c3Snir.tzachar@gmail.com 			case P_COMMENT:
770692d97c3Snir.tzachar@gmail.com 				if (prompt) {
771692d97c3Snir.tzachar@gmail.com 					child_count++;
772692d97c3Snir.tzachar@gmail.com 					item_make(menu, ':',
773692d97c3Snir.tzachar@gmail.com 						"   %*c*** %s ***",
774692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ',
775692d97c3Snir.tzachar@gmail.com 						_(prompt));
776692d97c3Snir.tzachar@gmail.com 				}
777692d97c3Snir.tzachar@gmail.com 				break;
778692d97c3Snir.tzachar@gmail.com 			default:
779692d97c3Snir.tzachar@gmail.com 				if (prompt) {
780692d97c3Snir.tzachar@gmail.com 					child_count++;
781692d97c3Snir.tzachar@gmail.com 					item_make(menu, ':', "---%*c%s",
782692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ',
783692d97c3Snir.tzachar@gmail.com 						_(prompt));
784692d97c3Snir.tzachar@gmail.com 				}
785692d97c3Snir.tzachar@gmail.com 			}
786692d97c3Snir.tzachar@gmail.com 		} else
787692d97c3Snir.tzachar@gmail.com 			doint = 0;
788692d97c3Snir.tzachar@gmail.com 		goto conf_childs;
789692d97c3Snir.tzachar@gmail.com 	}
790692d97c3Snir.tzachar@gmail.com 
791692d97c3Snir.tzachar@gmail.com 	type = sym_get_type(sym);
792692d97c3Snir.tzachar@gmail.com 	if (sym_is_choice(sym)) {
793692d97c3Snir.tzachar@gmail.com 		struct symbol *def_sym = sym_get_choice_value(sym);
794692d97c3Snir.tzachar@gmail.com 		struct menu *def_menu = NULL;
795692d97c3Snir.tzachar@gmail.com 
796692d97c3Snir.tzachar@gmail.com 		child_count++;
797692d97c3Snir.tzachar@gmail.com 		for (child = menu->list; child; child = child->next) {
798692d97c3Snir.tzachar@gmail.com 			if (menu_is_visible(child) && child->sym == def_sym)
799692d97c3Snir.tzachar@gmail.com 				def_menu = child;
800692d97c3Snir.tzachar@gmail.com 		}
801692d97c3Snir.tzachar@gmail.com 
802692d97c3Snir.tzachar@gmail.com 		val = sym_get_tristate_value(sym);
803692d97c3Snir.tzachar@gmail.com 		if (sym_is_changable(sym)) {
804692d97c3Snir.tzachar@gmail.com 			switch (type) {
805692d97c3Snir.tzachar@gmail.com 			case S_BOOLEAN:
806692d97c3Snir.tzachar@gmail.com 				item_make(menu, 't', "[%c]",
807692d97c3Snir.tzachar@gmail.com 						val == no ? ' ' : '*');
808692d97c3Snir.tzachar@gmail.com 				break;
809692d97c3Snir.tzachar@gmail.com 			case S_TRISTATE:
810692d97c3Snir.tzachar@gmail.com 				switch (val) {
811692d97c3Snir.tzachar@gmail.com 				case yes:
812692d97c3Snir.tzachar@gmail.com 					ch = '*';
813692d97c3Snir.tzachar@gmail.com 					break;
814692d97c3Snir.tzachar@gmail.com 				case mod:
815692d97c3Snir.tzachar@gmail.com 					ch = 'M';
816692d97c3Snir.tzachar@gmail.com 					break;
817692d97c3Snir.tzachar@gmail.com 				default:
818692d97c3Snir.tzachar@gmail.com 					ch = ' ';
819692d97c3Snir.tzachar@gmail.com 					break;
820692d97c3Snir.tzachar@gmail.com 				}
821692d97c3Snir.tzachar@gmail.com 				item_make(menu, 't', "<%c>", ch);
822692d97c3Snir.tzachar@gmail.com 				break;
823692d97c3Snir.tzachar@gmail.com 			}
824692d97c3Snir.tzachar@gmail.com 		} else {
825692d97c3Snir.tzachar@gmail.com 			item_make(menu, def_menu ? 't' : ':', "   ");
826692d97c3Snir.tzachar@gmail.com 		}
827692d97c3Snir.tzachar@gmail.com 
828692d97c3Snir.tzachar@gmail.com 		item_add_str("%*c%s", indent + 1,
829692d97c3Snir.tzachar@gmail.com 				' ', _(menu_get_prompt(menu)));
830692d97c3Snir.tzachar@gmail.com 		if (val == yes) {
831692d97c3Snir.tzachar@gmail.com 			if (def_menu) {
832692d97c3Snir.tzachar@gmail.com 				item_add_str(" (%s)",
833692d97c3Snir.tzachar@gmail.com 					_(menu_get_prompt(def_menu)));
834692d97c3Snir.tzachar@gmail.com 				item_add_str("  --->");
835692d97c3Snir.tzachar@gmail.com 				if (def_menu->list) {
836692d97c3Snir.tzachar@gmail.com 					indent += 2;
837692d97c3Snir.tzachar@gmail.com 					build_conf(def_menu);
838692d97c3Snir.tzachar@gmail.com 					indent -= 2;
839692d97c3Snir.tzachar@gmail.com 				}
840692d97c3Snir.tzachar@gmail.com 			}
841692d97c3Snir.tzachar@gmail.com 			return;
842692d97c3Snir.tzachar@gmail.com 		}
843692d97c3Snir.tzachar@gmail.com 	} else {
844692d97c3Snir.tzachar@gmail.com 		if (menu == current_menu) {
845692d97c3Snir.tzachar@gmail.com 			item_make(menu, ':',
846692d97c3Snir.tzachar@gmail.com 				"---%*c%s", indent + 1,
847692d97c3Snir.tzachar@gmail.com 				' ', _(menu_get_prompt(menu)));
848692d97c3Snir.tzachar@gmail.com 			goto conf_childs;
849692d97c3Snir.tzachar@gmail.com 		}
850692d97c3Snir.tzachar@gmail.com 		child_count++;
851692d97c3Snir.tzachar@gmail.com 		val = sym_get_tristate_value(sym);
852692d97c3Snir.tzachar@gmail.com 		if (sym_is_choice_value(sym) && val == yes) {
853692d97c3Snir.tzachar@gmail.com 			item_make(menu, ':', "   ");
854692d97c3Snir.tzachar@gmail.com 		} else {
855692d97c3Snir.tzachar@gmail.com 			switch (type) {
856692d97c3Snir.tzachar@gmail.com 			case S_BOOLEAN:
857692d97c3Snir.tzachar@gmail.com 				if (sym_is_changable(sym))
858692d97c3Snir.tzachar@gmail.com 					item_make(menu, 't', "[%c]",
859692d97c3Snir.tzachar@gmail.com 						val == no ? ' ' : '*');
860692d97c3Snir.tzachar@gmail.com 				else
861692d97c3Snir.tzachar@gmail.com 					item_make(menu, 't', "-%c-",
862692d97c3Snir.tzachar@gmail.com 						val == no ? ' ' : '*');
863692d97c3Snir.tzachar@gmail.com 				break;
864692d97c3Snir.tzachar@gmail.com 			case S_TRISTATE:
865692d97c3Snir.tzachar@gmail.com 				switch (val) {
866692d97c3Snir.tzachar@gmail.com 				case yes:
867692d97c3Snir.tzachar@gmail.com 					ch = '*';
868692d97c3Snir.tzachar@gmail.com 					break;
869692d97c3Snir.tzachar@gmail.com 				case mod:
870692d97c3Snir.tzachar@gmail.com 					ch = 'M';
871692d97c3Snir.tzachar@gmail.com 					break;
872692d97c3Snir.tzachar@gmail.com 				default:
873692d97c3Snir.tzachar@gmail.com 					ch = ' ';
874692d97c3Snir.tzachar@gmail.com 					break;
875692d97c3Snir.tzachar@gmail.com 				}
876692d97c3Snir.tzachar@gmail.com 				if (sym_is_changable(sym)) {
877692d97c3Snir.tzachar@gmail.com 					if (sym->rev_dep.tri == mod)
878692d97c3Snir.tzachar@gmail.com 						item_make(menu,
879692d97c3Snir.tzachar@gmail.com 							't', "{%c}", ch);
880692d97c3Snir.tzachar@gmail.com 					else
881692d97c3Snir.tzachar@gmail.com 						item_make(menu,
882692d97c3Snir.tzachar@gmail.com 							't', "<%c>", ch);
883692d97c3Snir.tzachar@gmail.com 				} else
884692d97c3Snir.tzachar@gmail.com 					item_make(menu, 't', "-%c-", ch);
885692d97c3Snir.tzachar@gmail.com 				break;
886692d97c3Snir.tzachar@gmail.com 			default:
887692d97c3Snir.tzachar@gmail.com 				tmp = 2 + strlen(sym_get_string_value(sym));
888692d97c3Snir.tzachar@gmail.com 				item_make(menu, 's', "    (%s)",
889692d97c3Snir.tzachar@gmail.com 						sym_get_string_value(sym));
890692d97c3Snir.tzachar@gmail.com 				tmp = indent - tmp + 4;
891692d97c3Snir.tzachar@gmail.com 				if (tmp < 0)
892692d97c3Snir.tzachar@gmail.com 					tmp = 0;
893692d97c3Snir.tzachar@gmail.com 				item_add_str("%*c%s%s", tmp, ' ',
894692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(menu)),
895692d97c3Snir.tzachar@gmail.com 						(sym_has_value(sym) ||
896692d97c3Snir.tzachar@gmail.com 						 !sym_is_changable(sym)) ? "" :
897692d97c3Snir.tzachar@gmail.com 						_(" (NEW)"));
898692d97c3Snir.tzachar@gmail.com 				goto conf_childs;
899692d97c3Snir.tzachar@gmail.com 			}
900692d97c3Snir.tzachar@gmail.com 		}
901692d97c3Snir.tzachar@gmail.com 		item_add_str("%*c%s%s", indent + 1, ' ',
902692d97c3Snir.tzachar@gmail.com 				_(menu_get_prompt(menu)),
903692d97c3Snir.tzachar@gmail.com 				(sym_has_value(sym) || !sym_is_changable(sym)) ?
904692d97c3Snir.tzachar@gmail.com 				"" : _(" (NEW)"));
905692d97c3Snir.tzachar@gmail.com 		if (menu->prompt && menu->prompt->type == P_MENU) {
906692d97c3Snir.tzachar@gmail.com 			item_add_str("  --->");
907692d97c3Snir.tzachar@gmail.com 			return;
908692d97c3Snir.tzachar@gmail.com 		}
909692d97c3Snir.tzachar@gmail.com 	}
910692d97c3Snir.tzachar@gmail.com 
911692d97c3Snir.tzachar@gmail.com conf_childs:
912692d97c3Snir.tzachar@gmail.com 	indent += doint;
913692d97c3Snir.tzachar@gmail.com 	for (child = menu->list; child; child = child->next)
914692d97c3Snir.tzachar@gmail.com 		build_conf(child);
915692d97c3Snir.tzachar@gmail.com 	indent -= doint;
916692d97c3Snir.tzachar@gmail.com }
917692d97c3Snir.tzachar@gmail.com 
918692d97c3Snir.tzachar@gmail.com static void reset_menu(void)
919692d97c3Snir.tzachar@gmail.com {
920692d97c3Snir.tzachar@gmail.com 	unpost_menu(curses_menu);
921692d97c3Snir.tzachar@gmail.com 	clean_items();
922692d97c3Snir.tzachar@gmail.com }
923692d97c3Snir.tzachar@gmail.com 
924692d97c3Snir.tzachar@gmail.com /* adjust the menu to show this item.
925692d97c3Snir.tzachar@gmail.com  * prefer not to scroll the menu if possible*/
926692d97c3Snir.tzachar@gmail.com static void center_item(int selected_index, int *last_top_row)
927692d97c3Snir.tzachar@gmail.com {
928692d97c3Snir.tzachar@gmail.com 	int toprow;
929692d97c3Snir.tzachar@gmail.com 
930692d97c3Snir.tzachar@gmail.com 	set_top_row(curses_menu, *last_top_row);
931692d97c3Snir.tzachar@gmail.com 	toprow = top_row(curses_menu);
932a72f3e2bSNir Tzachar 	if (selected_index < toprow ||
933a72f3e2bSNir Tzachar 	    selected_index >= toprow+mwin_max_lines) {
934a72f3e2bSNir Tzachar 		toprow = max(selected_index-mwin_max_lines/2, 0);
935a72f3e2bSNir Tzachar 		if (toprow >= item_count(curses_menu)-mwin_max_lines)
936692d97c3Snir.tzachar@gmail.com 			toprow = item_count(curses_menu)-mwin_max_lines;
937692d97c3Snir.tzachar@gmail.com 		set_top_row(curses_menu, toprow);
938a72f3e2bSNir Tzachar 	}
939692d97c3Snir.tzachar@gmail.com 	set_current_item(curses_menu,
940692d97c3Snir.tzachar@gmail.com 			curses_menu_items[selected_index]);
941692d97c3Snir.tzachar@gmail.com 	*last_top_row = toprow;
942692d97c3Snir.tzachar@gmail.com 	post_menu(curses_menu);
943692d97c3Snir.tzachar@gmail.com 	refresh_all_windows(main_window);
944692d97c3Snir.tzachar@gmail.com }
945692d97c3Snir.tzachar@gmail.com 
946692d97c3Snir.tzachar@gmail.com /* this function assumes reset_menu has been called before */
947692d97c3Snir.tzachar@gmail.com static void show_menu(const char *prompt, const char *instructions,
948692d97c3Snir.tzachar@gmail.com 		int selected_index, int *last_top_row)
949692d97c3Snir.tzachar@gmail.com {
950692d97c3Snir.tzachar@gmail.com 	int maxx, maxy;
951692d97c3Snir.tzachar@gmail.com 	WINDOW *menu_window;
952692d97c3Snir.tzachar@gmail.com 
953692d97c3Snir.tzachar@gmail.com 	current_instructions = instructions;
954692d97c3Snir.tzachar@gmail.com 
955692d97c3Snir.tzachar@gmail.com 	clear();
95610175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[NORMAL]);
957692d97c3Snir.tzachar@gmail.com 	print_in_middle(stdscr, 1, 0, COLS,
958692d97c3Snir.tzachar@gmail.com 			menu_backtitle,
959692d97c3Snir.tzachar@gmail.com 			attributes[MAIN_HEADING]);
960692d97c3Snir.tzachar@gmail.com 
96110175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
962692d97c3Snir.tzachar@gmail.com 	box(main_window, 0, 0);
96310175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
964692d97c3Snir.tzachar@gmail.com 	mvwprintw(main_window, 0, 3, " %s ", prompt);
96510175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[NORMAL]);
966692d97c3Snir.tzachar@gmail.com 
967692d97c3Snir.tzachar@gmail.com 	set_menu_items(curses_menu, curses_menu_items);
968692d97c3Snir.tzachar@gmail.com 
969692d97c3Snir.tzachar@gmail.com 	/* position the menu at the middle of the screen */
970692d97c3Snir.tzachar@gmail.com 	scale_menu(curses_menu, &maxy, &maxx);
97168c16eddSNir Tzachar 	maxx = min(maxx, mwin_max_cols-2);
972a72f3e2bSNir Tzachar 	maxy = mwin_max_lines;
973692d97c3Snir.tzachar@gmail.com 	menu_window = derwin(main_window,
974692d97c3Snir.tzachar@gmail.com 			maxy,
975692d97c3Snir.tzachar@gmail.com 			maxx,
976692d97c3Snir.tzachar@gmail.com 			2,
977692d97c3Snir.tzachar@gmail.com 			(mwin_max_cols-maxx)/2);
978692d97c3Snir.tzachar@gmail.com 	keypad(menu_window, TRUE);
979692d97c3Snir.tzachar@gmail.com 	set_menu_win(curses_menu, menu_window);
980692d97c3Snir.tzachar@gmail.com 	set_menu_sub(curses_menu, menu_window);
981692d97c3Snir.tzachar@gmail.com 
982692d97c3Snir.tzachar@gmail.com 	/* must reassert this after changing items, otherwise returns to a
983692d97c3Snir.tzachar@gmail.com 	 * default of 16
984692d97c3Snir.tzachar@gmail.com 	 */
985692d97c3Snir.tzachar@gmail.com 	set_menu_format(curses_menu, maxy, 1);
986692d97c3Snir.tzachar@gmail.com 	center_item(selected_index, last_top_row);
987692d97c3Snir.tzachar@gmail.com 	set_menu_format(curses_menu, maxy, 1);
988692d97c3Snir.tzachar@gmail.com 
989692d97c3Snir.tzachar@gmail.com 	print_function_line();
990692d97c3Snir.tzachar@gmail.com 
991692d97c3Snir.tzachar@gmail.com 	/* Post the menu */
992692d97c3Snir.tzachar@gmail.com 	post_menu(curses_menu);
993692d97c3Snir.tzachar@gmail.com 	refresh_all_windows(main_window);
994692d97c3Snir.tzachar@gmail.com }
995692d97c3Snir.tzachar@gmail.com 
996a72f3e2bSNir Tzachar static void adj_match_dir(match_f *match_direction)
997a72f3e2bSNir Tzachar {
998a72f3e2bSNir Tzachar 	if (*match_direction == FIND_NEXT_MATCH_DOWN)
999a72f3e2bSNir Tzachar 		*match_direction =
1000a72f3e2bSNir Tzachar 			MATCH_TINKER_PATTERN_DOWN;
1001a72f3e2bSNir Tzachar 	else if (*match_direction == FIND_NEXT_MATCH_UP)
1002a72f3e2bSNir Tzachar 		*match_direction =
1003a72f3e2bSNir Tzachar 			MATCH_TINKER_PATTERN_UP;
1004a72f3e2bSNir Tzachar 	/* else, do no change.. */
1005a72f3e2bSNir Tzachar }
1006a72f3e2bSNir Tzachar 
1007a72f3e2bSNir Tzachar struct match_state
1008a72f3e2bSNir Tzachar {
1009a72f3e2bSNir Tzachar 	int in_search;
1010a72f3e2bSNir Tzachar 	match_f match_direction;
1011a72f3e2bSNir Tzachar 	char pattern[256];
1012a72f3e2bSNir Tzachar };
1013a72f3e2bSNir Tzachar 
1014a72f3e2bSNir Tzachar /* Return 0 means I have handled the key. In such a case, ans should hold the
1015a72f3e2bSNir Tzachar  * item to center, or -1 otherwise.
1016a72f3e2bSNir Tzachar  * Else return -1 .
1017a72f3e2bSNir Tzachar  */
1018a72f3e2bSNir Tzachar static int do_match(int key, struct match_state *state, int *ans)
1019a72f3e2bSNir Tzachar {
1020a72f3e2bSNir Tzachar 	char c = (char) key;
1021a72f3e2bSNir Tzachar 	int terminate_search = 0;
1022a72f3e2bSNir Tzachar 	*ans = -1;
1023a72f3e2bSNir Tzachar 	if (key == '/' || (state->in_search && key == 27)) {
1024a72f3e2bSNir Tzachar 		move(0, 0);
1025a72f3e2bSNir Tzachar 		refresh();
1026a72f3e2bSNir Tzachar 		clrtoeol();
1027a72f3e2bSNir Tzachar 		state->in_search = 1-state->in_search;
1028a72f3e2bSNir Tzachar 		bzero(state->pattern, sizeof(state->pattern));
1029a72f3e2bSNir Tzachar 		state->match_direction = MATCH_TINKER_PATTERN_DOWN;
1030a72f3e2bSNir Tzachar 		return 0;
1031a72f3e2bSNir Tzachar 	} else if (!state->in_search)
1032a72f3e2bSNir Tzachar 		return 1;
1033a72f3e2bSNir Tzachar 
1034a72f3e2bSNir Tzachar 	if (isalnum(c) || isgraph(c) || c == ' ') {
1035a72f3e2bSNir Tzachar 		state->pattern[strlen(state->pattern)] = c;
1036a72f3e2bSNir Tzachar 		state->pattern[strlen(state->pattern)] = '\0';
1037a72f3e2bSNir Tzachar 		adj_match_dir(&state->match_direction);
1038a72f3e2bSNir Tzachar 		*ans = get_mext_match(state->pattern,
1039a72f3e2bSNir Tzachar 				state->match_direction);
1040a72f3e2bSNir Tzachar 	} else if (key == KEY_DOWN) {
1041a72f3e2bSNir Tzachar 		state->match_direction = FIND_NEXT_MATCH_DOWN;
1042a72f3e2bSNir Tzachar 		*ans = get_mext_match(state->pattern,
1043a72f3e2bSNir Tzachar 				state->match_direction);
1044a72f3e2bSNir Tzachar 	} else if (key == KEY_UP) {
1045a72f3e2bSNir Tzachar 		state->match_direction = FIND_NEXT_MATCH_UP;
1046a72f3e2bSNir Tzachar 		*ans = get_mext_match(state->pattern,
1047a72f3e2bSNir Tzachar 				state->match_direction);
1048a72f3e2bSNir Tzachar 	} else if (key == KEY_BACKSPACE || key == 127) {
1049a72f3e2bSNir Tzachar 		state->pattern[strlen(state->pattern)-1] = '\0';
1050a72f3e2bSNir Tzachar 		adj_match_dir(&state->match_direction);
1051a72f3e2bSNir Tzachar 	} else
1052a72f3e2bSNir Tzachar 		terminate_search = 1;
1053a72f3e2bSNir Tzachar 
1054a72f3e2bSNir Tzachar 	if (terminate_search) {
1055a72f3e2bSNir Tzachar 		state->in_search = 0;
1056a72f3e2bSNir Tzachar 		bzero(state->pattern, sizeof(state->pattern));
1057a72f3e2bSNir Tzachar 		move(0, 0);
1058a72f3e2bSNir Tzachar 		refresh();
1059a72f3e2bSNir Tzachar 		clrtoeol();
1060a72f3e2bSNir Tzachar 		return -1;
1061a72f3e2bSNir Tzachar 	}
1062a72f3e2bSNir Tzachar 	return 0;
1063a72f3e2bSNir Tzachar }
1064692d97c3Snir.tzachar@gmail.com 
1065692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu)
1066692d97c3Snir.tzachar@gmail.com {
1067692d97c3Snir.tzachar@gmail.com 	struct menu *submenu = 0;
1068692d97c3Snir.tzachar@gmail.com 	const char *prompt = menu_get_prompt(menu);
1069692d97c3Snir.tzachar@gmail.com 	struct symbol *sym;
1070692d97c3Snir.tzachar@gmail.com 	int res;
1071692d97c3Snir.tzachar@gmail.com 	int current_index = 0;
1072692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1073a72f3e2bSNir Tzachar 	struct match_state match_state = {
1074a72f3e2bSNir Tzachar 		.in_search = 0,
1075a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1076a72f3e2bSNir Tzachar 		.pattern = "",
1077a72f3e2bSNir Tzachar 	};
1078692d97c3Snir.tzachar@gmail.com 
1079692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1080692d97c3Snir.tzachar@gmail.com 		reset_menu();
1081692d97c3Snir.tzachar@gmail.com 		current_menu = menu;
1082692d97c3Snir.tzachar@gmail.com 		build_conf(menu);
1083692d97c3Snir.tzachar@gmail.com 		if (!child_count)
1084692d97c3Snir.tzachar@gmail.com 			break;
1085692d97c3Snir.tzachar@gmail.com 
1086692d97c3Snir.tzachar@gmail.com 		show_menu(prompt ? _(prompt) : _("Main Menu"),
1087692d97c3Snir.tzachar@gmail.com 				_(menu_instructions),
1088692d97c3Snir.tzachar@gmail.com 				current_index, &last_top_row);
1089692d97c3Snir.tzachar@gmail.com 		keypad((menu_win(curses_menu)), TRUE);
1090a72f3e2bSNir Tzachar 		while (!global_exit) {
1091a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1092a72f3e2bSNir Tzachar 				mvprintw(0, 0,
1093a72f3e2bSNir Tzachar 					"searching: %s", match_state.pattern);
1094a72f3e2bSNir Tzachar 				clrtoeol();
1095a72f3e2bSNir Tzachar 			}
1096a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1097a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1098a72f3e2bSNir Tzachar 			if (!res)
1099a72f3e2bSNir Tzachar 				break;
1100a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &current_index) == 0) {
1101a72f3e2bSNir Tzachar 				if (current_index != -1)
1102a72f3e2bSNir Tzachar 					center_item(current_index,
1103a72f3e2bSNir Tzachar 						    &last_top_row);
1104a72f3e2bSNir Tzachar 				continue;
1105a72f3e2bSNir Tzachar 			}
1106692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(&res,
1107692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1108692d97c3Snir.tzachar@gmail.com 				break;
1109692d97c3Snir.tzachar@gmail.com 			switch (res) {
1110692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
1111692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1112692d97c3Snir.tzachar@gmail.com 				break;
1113692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
1114692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1115692d97c3Snir.tzachar@gmail.com 				break;
1116692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1117692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1118692d97c3Snir.tzachar@gmail.com 				break;
1119692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1120692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1121692d97c3Snir.tzachar@gmail.com 				break;
1122692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1123692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1124692d97c3Snir.tzachar@gmail.com 				break;
1125692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1126692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1127692d97c3Snir.tzachar@gmail.com 				break;
1128692d97c3Snir.tzachar@gmail.com 			case 'h':
1129692d97c3Snir.tzachar@gmail.com 			case '?':
1130692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1131692d97c3Snir.tzachar@gmail.com 				break;
1132692d97c3Snir.tzachar@gmail.com 			}
1133692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 ||
1134692d97c3Snir.tzachar@gmail.com 				res == 32 || res == 'n' || res == 'y' ||
1135692d97c3Snir.tzachar@gmail.com 				res == KEY_LEFT || res == KEY_RIGHT ||
1136a72f3e2bSNir Tzachar 				res == 'm')
1137692d97c3Snir.tzachar@gmail.com 				break;
1138692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1139692d97c3Snir.tzachar@gmail.com 		}
1140692d97c3Snir.tzachar@gmail.com 
1141692d97c3Snir.tzachar@gmail.com 		refresh_all_windows(main_window);
1142692d97c3Snir.tzachar@gmail.com 		/* if ESC or left*/
1143692d97c3Snir.tzachar@gmail.com 		if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1144692d97c3Snir.tzachar@gmail.com 			break;
1145692d97c3Snir.tzachar@gmail.com 
1146692d97c3Snir.tzachar@gmail.com 		/* remember location in the menu */
1147692d97c3Snir.tzachar@gmail.com 		last_top_row = top_row(curses_menu);
1148692d97c3Snir.tzachar@gmail.com 		current_index = curses_item_index();
1149692d97c3Snir.tzachar@gmail.com 
1150692d97c3Snir.tzachar@gmail.com 		if (!item_tag())
1151692d97c3Snir.tzachar@gmail.com 			continue;
1152692d97c3Snir.tzachar@gmail.com 
1153692d97c3Snir.tzachar@gmail.com 		submenu = (struct menu *) item_data();
1154692d97c3Snir.tzachar@gmail.com 		if (!submenu || !menu_is_visible(submenu))
1155692d97c3Snir.tzachar@gmail.com 			continue;
1156692d97c3Snir.tzachar@gmail.com 		sym = submenu->sym;
1157692d97c3Snir.tzachar@gmail.com 
1158692d97c3Snir.tzachar@gmail.com 		switch (res) {
1159692d97c3Snir.tzachar@gmail.com 		case ' ':
1160692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1161692d97c3Snir.tzachar@gmail.com 				sym_toggle_tristate_value(sym);
1162692d97c3Snir.tzachar@gmail.com 			else if (item_is_tag('m'))
1163692d97c3Snir.tzachar@gmail.com 				conf(submenu);
1164692d97c3Snir.tzachar@gmail.com 			break;
1165692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1166692d97c3Snir.tzachar@gmail.com 		case 10: /* ENTER WAS PRESSED */
1167692d97c3Snir.tzachar@gmail.com 			switch (item_tag()) {
1168692d97c3Snir.tzachar@gmail.com 			case 'm':
1169692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode)
1170692d97c3Snir.tzachar@gmail.com 					submenu->data =
1171692d97c3Snir.tzachar@gmail.com 						(void *) (long) !submenu->data;
1172692d97c3Snir.tzachar@gmail.com 				else
1173692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1174692d97c3Snir.tzachar@gmail.com 				break;
1175692d97c3Snir.tzachar@gmail.com 			case 't':
1176692d97c3Snir.tzachar@gmail.com 				if (sym_is_choice(sym) &&
1177692d97c3Snir.tzachar@gmail.com 				    sym_get_tristate_value(sym) == yes)
1178692d97c3Snir.tzachar@gmail.com 					conf_choice(submenu);
1179692d97c3Snir.tzachar@gmail.com 				else if (submenu->prompt &&
1180692d97c3Snir.tzachar@gmail.com 					 submenu->prompt->type == P_MENU)
1181692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1182692d97c3Snir.tzachar@gmail.com 				else if (res == 10)
1183692d97c3Snir.tzachar@gmail.com 					sym_toggle_tristate_value(sym);
1184692d97c3Snir.tzachar@gmail.com 				break;
1185692d97c3Snir.tzachar@gmail.com 			case 's':
1186692d97c3Snir.tzachar@gmail.com 				conf_string(submenu);
1187692d97c3Snir.tzachar@gmail.com 				break;
1188692d97c3Snir.tzachar@gmail.com 			}
1189692d97c3Snir.tzachar@gmail.com 			break;
1190692d97c3Snir.tzachar@gmail.com 		case 'y':
1191692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t')) {
1192692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, yes))
1193692d97c3Snir.tzachar@gmail.com 					break;
1194692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, mod))
1195692d97c3Snir.tzachar@gmail.com 					btn_dialog(main_window, setmod_text, 0);
1196692d97c3Snir.tzachar@gmail.com 			}
1197692d97c3Snir.tzachar@gmail.com 			break;
1198692d97c3Snir.tzachar@gmail.com 		case 'n':
1199692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1200692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, no);
1201692d97c3Snir.tzachar@gmail.com 			break;
1202692d97c3Snir.tzachar@gmail.com 		case 'm':
1203692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1204692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, mod);
1205692d97c3Snir.tzachar@gmail.com 			break;
1206692d97c3Snir.tzachar@gmail.com 		}
1207692d97c3Snir.tzachar@gmail.com 	}
1208692d97c3Snir.tzachar@gmail.com }
1209692d97c3Snir.tzachar@gmail.com 
121042368c37SMichal Marek static void conf_message_callback(const char *fmt, va_list ap)
121142368c37SMichal Marek {
121242368c37SMichal Marek 	char buf[1024];
121342368c37SMichal Marek 
121442368c37SMichal Marek 	vsnprintf(buf, sizeof(buf), fmt, ap);
121542368c37SMichal Marek 	btn_dialog(main_window, buf, 1, "<OK>");
121642368c37SMichal Marek }
121742368c37SMichal Marek 
1218692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu)
1219692d97c3Snir.tzachar@gmail.com {
1220f98ee769SArnaud Lacombe 	struct gstr help;
1221f98ee769SArnaud Lacombe 
1222f98ee769SArnaud Lacombe 	if (!menu)
1223f98ee769SArnaud Lacombe 		return;
1224f98ee769SArnaud Lacombe 
1225f98ee769SArnaud Lacombe 	help = str_new();
122654168578SArnaud Lacombe 	menu_get_ext_help(menu, &help);
1227692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1228692d97c3Snir.tzachar@gmail.com 	str_free(&help);
1229692d97c3Snir.tzachar@gmail.com }
1230692d97c3Snir.tzachar@gmail.com 
1231692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu)
1232692d97c3Snir.tzachar@gmail.com {
1233692d97c3Snir.tzachar@gmail.com 	const char *prompt = _(menu_get_prompt(menu));
1234692d97c3Snir.tzachar@gmail.com 	struct menu *child = 0;
1235692d97c3Snir.tzachar@gmail.com 	struct symbol *active;
1236692d97c3Snir.tzachar@gmail.com 	int selected_index = 0;
1237692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1238692d97c3Snir.tzachar@gmail.com 	int res, i = 0;
1239a72f3e2bSNir Tzachar 	struct match_state match_state = {
1240a72f3e2bSNir Tzachar 		.in_search = 0,
1241a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1242a72f3e2bSNir Tzachar 		.pattern = "",
1243a72f3e2bSNir Tzachar 	};
1244692d97c3Snir.tzachar@gmail.com 
1245692d97c3Snir.tzachar@gmail.com 	active = sym_get_choice_value(menu->sym);
1246692d97c3Snir.tzachar@gmail.com 	/* this is mostly duplicated from the conf() function. */
1247692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1248692d97c3Snir.tzachar@gmail.com 		reset_menu();
1249692d97c3Snir.tzachar@gmail.com 
1250692d97c3Snir.tzachar@gmail.com 		for (i = 0, child = menu->list; child; child = child->next) {
1251692d97c3Snir.tzachar@gmail.com 			if (!show_all_items && !menu_is_visible(child))
1252692d97c3Snir.tzachar@gmail.com 				continue;
1253692d97c3Snir.tzachar@gmail.com 
1254692d97c3Snir.tzachar@gmail.com 			if (child->sym == sym_get_choice_value(menu->sym))
1255692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "<X> %s",
1256692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(child)));
125739177ec3SPeter Korsgaard 			else if (child->sym)
1258692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "    %s",
1259692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(child)));
126039177ec3SPeter Korsgaard 			else
126139177ec3SPeter Korsgaard 				item_make(child, ':', "*** %s ***",
126239177ec3SPeter Korsgaard 						_(menu_get_prompt(child)));
126339177ec3SPeter Korsgaard 
1264692d97c3Snir.tzachar@gmail.com 			if (child->sym == active){
1265692d97c3Snir.tzachar@gmail.com 				last_top_row = top_row(curses_menu);
1266692d97c3Snir.tzachar@gmail.com 				selected_index = i;
1267692d97c3Snir.tzachar@gmail.com 			}
1268692d97c3Snir.tzachar@gmail.com 			i++;
1269692d97c3Snir.tzachar@gmail.com 		}
1270692d97c3Snir.tzachar@gmail.com 		show_menu(prompt ? _(prompt) : _("Choice Menu"),
1271692d97c3Snir.tzachar@gmail.com 				_(radiolist_instructions),
1272692d97c3Snir.tzachar@gmail.com 				selected_index,
1273692d97c3Snir.tzachar@gmail.com 				&last_top_row);
1274a72f3e2bSNir Tzachar 		while (!global_exit) {
1275a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1276a72f3e2bSNir Tzachar 				mvprintw(0, 0, "searching: %s",
1277a72f3e2bSNir Tzachar 					 match_state.pattern);
1278a72f3e2bSNir Tzachar 				clrtoeol();
1279a72f3e2bSNir Tzachar 			}
1280a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1281a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1282a72f3e2bSNir Tzachar 			if (!res)
1283a72f3e2bSNir Tzachar 				break;
1284a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &selected_index) == 0) {
1285a72f3e2bSNir Tzachar 				if (selected_index != -1)
1286a72f3e2bSNir Tzachar 					center_item(selected_index,
1287a72f3e2bSNir Tzachar 						    &last_top_row);
1288a72f3e2bSNir Tzachar 				continue;
1289a72f3e2bSNir Tzachar 			}
1290692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(
1291692d97c3Snir.tzachar@gmail.com 						&res,
1292692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1293692d97c3Snir.tzachar@gmail.com 				break;
1294692d97c3Snir.tzachar@gmail.com 			switch (res) {
1295692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
1296692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1297692d97c3Snir.tzachar@gmail.com 				break;
1298692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
1299692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1300692d97c3Snir.tzachar@gmail.com 				break;
1301692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1302692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1303692d97c3Snir.tzachar@gmail.com 				break;
1304692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1305692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1306692d97c3Snir.tzachar@gmail.com 				break;
1307692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1308692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1309692d97c3Snir.tzachar@gmail.com 				break;
1310692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1311692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1312692d97c3Snir.tzachar@gmail.com 				break;
1313692d97c3Snir.tzachar@gmail.com 			case 'h':
1314692d97c3Snir.tzachar@gmail.com 			case '?':
1315692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1316692d97c3Snir.tzachar@gmail.com 				break;
1317692d97c3Snir.tzachar@gmail.com 			}
1318692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 || res == ' ' ||
1319a72f3e2bSNir Tzachar 					res == KEY_LEFT){
1320692d97c3Snir.tzachar@gmail.com 				break;
1321692d97c3Snir.tzachar@gmail.com 			}
1322692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1323692d97c3Snir.tzachar@gmail.com 		}
1324692d97c3Snir.tzachar@gmail.com 		/* if ESC or left */
1325692d97c3Snir.tzachar@gmail.com 		if (res == 27 || res == KEY_LEFT)
1326692d97c3Snir.tzachar@gmail.com 			break;
1327692d97c3Snir.tzachar@gmail.com 
1328692d97c3Snir.tzachar@gmail.com 		child = item_data();
132939177ec3SPeter Korsgaard 		if (!child || !menu_is_visible(child) || !child->sym)
1330692d97c3Snir.tzachar@gmail.com 			continue;
1331692d97c3Snir.tzachar@gmail.com 		switch (res) {
1332692d97c3Snir.tzachar@gmail.com 		case ' ':
1333692d97c3Snir.tzachar@gmail.com 		case  10:
1334692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1335692d97c3Snir.tzachar@gmail.com 			sym_set_tristate_value(child->sym, yes);
1336692d97c3Snir.tzachar@gmail.com 			return;
1337692d97c3Snir.tzachar@gmail.com 		case 'h':
1338692d97c3Snir.tzachar@gmail.com 		case '?':
1339692d97c3Snir.tzachar@gmail.com 			show_help(child);
1340692d97c3Snir.tzachar@gmail.com 			active = child->sym;
1341692d97c3Snir.tzachar@gmail.com 			break;
1342692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1343692d97c3Snir.tzachar@gmail.com 			return;
1344692d97c3Snir.tzachar@gmail.com 		}
1345692d97c3Snir.tzachar@gmail.com 	}
1346692d97c3Snir.tzachar@gmail.com }
1347692d97c3Snir.tzachar@gmail.com 
1348692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu)
1349692d97c3Snir.tzachar@gmail.com {
1350692d97c3Snir.tzachar@gmail.com 	const char *prompt = menu_get_prompt(menu);
1351692d97c3Snir.tzachar@gmail.com 
1352692d97c3Snir.tzachar@gmail.com 	while (1) {
1353692d97c3Snir.tzachar@gmail.com 		int res;
1354692d97c3Snir.tzachar@gmail.com 		const char *heading;
1355692d97c3Snir.tzachar@gmail.com 
1356692d97c3Snir.tzachar@gmail.com 		switch (sym_get_type(menu->sym)) {
1357692d97c3Snir.tzachar@gmail.com 		case S_INT:
1358692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_int);
1359692d97c3Snir.tzachar@gmail.com 			break;
1360692d97c3Snir.tzachar@gmail.com 		case S_HEX:
1361692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_hex);
1362692d97c3Snir.tzachar@gmail.com 			break;
1363692d97c3Snir.tzachar@gmail.com 		case S_STRING:
1364692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_string);
1365692d97c3Snir.tzachar@gmail.com 			break;
1366692d97c3Snir.tzachar@gmail.com 		default:
1367692d97c3Snir.tzachar@gmail.com 			heading = _("Internal nconf error!");
1368692d97c3Snir.tzachar@gmail.com 		}
1369692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1370692d97c3Snir.tzachar@gmail.com 				prompt ? _(prompt) : _("Main Menu"),
1371692d97c3Snir.tzachar@gmail.com 				heading,
1372692d97c3Snir.tzachar@gmail.com 				sym_get_string_value(menu->sym),
13735ea9f64fSCheng Renquan 				&dialog_input_result,
13745ea9f64fSCheng Renquan 				&dialog_input_result_len);
1375692d97c3Snir.tzachar@gmail.com 		switch (res) {
1376692d97c3Snir.tzachar@gmail.com 		case 0:
1377692d97c3Snir.tzachar@gmail.com 			if (sym_set_string_value(menu->sym,
1378692d97c3Snir.tzachar@gmail.com 						dialog_input_result))
1379692d97c3Snir.tzachar@gmail.com 				return;
1380692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window,
1381692d97c3Snir.tzachar@gmail.com 				_("You have made an invalid entry."), 0);
1382692d97c3Snir.tzachar@gmail.com 			break;
1383692d97c3Snir.tzachar@gmail.com 		case 1:
1384692d97c3Snir.tzachar@gmail.com 			show_help(menu);
1385692d97c3Snir.tzachar@gmail.com 			break;
1386692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1387692d97c3Snir.tzachar@gmail.com 			return;
1388692d97c3Snir.tzachar@gmail.com 		}
1389692d97c3Snir.tzachar@gmail.com 	}
1390692d97c3Snir.tzachar@gmail.com }
1391692d97c3Snir.tzachar@gmail.com 
1392692d97c3Snir.tzachar@gmail.com static void conf_load(void)
1393692d97c3Snir.tzachar@gmail.com {
1394692d97c3Snir.tzachar@gmail.com 	while (1) {
1395692d97c3Snir.tzachar@gmail.com 		int res;
1396692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1397692d97c3Snir.tzachar@gmail.com 				NULL, load_config_text,
1398692d97c3Snir.tzachar@gmail.com 				filename,
13995ea9f64fSCheng Renquan 				&dialog_input_result,
14005ea9f64fSCheng Renquan 				&dialog_input_result_len);
1401692d97c3Snir.tzachar@gmail.com 		switch (res) {
1402692d97c3Snir.tzachar@gmail.com 		case 0:
1403692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1404692d97c3Snir.tzachar@gmail.com 				return;
1405692d97c3Snir.tzachar@gmail.com 			if (!conf_read(dialog_input_result)) {
1406692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
1407692d97c3Snir.tzachar@gmail.com 				sym_set_change_count(1);
1408692d97c3Snir.tzachar@gmail.com 				return;
1409692d97c3Snir.tzachar@gmail.com 			}
1410692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window, _("File does not exist!"), 0);
1411692d97c3Snir.tzachar@gmail.com 			break;
1412692d97c3Snir.tzachar@gmail.com 		case 1:
1413692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1414692d97c3Snir.tzachar@gmail.com 					_("Load Alternate Configuration"),
1415692d97c3Snir.tzachar@gmail.com 					load_config_help);
1416692d97c3Snir.tzachar@gmail.com 			break;
1417692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1418692d97c3Snir.tzachar@gmail.com 			return;
1419692d97c3Snir.tzachar@gmail.com 		}
1420692d97c3Snir.tzachar@gmail.com 	}
1421692d97c3Snir.tzachar@gmail.com }
1422692d97c3Snir.tzachar@gmail.com 
1423692d97c3Snir.tzachar@gmail.com static void conf_save(void)
1424692d97c3Snir.tzachar@gmail.com {
1425692d97c3Snir.tzachar@gmail.com 	while (1) {
1426692d97c3Snir.tzachar@gmail.com 		int res;
1427692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1428692d97c3Snir.tzachar@gmail.com 				NULL, save_config_text,
1429692d97c3Snir.tzachar@gmail.com 				filename,
14305ea9f64fSCheng Renquan 				&dialog_input_result,
14315ea9f64fSCheng Renquan 				&dialog_input_result_len);
1432692d97c3Snir.tzachar@gmail.com 		switch (res) {
1433692d97c3Snir.tzachar@gmail.com 		case 0:
1434692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1435692d97c3Snir.tzachar@gmail.com 				return;
1436692d97c3Snir.tzachar@gmail.com 			res = conf_write(dialog_input_result);
1437692d97c3Snir.tzachar@gmail.com 			if (!res) {
1438692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
1439692d97c3Snir.tzachar@gmail.com 				return;
1440692d97c3Snir.tzachar@gmail.com 			}
1441692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window, _("Can't create file! "
1442692d97c3Snir.tzachar@gmail.com 				"Probably a nonexistent directory."),
1443692d97c3Snir.tzachar@gmail.com 				1, "<OK>");
1444692d97c3Snir.tzachar@gmail.com 			break;
1445692d97c3Snir.tzachar@gmail.com 		case 1:
1446692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1447692d97c3Snir.tzachar@gmail.com 				_("Save Alternate Configuration"),
1448692d97c3Snir.tzachar@gmail.com 				save_config_help);
1449692d97c3Snir.tzachar@gmail.com 			break;
1450692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1451692d97c3Snir.tzachar@gmail.com 			return;
1452692d97c3Snir.tzachar@gmail.com 		}
1453692d97c3Snir.tzachar@gmail.com 	}
1454692d97c3Snir.tzachar@gmail.com }
1455692d97c3Snir.tzachar@gmail.com 
1456692d97c3Snir.tzachar@gmail.com void setup_windows(void)
1457692d97c3Snir.tzachar@gmail.com {
1458692d97c3Snir.tzachar@gmail.com 	if (main_window != NULL)
1459692d97c3Snir.tzachar@gmail.com 		delwin(main_window);
1460692d97c3Snir.tzachar@gmail.com 
1461692d97c3Snir.tzachar@gmail.com 	/* set up the menu and menu window */
1462692d97c3Snir.tzachar@gmail.com 	main_window = newwin(LINES-2, COLS-2, 2, 1);
1463692d97c3Snir.tzachar@gmail.com 	keypad(main_window, TRUE);
1464a72f3e2bSNir Tzachar 	mwin_max_lines = LINES-7;
1465692d97c3Snir.tzachar@gmail.com 	mwin_max_cols = COLS-6;
1466692d97c3Snir.tzachar@gmail.com 
1467692d97c3Snir.tzachar@gmail.com 	/* panels order is from bottom to top */
1468692d97c3Snir.tzachar@gmail.com 	new_panel(main_window);
1469692d97c3Snir.tzachar@gmail.com }
1470692d97c3Snir.tzachar@gmail.com 
1471692d97c3Snir.tzachar@gmail.com int main(int ac, char **av)
1472692d97c3Snir.tzachar@gmail.com {
1473692d97c3Snir.tzachar@gmail.com 	char *mode;
1474692d97c3Snir.tzachar@gmail.com 
1475692d97c3Snir.tzachar@gmail.com 	setlocale(LC_ALL, "");
1476692d97c3Snir.tzachar@gmail.com 	bindtextdomain(PACKAGE, LOCALEDIR);
1477692d97c3Snir.tzachar@gmail.com 	textdomain(PACKAGE);
1478692d97c3Snir.tzachar@gmail.com 
1479692d97c3Snir.tzachar@gmail.com 	conf_parse(av[1]);
1480692d97c3Snir.tzachar@gmail.com 	conf_read(NULL);
1481692d97c3Snir.tzachar@gmail.com 
1482692d97c3Snir.tzachar@gmail.com 	mode = getenv("NCONFIG_MODE");
1483692d97c3Snir.tzachar@gmail.com 	if (mode) {
1484692d97c3Snir.tzachar@gmail.com 		if (!strcasecmp(mode, "single_menu"))
1485692d97c3Snir.tzachar@gmail.com 			single_menu_mode = 1;
1486692d97c3Snir.tzachar@gmail.com 	}
1487692d97c3Snir.tzachar@gmail.com 
1488692d97c3Snir.tzachar@gmail.com 	/* Initialize curses */
1489692d97c3Snir.tzachar@gmail.com 	initscr();
1490692d97c3Snir.tzachar@gmail.com 	/* set color theme */
1491692d97c3Snir.tzachar@gmail.com 	set_colors();
1492692d97c3Snir.tzachar@gmail.com 
1493692d97c3Snir.tzachar@gmail.com 	cbreak();
1494692d97c3Snir.tzachar@gmail.com 	noecho();
1495692d97c3Snir.tzachar@gmail.com 	keypad(stdscr, TRUE);
1496692d97c3Snir.tzachar@gmail.com 	curs_set(0);
1497692d97c3Snir.tzachar@gmail.com 
1498692d97c3Snir.tzachar@gmail.com 	if (COLS < 75 || LINES < 20) {
1499692d97c3Snir.tzachar@gmail.com 		endwin();
1500692d97c3Snir.tzachar@gmail.com 		printf("Your terminal should have at "
1501692d97c3Snir.tzachar@gmail.com 			"least 20 lines and 75 columns\n");
1502692d97c3Snir.tzachar@gmail.com 		return 1;
1503692d97c3Snir.tzachar@gmail.com 	}
1504692d97c3Snir.tzachar@gmail.com 
1505692d97c3Snir.tzachar@gmail.com 	notimeout(stdscr, FALSE);
1506d7c67a2eSYaakov Selkowitz #if NCURSES_REENTRANT
1507d7c67a2eSYaakov Selkowitz 	set_escdelay(1);
1508d7c67a2eSYaakov Selkowitz #else
1509692d97c3Snir.tzachar@gmail.com 	ESCDELAY = 1;
1510d7c67a2eSYaakov Selkowitz #endif
1511692d97c3Snir.tzachar@gmail.com 
1512692d97c3Snir.tzachar@gmail.com 	/* set btns menu */
1513692d97c3Snir.tzachar@gmail.com 	curses_menu = new_menu(curses_menu_items);
1514692d97c3Snir.tzachar@gmail.com 	menu_opts_off(curses_menu, O_SHOWDESC);
1515a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_SHOWMATCH);
1516692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_ONEVALUE);
1517692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_NONCYCLIC);
1518a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_IGNORECASE);
1519692d97c3Snir.tzachar@gmail.com 	set_menu_mark(curses_menu, " ");
1520692d97c3Snir.tzachar@gmail.com 	set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1521692d97c3Snir.tzachar@gmail.com 	set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1522692d97c3Snir.tzachar@gmail.com 	set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1523692d97c3Snir.tzachar@gmail.com 
1524692d97c3Snir.tzachar@gmail.com 	set_config_filename(conf_get_configname());
1525692d97c3Snir.tzachar@gmail.com 	setup_windows();
1526692d97c3Snir.tzachar@gmail.com 
1527692d97c3Snir.tzachar@gmail.com 	/* check for KEY_FUNC(1) */
1528692d97c3Snir.tzachar@gmail.com 	if (has_key(KEY_F(1)) == FALSE) {
1529692d97c3Snir.tzachar@gmail.com 		show_scroll_win(main_window,
1530692d97c3Snir.tzachar@gmail.com 				_("Instructions"),
1531692d97c3Snir.tzachar@gmail.com 				_(menu_no_f_instructions));
1532692d97c3Snir.tzachar@gmail.com 	}
1533692d97c3Snir.tzachar@gmail.com 
153442368c37SMichal Marek 	conf_set_message_callback(conf_message_callback);
1535692d97c3Snir.tzachar@gmail.com 	/* do the work */
1536692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1537692d97c3Snir.tzachar@gmail.com 		conf(&rootmenu);
1538692d97c3Snir.tzachar@gmail.com 		if (!global_exit && do_exit() == 0)
1539692d97c3Snir.tzachar@gmail.com 			break;
1540692d97c3Snir.tzachar@gmail.com 	}
1541692d97c3Snir.tzachar@gmail.com 	/* ok, we are done */
1542692d97c3Snir.tzachar@gmail.com 	unpost_menu(curses_menu);
1543692d97c3Snir.tzachar@gmail.com 	free_menu(curses_menu);
1544692d97c3Snir.tzachar@gmail.com 	delwin(main_window);
1545692d97c3Snir.tzachar@gmail.com 	clear();
1546692d97c3Snir.tzachar@gmail.com 	refresh();
1547692d97c3Snir.tzachar@gmail.com 	endwin();
1548692d97c3Snir.tzachar@gmail.com 	return 0;
1549692d97c3Snir.tzachar@gmail.com }
1550692d97c3Snir.tzachar@gmail.com 
1551