xref: /linux/scripts/kconfig/nconf.c (revision ff9a79307f89563da6d841da8b7cc4a0afceb0e2)
10c874100SMasahiro Yamada // SPDX-License-Identifier: GPL-2.0
2692d97c3Snir.tzachar@gmail.com /*
30c874100SMasahiro Yamada  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com>
4692d97c3Snir.tzachar@gmail.com  *
5692d97c3Snir.tzachar@gmail.com  * Derived from menuconfig.
6692d97c3Snir.tzachar@gmail.com  */
70eb47346SCheah Kok Cheong #ifndef _GNU_SOURCE
8a72f3e2bSNir Tzachar #define _GNU_SOURCE
90eb47346SCheah Kok Cheong #endif
10a72f3e2bSNir Tzachar #include <string.h>
11ba82f52eSBartosz Golaszewski #include <strings.h>
129a926d43SYann E. MORIN #include <stdlib.h>
135a6f8d2bSArnaud Lacombe 
144dae9cf5SMasahiro Yamada #include "list.h"
15692d97c3Snir.tzachar@gmail.com #include "lkc.h"
166c07fd84SMasahiro Yamada #include "mnconf-common.h"
17692d97c3Snir.tzachar@gmail.com #include "nconf.h"
18a72f3e2bSNir Tzachar #include <ctype.h>
19692d97c3Snir.tzachar@gmail.com 
20694c49a7SSam Ravnborg static const char nconf_global_help[] =
210b616500SRoland Eggner "Help windows\n"
220b616500SRoland Eggner "------------\n"
230b616500SRoland Eggner "o  Global help:  Unless in a data entry window, pressing <F1> will give \n"
240b616500SRoland Eggner "   you the global help window, which you are just reading.\n"
25692d97c3Snir.tzachar@gmail.com "\n"
260b616500SRoland Eggner "o  A short version of the global help is available by pressing <F3>.\n"
270b616500SRoland Eggner "\n"
280b616500SRoland Eggner "o  Local help:  To get help related to the current menu entry, use any\n"
290b616500SRoland Eggner "   of <?> <h>, or if in a data entry window then press <F1>.\n"
300b616500SRoland Eggner "\n"
310b616500SRoland Eggner "\n"
320b616500SRoland Eggner "Menu entries\n"
330b616500SRoland Eggner "------------\n"
340b616500SRoland Eggner "This interface lets you select features and parameters for the kernel\n"
350b616500SRoland Eggner "build.  Kernel features can either be built-in, modularized, or removed.\n"
360b616500SRoland Eggner "Parameters must be entered as text or decimal or hexadecimal numbers.\n"
370b616500SRoland Eggner "\n"
380b616500SRoland Eggner "Menu entries beginning with following braces represent features that\n"
39692d97c3Snir.tzachar@gmail.com "  [ ]  can be built in or removed\n"
40692d97c3Snir.tzachar@gmail.com "  < >  can be built in, modularized or removed\n"
410b616500SRoland Eggner "  { }  can be built in or modularized, are selected by another feature\n"
420b616500SRoland Eggner "  - -  are selected by another feature\n"
430b616500SRoland Eggner "  XXX  cannot be selected.  Symbol Info <F2> tells you why.\n"
440b616500SRoland Eggner "*, M or whitespace inside braces means to build in, build as a module\n"
450b616500SRoland Eggner "or to exclude the feature respectively.\n"
46692d97c3Snir.tzachar@gmail.com "\n"
470b616500SRoland Eggner "To change any of these features, highlight it with the movement keys\n"
480b616500SRoland Eggner "listed below and press <y> to build it in, <m> to make it a module or\n"
490b616500SRoland Eggner "<n> to remove it.  You may press the <Space> key to cycle through the\n"
500b616500SRoland Eggner "available options.\n"
51692d97c3Snir.tzachar@gmail.com "\n"
521278ebdbSDirk Gouders "A trailing \"--->\" designates a submenu, a trailing \"----\" an\n"
531278ebdbSDirk Gouders "empty submenu.\n"
540b616500SRoland Eggner "\n"
550b616500SRoland Eggner "Menu navigation keys\n"
560b616500SRoland Eggner "----------------------------------------------------------------------\n"
572bbb4861SIsak Ellmer "Linewise up                 <Up>    <k>\n"
582bbb4861SIsak Ellmer "Linewise down               <Down>  <j>\n"
590b616500SRoland Eggner "Pagewise up                 <Page Up>\n"
600b616500SRoland Eggner "Pagewise down               <Page Down>\n"
610b616500SRoland Eggner "First entry                 <Home>\n"
620b616500SRoland Eggner "Last entry                  <End>\n"
630b616500SRoland Eggner "Enter a submenu             <Right>  <Enter>\n"
640b616500SRoland Eggner "Go back to parent menu      <Left>   <Esc>  <F5>\n"
650b616500SRoland Eggner "Close a help window         <Enter>  <Esc>  <F5>\n"
660b616500SRoland Eggner "Close entry window, apply   <Enter>\n"
670b616500SRoland Eggner "Close entry window, forget  <Esc>  <F5>\n"
680b616500SRoland Eggner "Start incremental, case-insensitive search for STRING in menu entries,\n"
690b616500SRoland Eggner "    no regex support, STRING is displayed in upper left corner\n"
700b616500SRoland Eggner "                            </>STRING\n"
710b616500SRoland Eggner "    Remove last character   <Backspace>\n"
720b616500SRoland Eggner "    Jump to next hit        <Down>\n"
730b616500SRoland Eggner "    Jump to previous hit    <Up>\n"
740b616500SRoland Eggner "Exit menu search mode       </>  <Esc>\n"
750b616500SRoland Eggner "Search for configuration variables with or without leading CONFIG_\n"
760b616500SRoland Eggner "                            <F8>RegExpr<Enter>\n"
770b616500SRoland Eggner "Verbose search help         <F8><F1>\n"
780b616500SRoland Eggner "----------------------------------------------------------------------\n"
790b616500SRoland Eggner "\n"
800b616500SRoland Eggner "Unless in a data entry window, key <1> may be used instead of <F1>,\n"
810b616500SRoland Eggner "<2> instead of <F2>, etc.\n"
820b616500SRoland Eggner "\n"
830b616500SRoland Eggner "\n"
840b616500SRoland Eggner "Radiolist (Choice list)\n"
850b616500SRoland Eggner "-----------------------\n"
860b616500SRoland Eggner "Use the movement keys listed above to select the option you wish to set\n"
870b616500SRoland Eggner "and press <Space>.\n"
880b616500SRoland Eggner "\n"
890b616500SRoland Eggner "\n"
900b616500SRoland Eggner "Data entry\n"
91692d97c3Snir.tzachar@gmail.com "----------\n"
920b616500SRoland Eggner "Enter the requested information and press <Enter>.  Hexadecimal values\n"
930b616500SRoland Eggner "may be entered without the \"0x\" prefix.\n"
94692d97c3Snir.tzachar@gmail.com "\n"
95692d97c3Snir.tzachar@gmail.com "\n"
96692d97c3Snir.tzachar@gmail.com "Text Box (Help Window)\n"
970b616500SRoland Eggner "----------------------\n"
980b616500SRoland Eggner "Use movement keys as listed in table above.\n"
99692d97c3Snir.tzachar@gmail.com "\n"
1000b616500SRoland Eggner "Press any of <Enter> <Esc> <q> <F5> <F9> to exit.\n"
101692d97c3Snir.tzachar@gmail.com "\n"
102692d97c3Snir.tzachar@gmail.com "\n"
1030b616500SRoland Eggner "Alternate configuration files\n"
104692d97c3Snir.tzachar@gmail.com "-----------------------------\n"
1050b616500SRoland Eggner "nconfig supports switching between different configurations.\n"
1060b616500SRoland Eggner "Press <F6> to save your current configuration.  Press <F7> and enter\n"
1070b616500SRoland Eggner "a file name to load a previously saved configuration.\n"
108692d97c3Snir.tzachar@gmail.com "\n"
109692d97c3Snir.tzachar@gmail.com "\n"
1100b616500SRoland Eggner "Terminal configuration\n"
1110b616500SRoland Eggner "----------------------\n"
1120b616500SRoland Eggner "If you use nconfig in a xterm window, make sure your TERM environment\n"
1130b616500SRoland Eggner "variable specifies a terminal configuration which supports at least\n"
1140b616500SRoland Eggner "16 colors.  Otherwise nconfig will look rather bad.\n"
115692d97c3Snir.tzachar@gmail.com "\n"
1160b616500SRoland Eggner "If the \"stty size\" command reports the current terminalsize correctly,\n"
1170b616500SRoland Eggner "nconfig will adapt to sizes larger than the traditional 80x25 \"standard\"\n"
1180b616500SRoland Eggner "and display longer menus properly.\n"
119692d97c3Snir.tzachar@gmail.com "\n"
120692d97c3Snir.tzachar@gmail.com "\n"
1210b616500SRoland Eggner "Single menu mode\n"
1220b616500SRoland Eggner "----------------\n"
1230b616500SRoland Eggner "If you prefer to have all of the menu entries listed in a single menu,\n"
1240b616500SRoland Eggner "rather than the default multimenu hierarchy, run nconfig with\n"
1250b616500SRoland Eggner "NCONFIG_MODE environment variable set to single_menu.  Example:\n"
126692d97c3Snir.tzachar@gmail.com "\n"
127692d97c3Snir.tzachar@gmail.com "make NCONFIG_MODE=single_menu nconfig\n"
128692d97c3Snir.tzachar@gmail.com "\n"
1290b616500SRoland Eggner "<Enter> will then unfold the appropriate category, or fold it if it\n"
1300b616500SRoland Eggner "is already unfolded.  Folded menu entries will be designated by a\n"
1310b616500SRoland Eggner "leading \"++>\" and unfolded entries by a leading \"-->\".\n"
132692d97c3Snir.tzachar@gmail.com "\n"
1330b616500SRoland Eggner "Note that this mode can eventually be a little more CPU expensive than\n"
1340b616500SRoland Eggner "the default mode, especially with a larger number of unfolded submenus.\n"
135694c49a7SSam Ravnborg "\n",
136694c49a7SSam Ravnborg menu_no_f_instructions[] =
137692d97c3Snir.tzachar@gmail.com "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1381278ebdbSDirk Gouders "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
1390b616500SRoland Eggner "\n"
1400b616500SRoland Eggner "Use the following keys to navigate the menus:\n"
1410b616500SRoland Eggner "Move up or down with <Up> and <Down>.\n"
1420b616500SRoland Eggner "Enter a submenu with <Enter> or <Right>.\n"
1430b616500SRoland Eggner "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1440b616500SRoland Eggner "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1450b616500SRoland Eggner "Pressing <Space> cycles through the available options.\n"
1460b616500SRoland Eggner "To search for menu entries press </>.\n"
1470b616500SRoland Eggner "<Esc> always leaves the current window.\n"
1480b616500SRoland Eggner "\n"
1490b616500SRoland Eggner "You do not have function keys support.\n"
1500b616500SRoland Eggner "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
1510b616500SRoland Eggner "For verbose global help use key <1>.\n"
152694c49a7SSam Ravnborg "For help related to the current menu entry press <?> or <h>.\n",
153694c49a7SSam Ravnborg menu_instructions[] =
154692d97c3Snir.tzachar@gmail.com "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1551278ebdbSDirk Gouders "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
1560b616500SRoland Eggner "\n"
1570b616500SRoland Eggner "Use the following keys to navigate the menus:\n"
1580b616500SRoland Eggner "Move up or down with <Up> or <Down>.\n"
1590b616500SRoland Eggner "Enter a submenu with <Enter> or <Right>.\n"
1600b616500SRoland Eggner "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1610b616500SRoland Eggner "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1620b616500SRoland Eggner "Pressing <Space> cycles through the available options.\n"
1630b616500SRoland Eggner "To search for menu entries press </>.\n"
1640b616500SRoland Eggner "<Esc> always leaves the current window.\n"
1650b616500SRoland Eggner "\n"
1660b616500SRoland Eggner "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
1670b616500SRoland Eggner "For verbose global help press <F1>.\n"
168694c49a7SSam Ravnborg "For help related to the current menu entry press <?> or <h>.\n",
169694c49a7SSam Ravnborg radiolist_instructions[] =
1700b616500SRoland Eggner "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
1710b616500SRoland Eggner "with <Space>.\n"
1720b616500SRoland Eggner "For help related to the current entry press <?> or <h>.\n"
173694c49a7SSam Ravnborg "For global help press <F1>.\n",
174694c49a7SSam Ravnborg inputbox_instructions_int[] =
175692d97c3Snir.tzachar@gmail.com "Please enter a decimal value.\n"
176692d97c3Snir.tzachar@gmail.com "Fractions will not be accepted.\n"
177694c49a7SSam Ravnborg "Press <Enter> to apply, <Esc> to cancel.",
178694c49a7SSam Ravnborg inputbox_instructions_hex[] =
179692d97c3Snir.tzachar@gmail.com "Please enter a hexadecimal value.\n"
180694c49a7SSam Ravnborg "Press <Enter> to apply, <Esc> to cancel.",
181694c49a7SSam Ravnborg inputbox_instructions_string[] =
182692d97c3Snir.tzachar@gmail.com "Please enter a string value.\n"
183694c49a7SSam Ravnborg "Press <Enter> to apply, <Esc> to cancel.",
184694c49a7SSam Ravnborg setmod_text[] =
1850b616500SRoland Eggner "This feature depends on another feature which has been configured as a\n"
186694c49a7SSam Ravnborg "module.  As a result, the current feature will be built as a module too.",
187694c49a7SSam Ravnborg load_config_text[] =
188692d97c3Snir.tzachar@gmail.com "Enter the name of the configuration file you wish to load.\n"
1890b616500SRoland Eggner "Accept the name shown to restore the configuration you last\n"
190694c49a7SSam Ravnborg "retrieved.  Leave empty to abort.",
191694c49a7SSam Ravnborg load_config_help[] =
192652cf982SArnaud Lacombe "For various reasons, one may wish to keep several different\n"
193692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n"
194692d97c3Snir.tzachar@gmail.com "\n"
195692d97c3Snir.tzachar@gmail.com "If you have saved a previous configuration in a file other than the\n"
1960b616500SRoland Eggner "default one, entering its name here will allow you to load and modify\n"
1970b616500SRoland Eggner "that configuration.\n"
198692d97c3Snir.tzachar@gmail.com "\n"
199694c49a7SSam Ravnborg "Leave empty to abort.\n",
200694c49a7SSam Ravnborg save_config_text[] =
201692d97c3Snir.tzachar@gmail.com "Enter a filename to which this configuration should be saved\n"
202694c49a7SSam Ravnborg "as an alternate.  Leave empty to abort.",
203694c49a7SSam Ravnborg save_config_help[] =
2040b616500SRoland Eggner "For various reasons, one may wish to keep several different\n"
2050b616500SRoland Eggner "configurations available on a single machine.\n"
206692d97c3Snir.tzachar@gmail.com "\n"
207692d97c3Snir.tzachar@gmail.com "Entering a file name here will allow you to later retrieve, modify\n"
208692d97c3Snir.tzachar@gmail.com "and use the current configuration as an alternate to whatever\n"
209692d97c3Snir.tzachar@gmail.com "configuration options you have selected at that time.\n"
210692d97c3Snir.tzachar@gmail.com "\n"
211694c49a7SSam Ravnborg "Leave empty to abort.\n",
212694c49a7SSam Ravnborg search_help[] =
2130b616500SRoland Eggner "Search for symbols (configuration variable names CONFIG_*) and display\n"
2140b616500SRoland Eggner "their relations.  Regular expressions are supported.\n"
2150b616500SRoland Eggner "Example:  Search for \"^FOO\".\n"
216692d97c3Snir.tzachar@gmail.com "Result:\n"
217692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
218692d97c3Snir.tzachar@gmail.com "Symbol: FOO [ = m]\n"
219692d97c3Snir.tzachar@gmail.com "Prompt: Foo bus is used to drive the bar HW\n"
220692d97c3Snir.tzachar@gmail.com "Defined at drivers/pci/Kconfig:47\n"
2210df8e970SMasahiro Yamada "Depends on: X86_LOCAL_APIC && X86_IO_APIC\n"
222692d97c3Snir.tzachar@gmail.com "Location:\n"
223bb8187d3SPaul Gortmaker "  -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
224692d97c3Snir.tzachar@gmail.com "    -> PCI support (PCI [ = y])\n"
2251ba67cd3SJesse Taube "(1)   -> PCI access mode (<choice> [ = y])\n"
226692d97c3Snir.tzachar@gmail.com "Selects: LIBCRC32\n"
227692d97c3Snir.tzachar@gmail.com "Selected by: BAR\n"
228692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
2290b616500SRoland Eggner "o  The line 'Prompt:' shows the text displayed for this symbol in\n"
2300b616500SRoland Eggner "   the menu hierarchy.\n"
2310b616500SRoland Eggner "o  The 'Defined at' line tells at what file / line number the symbol is\n"
2320b616500SRoland Eggner "   defined.\n"
2330b616500SRoland Eggner "o  The 'Depends on:' line lists symbols that need to be defined for\n"
2340b616500SRoland Eggner "   this symbol to be visible and selectable in the menu.\n"
2350b616500SRoland Eggner "o  The 'Location:' lines tell, where in the menu structure this symbol\n"
2361ba67cd3SJesse Taube "   is located.\n"
2371ba67cd3SJesse Taube "     A location followed by a [ = y] indicates that this is\n"
2380b616500SRoland Eggner "     a selectable menu item, and the current value is displayed inside\n"
2390b616500SRoland Eggner "     brackets.\n"
2401ba67cd3SJesse Taube "     Press the key in the (#) prefix to jump directly to that\n"
2411ba67cd3SJesse Taube "     location. You will be returned to the current search results\n"
2421ba67cd3SJesse Taube "     after exiting this new menu.\n"
2430b616500SRoland Eggner "o  The 'Selects:' line tells, what symbol will be automatically selected\n"
2440b616500SRoland Eggner "   if this symbol is selected (y or m).\n"
2450b616500SRoland Eggner "o  The 'Selected by' line tells what symbol has selected this symbol.\n"
246692d97c3Snir.tzachar@gmail.com "\n"
247692d97c3Snir.tzachar@gmail.com "Only relevant lines are shown.\n"
248692d97c3Snir.tzachar@gmail.com "\n\n"
249692d97c3Snir.tzachar@gmail.com "Search examples:\n"
2500b616500SRoland Eggner "USB  => find all symbols containing USB\n"
25159dfa24dSArnaud Lacombe "^USB => find all symbols starting with USB\n"
25259dfa24dSArnaud Lacombe "USB$ => find all symbols ending with USB\n"
253694c49a7SSam Ravnborg "\n";
254692d97c3Snir.tzachar@gmail.com 
255692d97c3Snir.tzachar@gmail.com struct mitem {
256692d97c3Snir.tzachar@gmail.com 	char str[256];
257692d97c3Snir.tzachar@gmail.com 	char tag;
258692d97c3Snir.tzachar@gmail.com 	void *usrptr;
259692d97c3Snir.tzachar@gmail.com 	int is_visible;
260692d97c3Snir.tzachar@gmail.com };
261692d97c3Snir.tzachar@gmail.com 
262692d97c3Snir.tzachar@gmail.com #define MAX_MENU_ITEMS 4096
263692d97c3Snir.tzachar@gmail.com static int show_all_items;
264692d97c3Snir.tzachar@gmail.com static int indent;
265692d97c3Snir.tzachar@gmail.com static struct menu *current_menu;
266692d97c3Snir.tzachar@gmail.com static int child_count;
267692d97c3Snir.tzachar@gmail.com static int single_menu_mode;
268692d97c3Snir.tzachar@gmail.com /* the window in which all information appears */
269692d97c3Snir.tzachar@gmail.com static WINDOW *main_window;
270692d97c3Snir.tzachar@gmail.com /* the largest size of the menu window */
271692d97c3Snir.tzachar@gmail.com static int mwin_max_lines;
272692d97c3Snir.tzachar@gmail.com static int mwin_max_cols;
273692d97c3Snir.tzachar@gmail.com /* the window in which we show option buttons */
274692d97c3Snir.tzachar@gmail.com static MENU *curses_menu;
275692d97c3Snir.tzachar@gmail.com static ITEM *curses_menu_items[MAX_MENU_ITEMS];
276692d97c3Snir.tzachar@gmail.com static struct mitem k_menu_items[MAX_MENU_ITEMS];
2771f035a52SMasahiro Yamada static unsigned int items_num;
278692d97c3Snir.tzachar@gmail.com static int global_exit;
279692d97c3Snir.tzachar@gmail.com /* the currently selected button */
280ad818106SRandy Dunlap static const char *current_instructions = menu_instructions;
281692d97c3Snir.tzachar@gmail.com 
2825ea9f64fSCheng Renquan static char *dialog_input_result;
2835ea9f64fSCheng Renquan static int dialog_input_result_len;
2845ea9f64fSCheng Renquan 
2851ba67cd3SJesse Taube static void selected_conf(struct menu *menu, struct menu *active_menu);
286692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu);
287692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu);
288692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu);
289692d97c3Snir.tzachar@gmail.com static void conf_load(void);
290692d97c3Snir.tzachar@gmail.com static void conf_save(void);
291692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu);
292692d97c3Snir.tzachar@gmail.com static int do_exit(void);
293692d97c3Snir.tzachar@gmail.com static void setup_windows(void);
294a72f3e2bSNir Tzachar static void search_conf(void);
295692d97c3Snir.tzachar@gmail.com 
296692d97c3Snir.tzachar@gmail.com typedef void (*function_key_handler_t)(int *key, struct menu *menu);
297692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item);
298692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item);
299692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item);
300692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item);
301692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item);
302692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item);
303692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item);
304692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item);
305a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item);
306692d97c3Snir.tzachar@gmail.com 
307692d97c3Snir.tzachar@gmail.com struct function_keys {
308692d97c3Snir.tzachar@gmail.com 	const char *key_str;
309692d97c3Snir.tzachar@gmail.com 	const char *func;
310692d97c3Snir.tzachar@gmail.com 	function_key key;
311692d97c3Snir.tzachar@gmail.com 	function_key_handler_t handler;
312692d97c3Snir.tzachar@gmail.com };
313692d97c3Snir.tzachar@gmail.com 
314a72f3e2bSNir Tzachar static const int function_keys_num = 9;
315ad818106SRandy Dunlap static struct function_keys function_keys[] = {
316692d97c3Snir.tzachar@gmail.com 	{
317692d97c3Snir.tzachar@gmail.com 		.key_str = "F1",
318692d97c3Snir.tzachar@gmail.com 		.func = "Help",
319692d97c3Snir.tzachar@gmail.com 		.key = F_HELP,
320692d97c3Snir.tzachar@gmail.com 		.handler = handle_f1,
321692d97c3Snir.tzachar@gmail.com 	},
322692d97c3Snir.tzachar@gmail.com 	{
323692d97c3Snir.tzachar@gmail.com 		.key_str = "F2",
324a72f3e2bSNir Tzachar 		.func = "SymInfo",
325692d97c3Snir.tzachar@gmail.com 		.key = F_SYMBOL,
326692d97c3Snir.tzachar@gmail.com 		.handler = handle_f2,
327692d97c3Snir.tzachar@gmail.com 	},
328692d97c3Snir.tzachar@gmail.com 	{
329692d97c3Snir.tzachar@gmail.com 		.key_str = "F3",
3302c68115cSRoland Eggner 		.func = "Help 2",
331692d97c3Snir.tzachar@gmail.com 		.key = F_INSTS,
332692d97c3Snir.tzachar@gmail.com 		.handler = handle_f3,
333692d97c3Snir.tzachar@gmail.com 	},
334692d97c3Snir.tzachar@gmail.com 	{
335692d97c3Snir.tzachar@gmail.com 		.key_str = "F4",
3362c68115cSRoland Eggner 		.func = "ShowAll",
337692d97c3Snir.tzachar@gmail.com 		.key = F_CONF,
338692d97c3Snir.tzachar@gmail.com 		.handler = handle_f4,
339692d97c3Snir.tzachar@gmail.com 	},
340692d97c3Snir.tzachar@gmail.com 	{
341692d97c3Snir.tzachar@gmail.com 		.key_str = "F5",
342692d97c3Snir.tzachar@gmail.com 		.func = "Back",
343692d97c3Snir.tzachar@gmail.com 		.key = F_BACK,
344692d97c3Snir.tzachar@gmail.com 		.handler = handle_f5,
345692d97c3Snir.tzachar@gmail.com 	},
346692d97c3Snir.tzachar@gmail.com 	{
347692d97c3Snir.tzachar@gmail.com 		.key_str = "F6",
348692d97c3Snir.tzachar@gmail.com 		.func = "Save",
349692d97c3Snir.tzachar@gmail.com 		.key = F_SAVE,
350692d97c3Snir.tzachar@gmail.com 		.handler = handle_f6,
351692d97c3Snir.tzachar@gmail.com 	},
352692d97c3Snir.tzachar@gmail.com 	{
353692d97c3Snir.tzachar@gmail.com 		.key_str = "F7",
354692d97c3Snir.tzachar@gmail.com 		.func = "Load",
355692d97c3Snir.tzachar@gmail.com 		.key = F_LOAD,
356692d97c3Snir.tzachar@gmail.com 		.handler = handle_f7,
357692d97c3Snir.tzachar@gmail.com 	},
358692d97c3Snir.tzachar@gmail.com 	{
359692d97c3Snir.tzachar@gmail.com 		.key_str = "F8",
360a72f3e2bSNir Tzachar 		.func = "SymSearch",
361a72f3e2bSNir Tzachar 		.key = F_SEARCH,
362a72f3e2bSNir Tzachar 		.handler = handle_f8,
363a72f3e2bSNir Tzachar 	},
364a72f3e2bSNir Tzachar 	{
365a72f3e2bSNir Tzachar 		.key_str = "F9",
366692d97c3Snir.tzachar@gmail.com 		.func = "Exit",
367692d97c3Snir.tzachar@gmail.com 		.key = F_EXIT,
368a72f3e2bSNir Tzachar 		.handler = handle_f9,
369692d97c3Snir.tzachar@gmail.com 	},
370692d97c3Snir.tzachar@gmail.com };
371692d97c3Snir.tzachar@gmail.com 
print_function_line(void)372692d97c3Snir.tzachar@gmail.com static void print_function_line(void)
373692d97c3Snir.tzachar@gmail.com {
374692d97c3Snir.tzachar@gmail.com 	int i;
375692d97c3Snir.tzachar@gmail.com 	int offset = 1;
376692d97c3Snir.tzachar@gmail.com 	const int skip = 1;
377e0b42605SDirk Gouders 	int lines = getmaxy(stdscr);
378692d97c3Snir.tzachar@gmail.com 
379692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
38093487b17SMasahiro Yamada 		wattrset(main_window, attr_function_highlight);
381e0b42605SDirk Gouders 		mvwprintw(main_window, lines-3, offset,
382692d97c3Snir.tzachar@gmail.com 				"%s",
383692d97c3Snir.tzachar@gmail.com 				function_keys[i].key_str);
38493487b17SMasahiro Yamada 		wattrset(main_window, attr_function_text);
385692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].key_str);
386e0b42605SDirk Gouders 		mvwprintw(main_window, lines-3,
387692d97c3Snir.tzachar@gmail.com 				offset, "%s",
388692d97c3Snir.tzachar@gmail.com 				function_keys[i].func);
389692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].func) + skip;
390692d97c3Snir.tzachar@gmail.com 	}
39193487b17SMasahiro Yamada 	wattrset(main_window, attr_normal);
392692d97c3Snir.tzachar@gmail.com }
393692d97c3Snir.tzachar@gmail.com 
394692d97c3Snir.tzachar@gmail.com /* help */
handle_f1(int * key,struct menu * current_item)395692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item)
396692d97c3Snir.tzachar@gmail.com {
397692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
398694c49a7SSam Ravnborg 			"Global help", nconf_global_help);
399692d97c3Snir.tzachar@gmail.com 	return;
400692d97c3Snir.tzachar@gmail.com }
401692d97c3Snir.tzachar@gmail.com 
402692d97c3Snir.tzachar@gmail.com /* symbole help */
handle_f2(int * key,struct menu * current_item)403692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item)
404692d97c3Snir.tzachar@gmail.com {
405692d97c3Snir.tzachar@gmail.com 	show_help(current_item);
406692d97c3Snir.tzachar@gmail.com 	return;
407692d97c3Snir.tzachar@gmail.com }
408692d97c3Snir.tzachar@gmail.com 
409692d97c3Snir.tzachar@gmail.com /* instructions */
handle_f3(int * key,struct menu * current_item)410692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item)
411692d97c3Snir.tzachar@gmail.com {
412692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
413694c49a7SSam Ravnborg 			"Short help",
414694c49a7SSam Ravnborg 			current_instructions);
415692d97c3Snir.tzachar@gmail.com 	return;
416692d97c3Snir.tzachar@gmail.com }
417692d97c3Snir.tzachar@gmail.com 
418692d97c3Snir.tzachar@gmail.com /* config */
handle_f4(int * key,struct menu * current_item)419692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item)
420692d97c3Snir.tzachar@gmail.com {
421692d97c3Snir.tzachar@gmail.com 	int res = btn_dialog(main_window,
422694c49a7SSam Ravnborg 			"Show all symbols?",
423692d97c3Snir.tzachar@gmail.com 			2,
424692d97c3Snir.tzachar@gmail.com 			"   <Show All>   ",
425692d97c3Snir.tzachar@gmail.com 			"<Don't show all>");
426692d97c3Snir.tzachar@gmail.com 	if (res == 0)
427692d97c3Snir.tzachar@gmail.com 		show_all_items = 1;
428692d97c3Snir.tzachar@gmail.com 	else if (res == 1)
429692d97c3Snir.tzachar@gmail.com 		show_all_items = 0;
430692d97c3Snir.tzachar@gmail.com 
431692d97c3Snir.tzachar@gmail.com 	return;
432692d97c3Snir.tzachar@gmail.com }
433692d97c3Snir.tzachar@gmail.com 
434692d97c3Snir.tzachar@gmail.com /* back */
handle_f5(int * key,struct menu * current_item)435692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item)
436692d97c3Snir.tzachar@gmail.com {
437692d97c3Snir.tzachar@gmail.com 	*key = KEY_LEFT;
438692d97c3Snir.tzachar@gmail.com 	return;
439692d97c3Snir.tzachar@gmail.com }
440692d97c3Snir.tzachar@gmail.com 
441692d97c3Snir.tzachar@gmail.com /* save */
handle_f6(int * key,struct menu * current_item)442692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item)
443692d97c3Snir.tzachar@gmail.com {
444692d97c3Snir.tzachar@gmail.com 	conf_save();
445692d97c3Snir.tzachar@gmail.com 	return;
446692d97c3Snir.tzachar@gmail.com }
447692d97c3Snir.tzachar@gmail.com 
448692d97c3Snir.tzachar@gmail.com /* load */
handle_f7(int * key,struct menu * current_item)449692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item)
450692d97c3Snir.tzachar@gmail.com {
451692d97c3Snir.tzachar@gmail.com 	conf_load();
452692d97c3Snir.tzachar@gmail.com 	return;
453692d97c3Snir.tzachar@gmail.com }
454692d97c3Snir.tzachar@gmail.com 
455a72f3e2bSNir Tzachar /* search */
handle_f8(int * key,struct menu * current_item)456692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item)
457692d97c3Snir.tzachar@gmail.com {
458a72f3e2bSNir Tzachar 	search_conf();
459a72f3e2bSNir Tzachar 	return;
460a72f3e2bSNir Tzachar }
461a72f3e2bSNir Tzachar 
462a72f3e2bSNir Tzachar /* exit */
handle_f9(int * key,struct menu * current_item)463a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item)
464a72f3e2bSNir Tzachar {
465692d97c3Snir.tzachar@gmail.com 	do_exit();
466692d97c3Snir.tzachar@gmail.com 	return;
467692d97c3Snir.tzachar@gmail.com }
468692d97c3Snir.tzachar@gmail.com 
469692d97c3Snir.tzachar@gmail.com /* return != 0 to indicate the key was handles */
process_special_keys(int * key,struct menu * menu)470851190c9SMichal Marek static int process_special_keys(int *key, struct menu *menu)
471692d97c3Snir.tzachar@gmail.com {
472692d97c3Snir.tzachar@gmail.com 	int i;
473692d97c3Snir.tzachar@gmail.com 
474692d97c3Snir.tzachar@gmail.com 	if (*key == KEY_RESIZE) {
475692d97c3Snir.tzachar@gmail.com 		setup_windows();
476692d97c3Snir.tzachar@gmail.com 		return 1;
477692d97c3Snir.tzachar@gmail.com 	}
478692d97c3Snir.tzachar@gmail.com 
479692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
480692d97c3Snir.tzachar@gmail.com 		if (*key == KEY_F(function_keys[i].key) ||
481692d97c3Snir.tzachar@gmail.com 		    *key == '0' + function_keys[i].key){
482692d97c3Snir.tzachar@gmail.com 			function_keys[i].handler(key, menu);
483692d97c3Snir.tzachar@gmail.com 			return 1;
484692d97c3Snir.tzachar@gmail.com 		}
485692d97c3Snir.tzachar@gmail.com 	}
486692d97c3Snir.tzachar@gmail.com 
487692d97c3Snir.tzachar@gmail.com 	return 0;
488692d97c3Snir.tzachar@gmail.com }
489692d97c3Snir.tzachar@gmail.com 
clean_items(void)490692d97c3Snir.tzachar@gmail.com static void clean_items(void)
491692d97c3Snir.tzachar@gmail.com {
492692d97c3Snir.tzachar@gmail.com 	int i;
493692d97c3Snir.tzachar@gmail.com 	for (i = 0; curses_menu_items[i]; i++)
494692d97c3Snir.tzachar@gmail.com 		free_item(curses_menu_items[i]);
495692d97c3Snir.tzachar@gmail.com 	bzero(curses_menu_items, sizeof(curses_menu_items));
496692d97c3Snir.tzachar@gmail.com 	bzero(k_menu_items, sizeof(k_menu_items));
497692d97c3Snir.tzachar@gmail.com 	items_num = 0;
498692d97c3Snir.tzachar@gmail.com }
499692d97c3Snir.tzachar@gmail.com 
500a72f3e2bSNir Tzachar typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
501a72f3e2bSNir Tzachar 	FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
502692d97c3Snir.tzachar@gmail.com 
503a72f3e2bSNir Tzachar /* return the index of the matched item, or -1 if no such item exists */
get_mext_match(const char * match_str,match_f flag)504a72f3e2bSNir Tzachar static int get_mext_match(const char *match_str, match_f flag)
505a72f3e2bSNir Tzachar {
5061f035a52SMasahiro Yamada 	int match_start, index;
5071f035a52SMasahiro Yamada 
5081f035a52SMasahiro Yamada 	/* Do not search if the menu is empty (i.e. items_num == 0) */
5091f035a52SMasahiro Yamada 	match_start = item_index(current_item(curses_menu));
5101f035a52SMasahiro Yamada 	if (match_start == ERR)
5111f035a52SMasahiro Yamada 		return -1;
512a72f3e2bSNir Tzachar 
513a72f3e2bSNir Tzachar 	if (flag == FIND_NEXT_MATCH_DOWN)
514a72f3e2bSNir Tzachar 		++match_start;
515a72f3e2bSNir Tzachar 	else if (flag == FIND_NEXT_MATCH_UP)
516a72f3e2bSNir Tzachar 		--match_start;
517a72f3e2bSNir Tzachar 
5188c94b430SMihai Moldovan 	match_start = (match_start + items_num) % items_num;
519a72f3e2bSNir Tzachar 	index = match_start;
520a72f3e2bSNir Tzachar 	while (true) {
521a72f3e2bSNir Tzachar 		char *str = k_menu_items[index].str;
522ad818106SRandy Dunlap 		if (strcasestr(str, match_str) != NULL)
523a72f3e2bSNir Tzachar 			return index;
524a72f3e2bSNir Tzachar 		if (flag == FIND_NEXT_MATCH_UP ||
525a72f3e2bSNir Tzachar 		    flag == MATCH_TINKER_PATTERN_UP)
526a72f3e2bSNir Tzachar 			--index;
527a72f3e2bSNir Tzachar 		else
528a72f3e2bSNir Tzachar 			++index;
529a72f3e2bSNir Tzachar 		index = (index + items_num) % items_num;
530a72f3e2bSNir Tzachar 		if (index == match_start)
531692d97c3Snir.tzachar@gmail.com 			return -1;
532692d97c3Snir.tzachar@gmail.com 	}
533692d97c3Snir.tzachar@gmail.com }
534692d97c3Snir.tzachar@gmail.com 
535a72f3e2bSNir Tzachar /* Make a new item. */
item_make(struct menu * menu,char tag,const char * fmt,...)536851190c9SMichal Marek static void item_make(struct menu *menu, char tag, const char *fmt, ...)
537692d97c3Snir.tzachar@gmail.com {
538692d97c3Snir.tzachar@gmail.com 	va_list ap;
539692d97c3Snir.tzachar@gmail.com 
540692d97c3Snir.tzachar@gmail.com 	if (items_num > MAX_MENU_ITEMS-1)
541692d97c3Snir.tzachar@gmail.com 		return;
542692d97c3Snir.tzachar@gmail.com 
543692d97c3Snir.tzachar@gmail.com 	bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
544692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].tag = tag;
545692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].usrptr = menu;
546692d97c3Snir.tzachar@gmail.com 	if (menu != NULL)
547692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible =
548692d97c3Snir.tzachar@gmail.com 			menu_is_visible(menu);
549692d97c3Snir.tzachar@gmail.com 	else
550692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible = 1;
551692d97c3Snir.tzachar@gmail.com 
552692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
553a72f3e2bSNir Tzachar 	vsnprintf(k_menu_items[items_num].str,
554a72f3e2bSNir Tzachar 		  sizeof(k_menu_items[items_num].str),
555a72f3e2bSNir Tzachar 		  fmt, ap);
556692d97c3Snir.tzachar@gmail.com 	va_end(ap);
557a72f3e2bSNir Tzachar 
558a72f3e2bSNir Tzachar 	if (!k_menu_items[items_num].is_visible)
559a72f3e2bSNir Tzachar 		memcpy(k_menu_items[items_num].str, "XXX", 3);
560692d97c3Snir.tzachar@gmail.com 
561692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = new_item(
562692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str,
563692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str);
564692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[items_num],
565692d97c3Snir.tzachar@gmail.com 			&k_menu_items[items_num]);
566692d97c3Snir.tzachar@gmail.com 	/*
567692d97c3Snir.tzachar@gmail.com 	if (!k_menu_items[items_num].is_visible)
568692d97c3Snir.tzachar@gmail.com 		item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
569692d97c3Snir.tzachar@gmail.com 	*/
570692d97c3Snir.tzachar@gmail.com 
571692d97c3Snir.tzachar@gmail.com 	items_num++;
572692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = NULL;
573692d97c3Snir.tzachar@gmail.com }
574692d97c3Snir.tzachar@gmail.com 
575692d97c3Snir.tzachar@gmail.com /* very hackish. adds a string to the last item added */
item_add_str(const char * fmt,...)576851190c9SMichal Marek static void item_add_str(const char *fmt, ...)
577692d97c3Snir.tzachar@gmail.com {
578692d97c3Snir.tzachar@gmail.com 	va_list ap;
579692d97c3Snir.tzachar@gmail.com 	int index = items_num-1;
580692d97c3Snir.tzachar@gmail.com 	char new_str[256];
581692d97c3Snir.tzachar@gmail.com 	char tmp_str[256];
582692d97c3Snir.tzachar@gmail.com 
583692d97c3Snir.tzachar@gmail.com 	if (index < 0)
584692d97c3Snir.tzachar@gmail.com 		return;
585692d97c3Snir.tzachar@gmail.com 
586692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
587692d97c3Snir.tzachar@gmail.com 	vsnprintf(new_str, sizeof(new_str), fmt, ap);
588692d97c3Snir.tzachar@gmail.com 	va_end(ap);
589692d97c3Snir.tzachar@gmail.com 	snprintf(tmp_str, sizeof(tmp_str), "%s%s",
590692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str, new_str);
591692d97c3Snir.tzachar@gmail.com 	strncpy(k_menu_items[index].str,
592692d97c3Snir.tzachar@gmail.com 		tmp_str,
593692d97c3Snir.tzachar@gmail.com 		sizeof(k_menu_items[index].str));
594692d97c3Snir.tzachar@gmail.com 
595692d97c3Snir.tzachar@gmail.com 	free_item(curses_menu_items[index]);
596692d97c3Snir.tzachar@gmail.com 	curses_menu_items[index] = new_item(
597692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str,
598692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str);
599692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[index],
600692d97c3Snir.tzachar@gmail.com 			&k_menu_items[index]);
601692d97c3Snir.tzachar@gmail.com }
602692d97c3Snir.tzachar@gmail.com 
603692d97c3Snir.tzachar@gmail.com /* get the tag of the currently selected item */
item_tag(void)604851190c9SMichal Marek static char item_tag(void)
605692d97c3Snir.tzachar@gmail.com {
606692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
607692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
608692d97c3Snir.tzachar@gmail.com 
609692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
610692d97c3Snir.tzachar@gmail.com 	if (cur == NULL)
611692d97c3Snir.tzachar@gmail.com 		return 0;
612692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
613692d97c3Snir.tzachar@gmail.com 	return mcur->tag;
614692d97c3Snir.tzachar@gmail.com }
615692d97c3Snir.tzachar@gmail.com 
curses_item_index(void)616851190c9SMichal Marek static int curses_item_index(void)
617692d97c3Snir.tzachar@gmail.com {
618692d97c3Snir.tzachar@gmail.com 	return  item_index(current_item(curses_menu));
619692d97c3Snir.tzachar@gmail.com }
620692d97c3Snir.tzachar@gmail.com 
item_data(void)621851190c9SMichal Marek static void *item_data(void)
622692d97c3Snir.tzachar@gmail.com {
623692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
624692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
625692d97c3Snir.tzachar@gmail.com 
626692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
627866af407SAndrej Gelenberg 	if (!cur)
628866af407SAndrej Gelenberg 		return NULL;
629692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
630692d97c3Snir.tzachar@gmail.com 	return mcur->usrptr;
631692d97c3Snir.tzachar@gmail.com 
632692d97c3Snir.tzachar@gmail.com }
633692d97c3Snir.tzachar@gmail.com 
item_is_tag(char tag)634851190c9SMichal Marek static int item_is_tag(char tag)
635692d97c3Snir.tzachar@gmail.com {
636692d97c3Snir.tzachar@gmail.com 	return item_tag() == tag;
637692d97c3Snir.tzachar@gmail.com }
638692d97c3Snir.tzachar@gmail.com 
639692d97c3Snir.tzachar@gmail.com static char filename[PATH_MAX+1];
640692d97c3Snir.tzachar@gmail.com static char menu_backtitle[PATH_MAX+128];
set_config_filename(const char * config_filename)641ecdb733fSMasahiro Yamada static void set_config_filename(const char *config_filename)
642692d97c3Snir.tzachar@gmail.com {
64368876c38SMasahiro Yamada 	snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s",
64468876c38SMasahiro Yamada 		 config_filename, rootmenu.prompt->text);
645692d97c3Snir.tzachar@gmail.com 
64668876c38SMasahiro Yamada 	snprintf(filename, sizeof(filename), "%s", config_filename);
647692d97c3Snir.tzachar@gmail.com }
648692d97c3Snir.tzachar@gmail.com 
649692d97c3Snir.tzachar@gmail.com /* return = 0 means we are successful.
650692d97c3Snir.tzachar@gmail.com  * -1 means go on doing what you were doing
651692d97c3Snir.tzachar@gmail.com  */
do_exit(void)652692d97c3Snir.tzachar@gmail.com static int do_exit(void)
653692d97c3Snir.tzachar@gmail.com {
654692d97c3Snir.tzachar@gmail.com 	int res;
655692d97c3Snir.tzachar@gmail.com 	if (!conf_get_changed()) {
656692d97c3Snir.tzachar@gmail.com 		global_exit = 1;
657692d97c3Snir.tzachar@gmail.com 		return 0;
658692d97c3Snir.tzachar@gmail.com 	}
659692d97c3Snir.tzachar@gmail.com 	res = btn_dialog(main_window,
660694c49a7SSam Ravnborg 			"Do you wish to save your new configuration?\n"
661694c49a7SSam Ravnborg 				"<ESC> to cancel and resume nconfig.",
662692d97c3Snir.tzachar@gmail.com 			2,
663692d97c3Snir.tzachar@gmail.com 			"   <save>   ",
664692d97c3Snir.tzachar@gmail.com 			"<don't save>");
665692d97c3Snir.tzachar@gmail.com 	if (res == KEY_EXIT) {
666692d97c3Snir.tzachar@gmail.com 		global_exit = 0;
667692d97c3Snir.tzachar@gmail.com 		return -1;
668692d97c3Snir.tzachar@gmail.com 	}
669692d97c3Snir.tzachar@gmail.com 
670692d97c3Snir.tzachar@gmail.com 	/* if we got here, the user really wants to exit */
671692d97c3Snir.tzachar@gmail.com 	switch (res) {
672692d97c3Snir.tzachar@gmail.com 	case 0:
673692d97c3Snir.tzachar@gmail.com 		res = conf_write(filename);
674692d97c3Snir.tzachar@gmail.com 		if (res)
675692d97c3Snir.tzachar@gmail.com 			btn_dialog(
676692d97c3Snir.tzachar@gmail.com 				main_window,
677694c49a7SSam Ravnborg 				"Error during writing of configuration.\n"
678694c49a7SSam Ravnborg 				  "Your configuration changes were NOT saved.",
679692d97c3Snir.tzachar@gmail.com 				  1,
680692d97c3Snir.tzachar@gmail.com 				  "<OK>");
68100c864f8SMasahiro Yamada 		conf_write_autoconf(0);
682692d97c3Snir.tzachar@gmail.com 		break;
683692d97c3Snir.tzachar@gmail.com 	default:
684692d97c3Snir.tzachar@gmail.com 		btn_dialog(
685692d97c3Snir.tzachar@gmail.com 			main_window,
686694c49a7SSam Ravnborg 			"Your configuration changes were NOT saved.",
687692d97c3Snir.tzachar@gmail.com 			1,
688692d97c3Snir.tzachar@gmail.com 			"<OK>");
689692d97c3Snir.tzachar@gmail.com 		break;
690692d97c3Snir.tzachar@gmail.com 	}
691692d97c3Snir.tzachar@gmail.com 	global_exit = 1;
692692d97c3Snir.tzachar@gmail.com 	return 0;
693692d97c3Snir.tzachar@gmail.com }
694692d97c3Snir.tzachar@gmail.com 
695692d97c3Snir.tzachar@gmail.com 
search_conf(void)696692d97c3Snir.tzachar@gmail.com static void search_conf(void)
697692d97c3Snir.tzachar@gmail.com {
698692d97c3Snir.tzachar@gmail.com 	struct symbol **sym_arr;
699692d97c3Snir.tzachar@gmail.com 	struct gstr res;
700337a275dSYann E. MORIN 	struct gstr title;
701692d97c3Snir.tzachar@gmail.com 	char *dialog_input;
7021ba67cd3SJesse Taube 	int dres, vscroll = 0, hscroll = 0;
7031ba67cd3SJesse Taube 	bool again;
704337a275dSYann E. MORIN 
705337a275dSYann E. MORIN 	title = str_new();
706694c49a7SSam Ravnborg 	str_printf( &title, "Enter (sub)string or regexp to search for "
707694c49a7SSam Ravnborg 			      "(with or without \"%s\")", CONFIG_);
708337a275dSYann E. MORIN 
709692d97c3Snir.tzachar@gmail.com again:
710692d97c3Snir.tzachar@gmail.com 	dres = dialog_inputbox(main_window,
711694c49a7SSam Ravnborg 			"Search Configuration Parameter",
712337a275dSYann E. MORIN 			str_get(&title),
7135ea9f64fSCheng Renquan 			"", &dialog_input_result, &dialog_input_result_len);
714692d97c3Snir.tzachar@gmail.com 	switch (dres) {
715692d97c3Snir.tzachar@gmail.com 	case 0:
716692d97c3Snir.tzachar@gmail.com 		break;
717692d97c3Snir.tzachar@gmail.com 	case 1:
718692d97c3Snir.tzachar@gmail.com 		show_scroll_win(main_window,
719694c49a7SSam Ravnborg 				"Search Configuration", search_help);
720692d97c3Snir.tzachar@gmail.com 		goto again;
721692d97c3Snir.tzachar@gmail.com 	default:
722337a275dSYann E. MORIN 		str_free(&title);
723692d97c3Snir.tzachar@gmail.com 		return;
724692d97c3Snir.tzachar@gmail.com 	}
725692d97c3Snir.tzachar@gmail.com 
726ffb5957bSArnaud Lacombe 	/* strip the prefix if necessary */
727692d97c3Snir.tzachar@gmail.com 	dialog_input = dialog_input_result;
728ffb5957bSArnaud Lacombe 	if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
729ffb5957bSArnaud Lacombe 		dialog_input += strlen(CONFIG_);
730692d97c3Snir.tzachar@gmail.com 
731692d97c3Snir.tzachar@gmail.com 	sym_arr = sym_re_search(dialog_input);
7321ba67cd3SJesse Taube 
7331ba67cd3SJesse Taube 	do {
7341ba67cd3SJesse Taube 		LIST_HEAD(head);
7351ba67cd3SJesse Taube 		struct search_data data = {
7361ba67cd3SJesse Taube 			.head = &head,
7371ba67cd3SJesse Taube 			.target = NULL,
7381ba67cd3SJesse Taube 		};
7391ba67cd3SJesse Taube 		jump_key_char = 0;
7401ba67cd3SJesse Taube 		res = get_relations_str(sym_arr, &head);
7411ba67cd3SJesse Taube 		dres = show_scroll_win_ext(main_window,
7421ba67cd3SJesse Taube 				"Search Results", str_get(&res),
7431ba67cd3SJesse Taube 				&vscroll, &hscroll,
7441ba67cd3SJesse Taube 				handle_search_keys, &data);
7451ba67cd3SJesse Taube 		again = false;
7461ba67cd3SJesse Taube 		if (dres >= '1' && dres <= '9') {
7471ba67cd3SJesse Taube 			assert(data.target != NULL);
7481ba67cd3SJesse Taube 			selected_conf(data.target->parent, data.target);
7491ba67cd3SJesse Taube 			again = true;
7501ba67cd3SJesse Taube 		}
751692d97c3Snir.tzachar@gmail.com 		str_free(&res);
7521ba67cd3SJesse Taube 	} while (again);
7531ba67cd3SJesse Taube 	free(sym_arr);
754337a275dSYann E. MORIN 	str_free(&title);
755692d97c3Snir.tzachar@gmail.com }
756692d97c3Snir.tzachar@gmail.com 
757692d97c3Snir.tzachar@gmail.com 
build_conf(struct menu * menu)758692d97c3Snir.tzachar@gmail.com static void build_conf(struct menu *menu)
759692d97c3Snir.tzachar@gmail.com {
760692d97c3Snir.tzachar@gmail.com 	struct symbol *sym;
761692d97c3Snir.tzachar@gmail.com 	struct property *prop;
762692d97c3Snir.tzachar@gmail.com 	struct menu *child;
763692d97c3Snir.tzachar@gmail.com 	int type, tmp, doint = 2;
764692d97c3Snir.tzachar@gmail.com 	tristate val;
765692d97c3Snir.tzachar@gmail.com 	char ch;
766692d97c3Snir.tzachar@gmail.com 
767692d97c3Snir.tzachar@gmail.com 	if (!menu || (!show_all_items && !menu_is_visible(menu)))
768692d97c3Snir.tzachar@gmail.com 		return;
769692d97c3Snir.tzachar@gmail.com 
770692d97c3Snir.tzachar@gmail.com 	sym = menu->sym;
771692d97c3Snir.tzachar@gmail.com 	prop = menu->prompt;
772692d97c3Snir.tzachar@gmail.com 	if (!sym) {
773692d97c3Snir.tzachar@gmail.com 		if (prop && menu != current_menu) {
774692d97c3Snir.tzachar@gmail.com 			const char *prompt = menu_get_prompt(menu);
775692d97c3Snir.tzachar@gmail.com 			enum prop_type ptype;
776692d97c3Snir.tzachar@gmail.com 			ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
777692d97c3Snir.tzachar@gmail.com 			switch (ptype) {
778692d97c3Snir.tzachar@gmail.com 			case P_MENU:
779692d97c3Snir.tzachar@gmail.com 				child_count++;
780692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode) {
781692d97c3Snir.tzachar@gmail.com 					item_make(menu, 'm',
782692d97c3Snir.tzachar@gmail.com 						"%s%*c%s",
783692d97c3Snir.tzachar@gmail.com 						menu->data ? "-->" : "++>",
784692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ', prompt);
785692d97c3Snir.tzachar@gmail.com 				} else
786692d97c3Snir.tzachar@gmail.com 					item_make(menu, 'm',
7871278ebdbSDirk Gouders 						  "   %*c%s  %s",
7881278ebdbSDirk Gouders 						  indent + 1, ' ', prompt,
7891278ebdbSDirk Gouders 						  menu_is_empty(menu) ? "----" : "--->");
790692d97c3Snir.tzachar@gmail.com 
791692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode && menu->data)
792692d97c3Snir.tzachar@gmail.com 					goto conf_childs;
793692d97c3Snir.tzachar@gmail.com 				return;
794692d97c3Snir.tzachar@gmail.com 			case P_COMMENT:
795692d97c3Snir.tzachar@gmail.com 				if (prompt) {
796692d97c3Snir.tzachar@gmail.com 					child_count++;
797692d97c3Snir.tzachar@gmail.com 					item_make(menu, ':',
798692d97c3Snir.tzachar@gmail.com 						"   %*c*** %s ***",
799692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ',
800694c49a7SSam Ravnborg 						prompt);
801692d97c3Snir.tzachar@gmail.com 				}
802692d97c3Snir.tzachar@gmail.com 				break;
803692d97c3Snir.tzachar@gmail.com 			default:
804692d97c3Snir.tzachar@gmail.com 				if (prompt) {
805692d97c3Snir.tzachar@gmail.com 					child_count++;
806692d97c3Snir.tzachar@gmail.com 					item_make(menu, ':', "---%*c%s",
807692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ',
808694c49a7SSam Ravnborg 						prompt);
809692d97c3Snir.tzachar@gmail.com 				}
810692d97c3Snir.tzachar@gmail.com 			}
811692d97c3Snir.tzachar@gmail.com 		} else
812692d97c3Snir.tzachar@gmail.com 			doint = 0;
813692d97c3Snir.tzachar@gmail.com 		goto conf_childs;
814692d97c3Snir.tzachar@gmail.com 	}
815692d97c3Snir.tzachar@gmail.com 
816692d97c3Snir.tzachar@gmail.com 	type = sym_get_type(sym);
817692d97c3Snir.tzachar@gmail.com 	if (sym_is_choice(sym)) {
818692d97c3Snir.tzachar@gmail.com 		struct symbol *def_sym = sym_get_choice_value(sym);
819692d97c3Snir.tzachar@gmail.com 		struct menu *def_menu = NULL;
820692d97c3Snir.tzachar@gmail.com 
821692d97c3Snir.tzachar@gmail.com 		child_count++;
822692d97c3Snir.tzachar@gmail.com 		for (child = menu->list; child; child = child->next) {
823692d97c3Snir.tzachar@gmail.com 			if (menu_is_visible(child) && child->sym == def_sym)
824692d97c3Snir.tzachar@gmail.com 				def_menu = child;
825692d97c3Snir.tzachar@gmail.com 		}
826692d97c3Snir.tzachar@gmail.com 
827692d97c3Snir.tzachar@gmail.com 		val = sym_get_tristate_value(sym);
828baa23ec8SMarco Ammon 		if (sym_is_changeable(sym)) {
829692d97c3Snir.tzachar@gmail.com 			switch (val) {
830692d97c3Snir.tzachar@gmail.com 			case yes:
831692d97c3Snir.tzachar@gmail.com 				ch = '*';
832692d97c3Snir.tzachar@gmail.com 				break;
833692d97c3Snir.tzachar@gmail.com 			case mod:
834692d97c3Snir.tzachar@gmail.com 				ch = 'M';
835692d97c3Snir.tzachar@gmail.com 				break;
836692d97c3Snir.tzachar@gmail.com 			default:
837692d97c3Snir.tzachar@gmail.com 				ch = ' ';
838692d97c3Snir.tzachar@gmail.com 				break;
839692d97c3Snir.tzachar@gmail.com 			}
840692d97c3Snir.tzachar@gmail.com 			item_make(menu, 't', "<%c>", ch);
841692d97c3Snir.tzachar@gmail.com 		} else {
842692d97c3Snir.tzachar@gmail.com 			item_make(menu, def_menu ? 't' : ':', "   ");
843692d97c3Snir.tzachar@gmail.com 		}
844692d97c3Snir.tzachar@gmail.com 
845692d97c3Snir.tzachar@gmail.com 		item_add_str("%*c%s", indent + 1,
846694c49a7SSam Ravnborg 				' ', menu_get_prompt(menu));
847692d97c3Snir.tzachar@gmail.com 		if (val == yes) {
848*648d82a9SMasahiro Yamada 			if (def_menu)
849*648d82a9SMasahiro Yamada 				item_add_str(" (%s)  --->", menu_get_prompt(def_menu));
850692d97c3Snir.tzachar@gmail.com 			return;
851692d97c3Snir.tzachar@gmail.com 		}
852692d97c3Snir.tzachar@gmail.com 	} else {
853692d97c3Snir.tzachar@gmail.com 		if (menu == current_menu) {
854692d97c3Snir.tzachar@gmail.com 			item_make(menu, ':',
855692d97c3Snir.tzachar@gmail.com 				"---%*c%s", indent + 1,
856694c49a7SSam Ravnborg 				' ', menu_get_prompt(menu));
857692d97c3Snir.tzachar@gmail.com 			goto conf_childs;
858692d97c3Snir.tzachar@gmail.com 		}
859692d97c3Snir.tzachar@gmail.com 		child_count++;
860692d97c3Snir.tzachar@gmail.com 		val = sym_get_tristate_value(sym);
861692d97c3Snir.tzachar@gmail.com 		switch (type) {
862692d97c3Snir.tzachar@gmail.com 		case S_BOOLEAN:
863baa23ec8SMarco Ammon 			if (sym_is_changeable(sym))
864692d97c3Snir.tzachar@gmail.com 				item_make(menu, 't', "[%c]",
865692d97c3Snir.tzachar@gmail.com 					  val == no ? ' ' : '*');
866692d97c3Snir.tzachar@gmail.com 			else
867692d97c3Snir.tzachar@gmail.com 				item_make(menu, 't', "-%c-",
868692d97c3Snir.tzachar@gmail.com 					  val == no ? ' ' : '*');
869692d97c3Snir.tzachar@gmail.com 			break;
870692d97c3Snir.tzachar@gmail.com 		case S_TRISTATE:
871692d97c3Snir.tzachar@gmail.com 			switch (val) {
872692d97c3Snir.tzachar@gmail.com 			case yes:
873692d97c3Snir.tzachar@gmail.com 				ch = '*';
874692d97c3Snir.tzachar@gmail.com 				break;
875692d97c3Snir.tzachar@gmail.com 			case mod:
876692d97c3Snir.tzachar@gmail.com 				ch = 'M';
877692d97c3Snir.tzachar@gmail.com 				break;
878692d97c3Snir.tzachar@gmail.com 			default:
879692d97c3Snir.tzachar@gmail.com 				ch = ' ';
880692d97c3Snir.tzachar@gmail.com 				break;
881692d97c3Snir.tzachar@gmail.com 			}
882baa23ec8SMarco Ammon 			if (sym_is_changeable(sym)) {
883692d97c3Snir.tzachar@gmail.com 				if (sym->rev_dep.tri == mod)
884e89b4615SMasahiro Yamada 					item_make(menu, 't', "{%c}", ch);
885692d97c3Snir.tzachar@gmail.com 				else
886e89b4615SMasahiro Yamada 					item_make(menu, 't', "<%c>", ch);
887692d97c3Snir.tzachar@gmail.com 			} else
888692d97c3Snir.tzachar@gmail.com 				item_make(menu, 't', "-%c-", ch);
889692d97c3Snir.tzachar@gmail.com 			break;
890692d97c3Snir.tzachar@gmail.com 		default:
891692d97c3Snir.tzachar@gmail.com 			tmp = 2 + strlen(sym_get_string_value(sym));
892692d97c3Snir.tzachar@gmail.com 			item_make(menu, 's', "    (%s)",
893692d97c3Snir.tzachar@gmail.com 				  sym_get_string_value(sym));
894692d97c3Snir.tzachar@gmail.com 			tmp = indent - tmp + 4;
895692d97c3Snir.tzachar@gmail.com 			if (tmp < 0)
896692d97c3Snir.tzachar@gmail.com 				tmp = 0;
897e89b4615SMasahiro Yamada 			item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
898692d97c3Snir.tzachar@gmail.com 				     (sym_has_value(sym) ||
899e89b4615SMasahiro Yamada 				      !sym_is_changeable(sym)) ? "" : " (NEW)");
900692d97c3Snir.tzachar@gmail.com 			goto conf_childs;
901692d97c3Snir.tzachar@gmail.com 		}
902692d97c3Snir.tzachar@gmail.com 		item_add_str("%*c%s%s", indent + 1, ' ',
903694c49a7SSam Ravnborg 				menu_get_prompt(menu),
904baa23ec8SMarco Ammon 				(sym_has_value(sym) || !sym_is_changeable(sym)) ?
905694c49a7SSam Ravnborg 				"" : " (NEW)");
906692d97c3Snir.tzachar@gmail.com 		if (menu->prompt && menu->prompt->type == P_MENU) {
9071278ebdbSDirk Gouders 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");
908692d97c3Snir.tzachar@gmail.com 			return;
909692d97c3Snir.tzachar@gmail.com 		}
910692d97c3Snir.tzachar@gmail.com 	}
911692d97c3Snir.tzachar@gmail.com 
912692d97c3Snir.tzachar@gmail.com conf_childs:
913692d97c3Snir.tzachar@gmail.com 	indent += doint;
914692d97c3Snir.tzachar@gmail.com 	for (child = menu->list; child; child = child->next)
915692d97c3Snir.tzachar@gmail.com 		build_conf(child);
916692d97c3Snir.tzachar@gmail.com 	indent -= doint;
917692d97c3Snir.tzachar@gmail.com }
918692d97c3Snir.tzachar@gmail.com 
reset_menu(void)919692d97c3Snir.tzachar@gmail.com static void reset_menu(void)
920692d97c3Snir.tzachar@gmail.com {
921692d97c3Snir.tzachar@gmail.com 	unpost_menu(curses_menu);
922692d97c3Snir.tzachar@gmail.com 	clean_items();
923692d97c3Snir.tzachar@gmail.com }
924692d97c3Snir.tzachar@gmail.com 
925692d97c3Snir.tzachar@gmail.com /* adjust the menu to show this item.
926692d97c3Snir.tzachar@gmail.com  * prefer not to scroll the menu if possible*/
center_item(int selected_index,int * last_top_row)927692d97c3Snir.tzachar@gmail.com static void center_item(int selected_index, int *last_top_row)
928692d97c3Snir.tzachar@gmail.com {
929692d97c3Snir.tzachar@gmail.com 	int toprow;
930692d97c3Snir.tzachar@gmail.com 
931692d97c3Snir.tzachar@gmail.com 	set_top_row(curses_menu, *last_top_row);
932692d97c3Snir.tzachar@gmail.com 	toprow = top_row(curses_menu);
933a72f3e2bSNir Tzachar 	if (selected_index < toprow ||
934a72f3e2bSNir Tzachar 	    selected_index >= toprow+mwin_max_lines) {
935a72f3e2bSNir Tzachar 		toprow = max(selected_index-mwin_max_lines/2, 0);
936a72f3e2bSNir Tzachar 		if (toprow >= item_count(curses_menu)-mwin_max_lines)
937692d97c3Snir.tzachar@gmail.com 			toprow = item_count(curses_menu)-mwin_max_lines;
938692d97c3Snir.tzachar@gmail.com 		set_top_row(curses_menu, toprow);
939a72f3e2bSNir Tzachar 	}
940692d97c3Snir.tzachar@gmail.com 	set_current_item(curses_menu,
941692d97c3Snir.tzachar@gmail.com 			curses_menu_items[selected_index]);
942692d97c3Snir.tzachar@gmail.com 	*last_top_row = toprow;
943692d97c3Snir.tzachar@gmail.com 	post_menu(curses_menu);
944692d97c3Snir.tzachar@gmail.com 	refresh_all_windows(main_window);
945692d97c3Snir.tzachar@gmail.com }
946692d97c3Snir.tzachar@gmail.com 
947692d97c3Snir.tzachar@gmail.com /* this function assumes reset_menu has been called before */
show_menu(const char * prompt,const char * instructions,int selected_index,int * last_top_row)948692d97c3Snir.tzachar@gmail.com static void show_menu(const char *prompt, const char *instructions,
949692d97c3Snir.tzachar@gmail.com 		int selected_index, int *last_top_row)
950692d97c3Snir.tzachar@gmail.com {
951692d97c3Snir.tzachar@gmail.com 	int maxx, maxy;
952692d97c3Snir.tzachar@gmail.com 	WINDOW *menu_window;
953692d97c3Snir.tzachar@gmail.com 
954692d97c3Snir.tzachar@gmail.com 	current_instructions = instructions;
955692d97c3Snir.tzachar@gmail.com 
956692d97c3Snir.tzachar@gmail.com 	clear();
95708718745SMasahiro Yamada 	print_in_middle(stdscr, 1, getmaxx(stdscr),
958692d97c3Snir.tzachar@gmail.com 			menu_backtitle,
95993487b17SMasahiro Yamada 			attr_main_heading);
960692d97c3Snir.tzachar@gmail.com 
96193487b17SMasahiro Yamada 	wattrset(main_window, attr_main_menu_box);
962692d97c3Snir.tzachar@gmail.com 	box(main_window, 0, 0);
96393487b17SMasahiro Yamada 	wattrset(main_window, attr_main_menu_heading);
964692d97c3Snir.tzachar@gmail.com 	mvwprintw(main_window, 0, 3, " %s ", prompt);
96593487b17SMasahiro Yamada 	wattrset(main_window, attr_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 
adj_match_dir(match_f * match_direction)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  */
do_match(int key,struct match_state * state,int * ans)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);
10489c38f1f0SChangbin Du 	} else if (key == KEY_BACKSPACE || key == 8 || 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 
conf(struct menu * menu)1065692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu)
1066692d97c3Snir.tzachar@gmail.com {
10671ba67cd3SJesse Taube 	selected_conf(menu, NULL);
10681ba67cd3SJesse Taube }
10691ba67cd3SJesse Taube 
selected_conf(struct menu * menu,struct menu * active_menu)10701ba67cd3SJesse Taube static void selected_conf(struct menu *menu, struct menu *active_menu)
10711ba67cd3SJesse Taube {
1072ad818106SRandy Dunlap 	struct menu *submenu = NULL;
1073692d97c3Snir.tzachar@gmail.com 	struct symbol *sym;
10741ba67cd3SJesse Taube 	int i, res;
1075692d97c3Snir.tzachar@gmail.com 	int current_index = 0;
1076692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1077a72f3e2bSNir Tzachar 	struct match_state match_state = {
1078a72f3e2bSNir Tzachar 		.in_search = 0,
1079a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1080a72f3e2bSNir Tzachar 		.pattern = "",
1081a72f3e2bSNir Tzachar 	};
1082692d97c3Snir.tzachar@gmail.com 
1083692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1084692d97c3Snir.tzachar@gmail.com 		reset_menu();
1085692d97c3Snir.tzachar@gmail.com 		current_menu = menu;
1086692d97c3Snir.tzachar@gmail.com 		build_conf(menu);
1087692d97c3Snir.tzachar@gmail.com 		if (!child_count)
1088692d97c3Snir.tzachar@gmail.com 			break;
1089692d97c3Snir.tzachar@gmail.com 
10901ba67cd3SJesse Taube 		if (active_menu != NULL) {
10911ba67cd3SJesse Taube 			for (i = 0; i < items_num; i++) {
10921ba67cd3SJesse Taube 				struct mitem *mcur;
10931ba67cd3SJesse Taube 
10941ba67cd3SJesse Taube 				mcur = (struct mitem *) item_userptr(curses_menu_items[i]);
10951ba67cd3SJesse Taube 				if ((struct menu *) mcur->usrptr == active_menu) {
10961ba67cd3SJesse Taube 					current_index = i;
10971ba67cd3SJesse Taube 					break;
10981ba67cd3SJesse Taube 				}
10991ba67cd3SJesse Taube 			}
11001ba67cd3SJesse Taube 			active_menu = NULL;
11011ba67cd3SJesse Taube 		}
11021ba67cd3SJesse Taube 
110316b0e102SMasahiro Yamada 		show_menu(menu_get_prompt(menu), menu_instructions,
1104692d97c3Snir.tzachar@gmail.com 			  current_index, &last_top_row);
1105692d97c3Snir.tzachar@gmail.com 		keypad((menu_win(curses_menu)), TRUE);
1106a72f3e2bSNir Tzachar 		while (!global_exit) {
1107a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1108a72f3e2bSNir Tzachar 				mvprintw(0, 0,
1109a72f3e2bSNir Tzachar 					"searching: %s", match_state.pattern);
1110a72f3e2bSNir Tzachar 				clrtoeol();
1111a72f3e2bSNir Tzachar 			}
1112a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1113a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1114a72f3e2bSNir Tzachar 			if (!res)
1115a72f3e2bSNir Tzachar 				break;
1116a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &current_index) == 0) {
1117a72f3e2bSNir Tzachar 				if (current_index != -1)
1118a72f3e2bSNir Tzachar 					center_item(current_index,
1119a72f3e2bSNir Tzachar 						    &last_top_row);
1120a72f3e2bSNir Tzachar 				continue;
1121a72f3e2bSNir Tzachar 			}
1122692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(&res,
1123692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1124692d97c3Snir.tzachar@gmail.com 				break;
1125692d97c3Snir.tzachar@gmail.com 			switch (res) {
1126692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
11272bbb4861SIsak Ellmer 			case 'j':
1128692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1129692d97c3Snir.tzachar@gmail.com 				break;
1130692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
11312bbb4861SIsak Ellmer 			case 'k':
1132692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1133692d97c3Snir.tzachar@gmail.com 				break;
1134692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1135692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1136692d97c3Snir.tzachar@gmail.com 				break;
1137692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1138692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1139692d97c3Snir.tzachar@gmail.com 				break;
1140692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1141692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1142692d97c3Snir.tzachar@gmail.com 				break;
1143692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1144692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1145692d97c3Snir.tzachar@gmail.com 				break;
1146692d97c3Snir.tzachar@gmail.com 			case 'h':
1147692d97c3Snir.tzachar@gmail.com 			case '?':
1148692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1149692d97c3Snir.tzachar@gmail.com 				break;
1150692d97c3Snir.tzachar@gmail.com 			}
1151692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 ||
1152692d97c3Snir.tzachar@gmail.com 				res == 32 || res == 'n' || res == 'y' ||
1153692d97c3Snir.tzachar@gmail.com 				res == KEY_LEFT || res == KEY_RIGHT ||
1154a72f3e2bSNir Tzachar 				res == 'm')
1155692d97c3Snir.tzachar@gmail.com 				break;
1156692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1157692d97c3Snir.tzachar@gmail.com 		}
1158692d97c3Snir.tzachar@gmail.com 
1159692d97c3Snir.tzachar@gmail.com 		refresh_all_windows(main_window);
1160692d97c3Snir.tzachar@gmail.com 		/* if ESC or left*/
1161692d97c3Snir.tzachar@gmail.com 		if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1162692d97c3Snir.tzachar@gmail.com 			break;
1163692d97c3Snir.tzachar@gmail.com 
1164692d97c3Snir.tzachar@gmail.com 		/* remember location in the menu */
1165692d97c3Snir.tzachar@gmail.com 		last_top_row = top_row(curses_menu);
1166692d97c3Snir.tzachar@gmail.com 		current_index = curses_item_index();
1167692d97c3Snir.tzachar@gmail.com 
1168692d97c3Snir.tzachar@gmail.com 		if (!item_tag())
1169692d97c3Snir.tzachar@gmail.com 			continue;
1170692d97c3Snir.tzachar@gmail.com 
1171692d97c3Snir.tzachar@gmail.com 		submenu = (struct menu *) item_data();
1172692d97c3Snir.tzachar@gmail.com 		if (!submenu || !menu_is_visible(submenu))
1173692d97c3Snir.tzachar@gmail.com 			continue;
1174692d97c3Snir.tzachar@gmail.com 		sym = submenu->sym;
1175692d97c3Snir.tzachar@gmail.com 
1176692d97c3Snir.tzachar@gmail.com 		switch (res) {
1177692d97c3Snir.tzachar@gmail.com 		case ' ':
1178692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1179692d97c3Snir.tzachar@gmail.com 				sym_toggle_tristate_value(sym);
1180692d97c3Snir.tzachar@gmail.com 			else if (item_is_tag('m'))
1181692d97c3Snir.tzachar@gmail.com 				conf(submenu);
1182692d97c3Snir.tzachar@gmail.com 			break;
1183692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1184692d97c3Snir.tzachar@gmail.com 		case 10: /* ENTER WAS PRESSED */
1185692d97c3Snir.tzachar@gmail.com 			switch (item_tag()) {
1186692d97c3Snir.tzachar@gmail.com 			case 'm':
1187692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode)
1188692d97c3Snir.tzachar@gmail.com 					submenu->data =
1189692d97c3Snir.tzachar@gmail.com 						(void *) (long) !submenu->data;
1190692d97c3Snir.tzachar@gmail.com 				else
1191692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1192692d97c3Snir.tzachar@gmail.com 				break;
1193692d97c3Snir.tzachar@gmail.com 			case 't':
1194692d97c3Snir.tzachar@gmail.com 				if (sym_is_choice(sym) &&
1195692d97c3Snir.tzachar@gmail.com 				    sym_get_tristate_value(sym) == yes)
1196692d97c3Snir.tzachar@gmail.com 					conf_choice(submenu);
1197692d97c3Snir.tzachar@gmail.com 				else if (submenu->prompt &&
1198692d97c3Snir.tzachar@gmail.com 					 submenu->prompt->type == P_MENU)
1199692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1200692d97c3Snir.tzachar@gmail.com 				else if (res == 10)
1201692d97c3Snir.tzachar@gmail.com 					sym_toggle_tristate_value(sym);
1202692d97c3Snir.tzachar@gmail.com 				break;
1203692d97c3Snir.tzachar@gmail.com 			case 's':
1204692d97c3Snir.tzachar@gmail.com 				conf_string(submenu);
1205692d97c3Snir.tzachar@gmail.com 				break;
1206692d97c3Snir.tzachar@gmail.com 			}
1207692d97c3Snir.tzachar@gmail.com 			break;
1208692d97c3Snir.tzachar@gmail.com 		case 'y':
1209692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t')) {
1210692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, yes))
1211692d97c3Snir.tzachar@gmail.com 					break;
1212692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, mod))
1213692d97c3Snir.tzachar@gmail.com 					btn_dialog(main_window, setmod_text, 0);
1214692d97c3Snir.tzachar@gmail.com 			}
1215692d97c3Snir.tzachar@gmail.com 			break;
1216692d97c3Snir.tzachar@gmail.com 		case 'n':
1217692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1218692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, no);
1219692d97c3Snir.tzachar@gmail.com 			break;
1220692d97c3Snir.tzachar@gmail.com 		case 'm':
1221692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1222692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, mod);
1223692d97c3Snir.tzachar@gmail.com 			break;
1224692d97c3Snir.tzachar@gmail.com 		}
1225692d97c3Snir.tzachar@gmail.com 	}
1226692d97c3Snir.tzachar@gmail.com }
1227692d97c3Snir.tzachar@gmail.com 
conf_message_callback(const char * s)12285accd7f3SMasahiro Yamada static void conf_message_callback(const char *s)
122942368c37SMichal Marek {
12305accd7f3SMasahiro Yamada 	btn_dialog(main_window, s, 1, "<OK>");
123142368c37SMichal Marek }
123242368c37SMichal Marek 
show_help(struct menu * menu)1233692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu)
1234692d97c3Snir.tzachar@gmail.com {
1235f98ee769SArnaud Lacombe 	struct gstr help;
1236f98ee769SArnaud Lacombe 
1237f98ee769SArnaud Lacombe 	if (!menu)
1238f98ee769SArnaud Lacombe 		return;
1239f98ee769SArnaud Lacombe 
1240f98ee769SArnaud Lacombe 	help = str_new();
124154168578SArnaud Lacombe 	menu_get_ext_help(menu, &help);
1242694c49a7SSam Ravnborg 	show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help));
1243692d97c3Snir.tzachar@gmail.com 	str_free(&help);
1244692d97c3Snir.tzachar@gmail.com }
1245692d97c3Snir.tzachar@gmail.com 
conf_choice(struct menu * menu)1246692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu)
1247692d97c3Snir.tzachar@gmail.com {
1248694c49a7SSam Ravnborg 	const char *prompt = menu_get_prompt(menu);
1249ad818106SRandy Dunlap 	struct menu *child = NULL;
1250692d97c3Snir.tzachar@gmail.com 	struct symbol *active;
1251692d97c3Snir.tzachar@gmail.com 	int selected_index = 0;
1252692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1253692d97c3Snir.tzachar@gmail.com 	int res, i = 0;
1254a72f3e2bSNir Tzachar 	struct match_state match_state = {
1255a72f3e2bSNir Tzachar 		.in_search = 0,
1256a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1257a72f3e2bSNir Tzachar 		.pattern = "",
1258a72f3e2bSNir Tzachar 	};
1259692d97c3Snir.tzachar@gmail.com 
1260692d97c3Snir.tzachar@gmail.com 	active = sym_get_choice_value(menu->sym);
1261692d97c3Snir.tzachar@gmail.com 	/* this is mostly duplicated from the conf() function. */
1262692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1263692d97c3Snir.tzachar@gmail.com 		reset_menu();
1264692d97c3Snir.tzachar@gmail.com 
1265692d97c3Snir.tzachar@gmail.com 		for (i = 0, child = menu->list; child; child = child->next) {
1266692d97c3Snir.tzachar@gmail.com 			if (!show_all_items && !menu_is_visible(child))
1267692d97c3Snir.tzachar@gmail.com 				continue;
1268692d97c3Snir.tzachar@gmail.com 
1269692d97c3Snir.tzachar@gmail.com 			if (child->sym == sym_get_choice_value(menu->sym))
1270692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "<X> %s",
1271694c49a7SSam Ravnborg 						menu_get_prompt(child));
127239177ec3SPeter Korsgaard 			else if (child->sym)
1273692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "    %s",
1274694c49a7SSam Ravnborg 						menu_get_prompt(child));
127539177ec3SPeter Korsgaard 			else
127639177ec3SPeter Korsgaard 				item_make(child, ':', "*** %s ***",
1277694c49a7SSam Ravnborg 						menu_get_prompt(child));
127839177ec3SPeter Korsgaard 
1279692d97c3Snir.tzachar@gmail.com 			if (child->sym == active){
1280692d97c3Snir.tzachar@gmail.com 				last_top_row = top_row(curses_menu);
1281692d97c3Snir.tzachar@gmail.com 				selected_index = i;
1282692d97c3Snir.tzachar@gmail.com 			}
1283692d97c3Snir.tzachar@gmail.com 			i++;
1284692d97c3Snir.tzachar@gmail.com 		}
1285694c49a7SSam Ravnborg 		show_menu(prompt ? prompt : "Choice Menu",
1286694c49a7SSam Ravnborg 				radiolist_instructions,
1287692d97c3Snir.tzachar@gmail.com 				selected_index,
1288692d97c3Snir.tzachar@gmail.com 				&last_top_row);
1289a72f3e2bSNir Tzachar 		while (!global_exit) {
1290a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1291a72f3e2bSNir Tzachar 				mvprintw(0, 0, "searching: %s",
1292a72f3e2bSNir Tzachar 					 match_state.pattern);
1293a72f3e2bSNir Tzachar 				clrtoeol();
1294a72f3e2bSNir Tzachar 			}
1295a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1296a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1297a72f3e2bSNir Tzachar 			if (!res)
1298a72f3e2bSNir Tzachar 				break;
1299a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &selected_index) == 0) {
1300a72f3e2bSNir Tzachar 				if (selected_index != -1)
1301a72f3e2bSNir Tzachar 					center_item(selected_index,
1302a72f3e2bSNir Tzachar 						    &last_top_row);
1303a72f3e2bSNir Tzachar 				continue;
1304a72f3e2bSNir Tzachar 			}
1305692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(
1306692d97c3Snir.tzachar@gmail.com 						&res,
1307692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1308692d97c3Snir.tzachar@gmail.com 				break;
1309692d97c3Snir.tzachar@gmail.com 			switch (res) {
1310692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
13112bbb4861SIsak Ellmer 			case 'j':
1312692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1313692d97c3Snir.tzachar@gmail.com 				break;
1314692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
13152bbb4861SIsak Ellmer 			case 'k':
1316692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1317692d97c3Snir.tzachar@gmail.com 				break;
1318692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1319692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1320692d97c3Snir.tzachar@gmail.com 				break;
1321692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1322692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1323692d97c3Snir.tzachar@gmail.com 				break;
1324692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1325692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1326692d97c3Snir.tzachar@gmail.com 				break;
1327692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1328692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1329692d97c3Snir.tzachar@gmail.com 				break;
1330692d97c3Snir.tzachar@gmail.com 			case 'h':
1331692d97c3Snir.tzachar@gmail.com 			case '?':
1332692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1333692d97c3Snir.tzachar@gmail.com 				break;
1334692d97c3Snir.tzachar@gmail.com 			}
1335692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 || res == ' ' ||
1336a72f3e2bSNir Tzachar 					res == KEY_LEFT){
1337692d97c3Snir.tzachar@gmail.com 				break;
1338692d97c3Snir.tzachar@gmail.com 			}
1339692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1340692d97c3Snir.tzachar@gmail.com 		}
1341692d97c3Snir.tzachar@gmail.com 		/* if ESC or left */
1342692d97c3Snir.tzachar@gmail.com 		if (res == 27 || res == KEY_LEFT)
1343692d97c3Snir.tzachar@gmail.com 			break;
1344692d97c3Snir.tzachar@gmail.com 
1345692d97c3Snir.tzachar@gmail.com 		child = item_data();
134639177ec3SPeter Korsgaard 		if (!child || !menu_is_visible(child) || !child->sym)
1347692d97c3Snir.tzachar@gmail.com 			continue;
1348692d97c3Snir.tzachar@gmail.com 		switch (res) {
1349692d97c3Snir.tzachar@gmail.com 		case ' ':
1350692d97c3Snir.tzachar@gmail.com 		case  10:
1351692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1352692d97c3Snir.tzachar@gmail.com 			sym_set_tristate_value(child->sym, yes);
1353692d97c3Snir.tzachar@gmail.com 			return;
1354692d97c3Snir.tzachar@gmail.com 		case 'h':
1355692d97c3Snir.tzachar@gmail.com 		case '?':
1356692d97c3Snir.tzachar@gmail.com 			show_help(child);
1357692d97c3Snir.tzachar@gmail.com 			active = child->sym;
1358692d97c3Snir.tzachar@gmail.com 			break;
1359692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1360692d97c3Snir.tzachar@gmail.com 			return;
1361692d97c3Snir.tzachar@gmail.com 		}
1362692d97c3Snir.tzachar@gmail.com 	}
1363692d97c3Snir.tzachar@gmail.com }
1364692d97c3Snir.tzachar@gmail.com 
conf_string(struct menu * menu)1365692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu)
1366692d97c3Snir.tzachar@gmail.com {
1367692d97c3Snir.tzachar@gmail.com 	const char *prompt = menu_get_prompt(menu);
1368692d97c3Snir.tzachar@gmail.com 
1369692d97c3Snir.tzachar@gmail.com 	while (1) {
1370692d97c3Snir.tzachar@gmail.com 		int res;
1371692d97c3Snir.tzachar@gmail.com 		const char *heading;
1372692d97c3Snir.tzachar@gmail.com 
1373692d97c3Snir.tzachar@gmail.com 		switch (sym_get_type(menu->sym)) {
1374692d97c3Snir.tzachar@gmail.com 		case S_INT:
1375694c49a7SSam Ravnborg 			heading = inputbox_instructions_int;
1376692d97c3Snir.tzachar@gmail.com 			break;
1377692d97c3Snir.tzachar@gmail.com 		case S_HEX:
1378694c49a7SSam Ravnborg 			heading = inputbox_instructions_hex;
1379692d97c3Snir.tzachar@gmail.com 			break;
1380692d97c3Snir.tzachar@gmail.com 		case S_STRING:
1381694c49a7SSam Ravnborg 			heading = inputbox_instructions_string;
1382692d97c3Snir.tzachar@gmail.com 			break;
1383692d97c3Snir.tzachar@gmail.com 		default:
1384694c49a7SSam Ravnborg 			heading = "Internal nconf error!";
1385692d97c3Snir.tzachar@gmail.com 		}
1386692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1387694c49a7SSam Ravnborg 				prompt ? prompt : "Main Menu",
1388692d97c3Snir.tzachar@gmail.com 				heading,
1389692d97c3Snir.tzachar@gmail.com 				sym_get_string_value(menu->sym),
13905ea9f64fSCheng Renquan 				&dialog_input_result,
13915ea9f64fSCheng Renquan 				&dialog_input_result_len);
1392692d97c3Snir.tzachar@gmail.com 		switch (res) {
1393692d97c3Snir.tzachar@gmail.com 		case 0:
1394692d97c3Snir.tzachar@gmail.com 			if (sym_set_string_value(menu->sym,
1395692d97c3Snir.tzachar@gmail.com 						dialog_input_result))
1396692d97c3Snir.tzachar@gmail.com 				return;
1397692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window,
1398694c49a7SSam Ravnborg 				"You have made an invalid entry.", 0);
1399692d97c3Snir.tzachar@gmail.com 			break;
1400692d97c3Snir.tzachar@gmail.com 		case 1:
1401692d97c3Snir.tzachar@gmail.com 			show_help(menu);
1402692d97c3Snir.tzachar@gmail.com 			break;
1403692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1404692d97c3Snir.tzachar@gmail.com 			return;
1405692d97c3Snir.tzachar@gmail.com 		}
1406692d97c3Snir.tzachar@gmail.com 	}
1407692d97c3Snir.tzachar@gmail.com }
1408692d97c3Snir.tzachar@gmail.com 
conf_load(void)1409692d97c3Snir.tzachar@gmail.com static void conf_load(void)
1410692d97c3Snir.tzachar@gmail.com {
1411692d97c3Snir.tzachar@gmail.com 	while (1) {
1412692d97c3Snir.tzachar@gmail.com 		int res;
1413692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1414692d97c3Snir.tzachar@gmail.com 				NULL, load_config_text,
1415692d97c3Snir.tzachar@gmail.com 				filename,
14165ea9f64fSCheng Renquan 				&dialog_input_result,
14175ea9f64fSCheng Renquan 				&dialog_input_result_len);
1418692d97c3Snir.tzachar@gmail.com 		switch (res) {
1419692d97c3Snir.tzachar@gmail.com 		case 0:
1420692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1421692d97c3Snir.tzachar@gmail.com 				return;
1422692d97c3Snir.tzachar@gmail.com 			if (!conf_read(dialog_input_result)) {
1423692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
14245ee54659SMasahiro Yamada 				conf_set_changed(true);
1425692d97c3Snir.tzachar@gmail.com 				return;
1426692d97c3Snir.tzachar@gmail.com 			}
1427694c49a7SSam Ravnborg 			btn_dialog(main_window, "File does not exist!", 0);
1428692d97c3Snir.tzachar@gmail.com 			break;
1429692d97c3Snir.tzachar@gmail.com 		case 1:
1430692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1431694c49a7SSam Ravnborg 					"Load Alternate Configuration",
1432692d97c3Snir.tzachar@gmail.com 					load_config_help);
1433692d97c3Snir.tzachar@gmail.com 			break;
1434692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1435692d97c3Snir.tzachar@gmail.com 			return;
1436692d97c3Snir.tzachar@gmail.com 		}
1437692d97c3Snir.tzachar@gmail.com 	}
1438692d97c3Snir.tzachar@gmail.com }
1439692d97c3Snir.tzachar@gmail.com 
conf_save(void)1440692d97c3Snir.tzachar@gmail.com static void conf_save(void)
1441692d97c3Snir.tzachar@gmail.com {
1442692d97c3Snir.tzachar@gmail.com 	while (1) {
1443692d97c3Snir.tzachar@gmail.com 		int res;
1444692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1445692d97c3Snir.tzachar@gmail.com 				NULL, save_config_text,
1446692d97c3Snir.tzachar@gmail.com 				filename,
14475ea9f64fSCheng Renquan 				&dialog_input_result,
14485ea9f64fSCheng Renquan 				&dialog_input_result_len);
1449692d97c3Snir.tzachar@gmail.com 		switch (res) {
1450692d97c3Snir.tzachar@gmail.com 		case 0:
1451692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1452692d97c3Snir.tzachar@gmail.com 				return;
1453692d97c3Snir.tzachar@gmail.com 			res = conf_write(dialog_input_result);
1454692d97c3Snir.tzachar@gmail.com 			if (!res) {
1455692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
1456692d97c3Snir.tzachar@gmail.com 				return;
1457692d97c3Snir.tzachar@gmail.com 			}
1458580c5b3eSMasahiro Yamada 			btn_dialog(main_window, "Can't create file!",
1459692d97c3Snir.tzachar@gmail.com 				1, "<OK>");
1460692d97c3Snir.tzachar@gmail.com 			break;
1461692d97c3Snir.tzachar@gmail.com 		case 1:
1462692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1463694c49a7SSam Ravnborg 				"Save Alternate Configuration",
1464692d97c3Snir.tzachar@gmail.com 				save_config_help);
1465692d97c3Snir.tzachar@gmail.com 			break;
1466692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1467692d97c3Snir.tzachar@gmail.com 			return;
1468692d97c3Snir.tzachar@gmail.com 		}
1469692d97c3Snir.tzachar@gmail.com 	}
1470692d97c3Snir.tzachar@gmail.com }
1471692d97c3Snir.tzachar@gmail.com 
setup_windows(void)1472ad818106SRandy Dunlap static void setup_windows(void)
1473692d97c3Snir.tzachar@gmail.com {
1474e0b42605SDirk Gouders 	int lines, columns;
1475e0b42605SDirk Gouders 
1476e0b42605SDirk Gouders 	getmaxyx(stdscr, lines, columns);
1477e0b42605SDirk Gouders 
1478692d97c3Snir.tzachar@gmail.com 	if (main_window != NULL)
1479692d97c3Snir.tzachar@gmail.com 		delwin(main_window);
1480692d97c3Snir.tzachar@gmail.com 
1481692d97c3Snir.tzachar@gmail.com 	/* set up the menu and menu window */
1482e0b42605SDirk Gouders 	main_window = newwin(lines-2, columns-2, 2, 1);
1483692d97c3Snir.tzachar@gmail.com 	keypad(main_window, TRUE);
1484e0b42605SDirk Gouders 	mwin_max_lines = lines-7;
1485e0b42605SDirk Gouders 	mwin_max_cols = columns-6;
1486692d97c3Snir.tzachar@gmail.com 
1487692d97c3Snir.tzachar@gmail.com 	/* panels order is from bottom to top */
1488692d97c3Snir.tzachar@gmail.com 	new_panel(main_window);
1489692d97c3Snir.tzachar@gmail.com }
1490692d97c3Snir.tzachar@gmail.com 
main(int ac,char ** av)1491692d97c3Snir.tzachar@gmail.com int main(int ac, char **av)
1492692d97c3Snir.tzachar@gmail.com {
1493e0b42605SDirk Gouders 	int lines, columns;
1494692d97c3Snir.tzachar@gmail.com 	char *mode;
1495692d97c3Snir.tzachar@gmail.com 
14960a1f00a1SMichal Marek 	if (ac > 1 && strcmp(av[1], "-s") == 0) {
14970a1f00a1SMichal Marek 		/* Silence conf_read() until the real callback is set up */
14980a1f00a1SMichal Marek 		conf_set_message_callback(NULL);
14990a1f00a1SMichal Marek 		av++;
15000a1f00a1SMichal Marek 	}
1501692d97c3Snir.tzachar@gmail.com 	conf_parse(av[1]);
1502692d97c3Snir.tzachar@gmail.com 	conf_read(NULL);
1503692d97c3Snir.tzachar@gmail.com 
1504692d97c3Snir.tzachar@gmail.com 	mode = getenv("NCONFIG_MODE");
1505692d97c3Snir.tzachar@gmail.com 	if (mode) {
1506692d97c3Snir.tzachar@gmail.com 		if (!strcasecmp(mode, "single_menu"))
1507692d97c3Snir.tzachar@gmail.com 			single_menu_mode = 1;
1508692d97c3Snir.tzachar@gmail.com 	}
1509692d97c3Snir.tzachar@gmail.com 
1510692d97c3Snir.tzachar@gmail.com 	/* Initialize curses */
1511692d97c3Snir.tzachar@gmail.com 	initscr();
1512692d97c3Snir.tzachar@gmail.com 	/* set color theme */
1513692d97c3Snir.tzachar@gmail.com 	set_colors();
1514692d97c3Snir.tzachar@gmail.com 
1515692d97c3Snir.tzachar@gmail.com 	cbreak();
1516692d97c3Snir.tzachar@gmail.com 	noecho();
1517692d97c3Snir.tzachar@gmail.com 	keypad(stdscr, TRUE);
1518692d97c3Snir.tzachar@gmail.com 	curs_set(0);
1519692d97c3Snir.tzachar@gmail.com 
1520e0b42605SDirk Gouders 	getmaxyx(stdscr, lines, columns);
1521e0b42605SDirk Gouders 	if (columns < 75 || lines < 20) {
1522692d97c3Snir.tzachar@gmail.com 		endwin();
1523692d97c3Snir.tzachar@gmail.com 		printf("Your terminal should have at "
1524692d97c3Snir.tzachar@gmail.com 			"least 20 lines and 75 columns\n");
1525692d97c3Snir.tzachar@gmail.com 		return 1;
1526692d97c3Snir.tzachar@gmail.com 	}
1527692d97c3Snir.tzachar@gmail.com 
1528692d97c3Snir.tzachar@gmail.com 	notimeout(stdscr, FALSE);
1529d7c67a2eSYaakov Selkowitz #if NCURSES_REENTRANT
1530d7c67a2eSYaakov Selkowitz 	set_escdelay(1);
1531d7c67a2eSYaakov Selkowitz #else
1532692d97c3Snir.tzachar@gmail.com 	ESCDELAY = 1;
1533d7c67a2eSYaakov Selkowitz #endif
1534692d97c3Snir.tzachar@gmail.com 
1535692d97c3Snir.tzachar@gmail.com 	/* set btns menu */
1536692d97c3Snir.tzachar@gmail.com 	curses_menu = new_menu(curses_menu_items);
1537692d97c3Snir.tzachar@gmail.com 	menu_opts_off(curses_menu, O_SHOWDESC);
1538a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_SHOWMATCH);
1539692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_ONEVALUE);
1540692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_NONCYCLIC);
1541a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_IGNORECASE);
1542692d97c3Snir.tzachar@gmail.com 	set_menu_mark(curses_menu, " ");
154393487b17SMasahiro Yamada 	set_menu_fore(curses_menu, attr_main_menu_fore);
154493487b17SMasahiro Yamada 	set_menu_back(curses_menu, attr_main_menu_back);
154593487b17SMasahiro Yamada 	set_menu_grey(curses_menu, attr_main_menu_grey);
1546692d97c3Snir.tzachar@gmail.com 
1547692d97c3Snir.tzachar@gmail.com 	set_config_filename(conf_get_configname());
1548692d97c3Snir.tzachar@gmail.com 	setup_windows();
1549692d97c3Snir.tzachar@gmail.com 
1550692d97c3Snir.tzachar@gmail.com 	/* check for KEY_FUNC(1) */
1551692d97c3Snir.tzachar@gmail.com 	if (has_key(KEY_F(1)) == FALSE) {
1552692d97c3Snir.tzachar@gmail.com 		show_scroll_win(main_window,
1553694c49a7SSam Ravnborg 				"Instructions",
1554694c49a7SSam Ravnborg 				menu_no_f_instructions);
1555692d97c3Snir.tzachar@gmail.com 	}
1556692d97c3Snir.tzachar@gmail.com 
155742368c37SMichal Marek 	conf_set_message_callback(conf_message_callback);
1558692d97c3Snir.tzachar@gmail.com 	/* do the work */
1559692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1560692d97c3Snir.tzachar@gmail.com 		conf(&rootmenu);
1561692d97c3Snir.tzachar@gmail.com 		if (!global_exit && do_exit() == 0)
1562692d97c3Snir.tzachar@gmail.com 			break;
1563692d97c3Snir.tzachar@gmail.com 	}
1564692d97c3Snir.tzachar@gmail.com 	/* ok, we are done */
1565692d97c3Snir.tzachar@gmail.com 	unpost_menu(curses_menu);
1566692d97c3Snir.tzachar@gmail.com 	free_menu(curses_menu);
1567692d97c3Snir.tzachar@gmail.com 	delwin(main_window);
1568692d97c3Snir.tzachar@gmail.com 	clear();
1569692d97c3Snir.tzachar@gmail.com 	refresh();
1570692d97c3Snir.tzachar@gmail.com 	endwin();
1571692d97c3Snir.tzachar@gmail.com 	return 0;
1572692d97c3Snir.tzachar@gmail.com }
1573