xref: /rk3399_rockchip-uboot/scripts/kconfig/nconf.c (revision 9b5f0b1da9ba7019316ed8c9698fe25e8c7fc33e)
10a9064fbSMasahiro Yamada /*
20a9064fbSMasahiro Yamada  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
30a9064fbSMasahiro Yamada  * Released under the terms of the GNU GPL v2.0.
40a9064fbSMasahiro Yamada  *
50a9064fbSMasahiro Yamada  * Derived from menuconfig.
60a9064fbSMasahiro Yamada  *
70a9064fbSMasahiro Yamada  */
80a9064fbSMasahiro Yamada #define _GNU_SOURCE
90a9064fbSMasahiro Yamada #include <string.h>
100a9064fbSMasahiro Yamada #include <stdlib.h>
110a9064fbSMasahiro Yamada 
120a9064fbSMasahiro Yamada #include "lkc.h"
130a9064fbSMasahiro Yamada #include "nconf.h"
140a9064fbSMasahiro Yamada #include <ctype.h>
150a9064fbSMasahiro Yamada 
160a9064fbSMasahiro Yamada static const char nconf_global_help[] = N_(
170a9064fbSMasahiro Yamada "Help windows\n"
180a9064fbSMasahiro Yamada "------------\n"
190a9064fbSMasahiro Yamada "o  Global help:  Unless in a data entry window, pressing <F1> will give \n"
200a9064fbSMasahiro Yamada "   you the global help window, which you are just reading.\n"
210a9064fbSMasahiro Yamada "\n"
220a9064fbSMasahiro Yamada "o  A short version of the global help is available by pressing <F3>.\n"
230a9064fbSMasahiro Yamada "\n"
240a9064fbSMasahiro Yamada "o  Local help:  To get help related to the current menu entry, use any\n"
250a9064fbSMasahiro Yamada "   of <?> <h>, or if in a data entry window then press <F1>.\n"
260a9064fbSMasahiro Yamada "\n"
270a9064fbSMasahiro Yamada "\n"
280a9064fbSMasahiro Yamada "Menu entries\n"
290a9064fbSMasahiro Yamada "------------\n"
300a9064fbSMasahiro Yamada "This interface lets you select features and parameters for the kernel\n"
310a9064fbSMasahiro Yamada "build.  Kernel features can either be built-in, modularized, or removed.\n"
320a9064fbSMasahiro Yamada "Parameters must be entered as text or decimal or hexadecimal numbers.\n"
330a9064fbSMasahiro Yamada "\n"
340a9064fbSMasahiro Yamada "Menu entries beginning with following braces represent features that\n"
350a9064fbSMasahiro Yamada "  [ ]  can be built in or removed\n"
360a9064fbSMasahiro Yamada "  < >  can be built in, modularized or removed\n"
370a9064fbSMasahiro Yamada "  { }  can be built in or modularized, are selected by another feature\n"
380a9064fbSMasahiro Yamada "  - -  are selected by another feature\n"
390a9064fbSMasahiro Yamada "  XXX  cannot be selected.  Symbol Info <F2> tells you why.\n"
400a9064fbSMasahiro Yamada "*, M or whitespace inside braces means to build in, build as a module\n"
410a9064fbSMasahiro Yamada "or to exclude the feature respectively.\n"
420a9064fbSMasahiro Yamada "\n"
430a9064fbSMasahiro Yamada "To change any of these features, highlight it with the movement keys\n"
440a9064fbSMasahiro Yamada "listed below and press <y> to build it in, <m> to make it a module or\n"
450a9064fbSMasahiro Yamada "<n> to remove it.  You may press the <Space> key to cycle through the\n"
460a9064fbSMasahiro Yamada "available options.\n"
470a9064fbSMasahiro Yamada "\n"
480a9064fbSMasahiro Yamada "A trailing \"--->\" designates a submenu, a trailing \"----\" an\n"
490a9064fbSMasahiro Yamada "empty submenu.\n"
500a9064fbSMasahiro Yamada "\n"
510a9064fbSMasahiro Yamada "Menu navigation keys\n"
520a9064fbSMasahiro Yamada "----------------------------------------------------------------------\n"
530a9064fbSMasahiro Yamada "Linewise up                 <Up>\n"
540a9064fbSMasahiro Yamada "Linewise down               <Down>\n"
550a9064fbSMasahiro Yamada "Pagewise up                 <Page Up>\n"
560a9064fbSMasahiro Yamada "Pagewise down               <Page Down>\n"
570a9064fbSMasahiro Yamada "First entry                 <Home>\n"
580a9064fbSMasahiro Yamada "Last entry                  <End>\n"
590a9064fbSMasahiro Yamada "Enter a submenu             <Right>  <Enter>\n"
600a9064fbSMasahiro Yamada "Go back to parent menu      <Left>   <Esc>  <F5>\n"
610a9064fbSMasahiro Yamada "Close a help window         <Enter>  <Esc>  <F5>\n"
620a9064fbSMasahiro Yamada "Close entry window, apply   <Enter>\n"
630a9064fbSMasahiro Yamada "Close entry window, forget  <Esc>  <F5>\n"
640a9064fbSMasahiro Yamada "Start incremental, case-insensitive search for STRING in menu entries,\n"
650a9064fbSMasahiro Yamada "    no regex support, STRING is displayed in upper left corner\n"
660a9064fbSMasahiro Yamada "                            </>STRING\n"
670a9064fbSMasahiro Yamada "    Remove last character   <Backspace>\n"
680a9064fbSMasahiro Yamada "    Jump to next hit        <Down>\n"
690a9064fbSMasahiro Yamada "    Jump to previous hit    <Up>\n"
700a9064fbSMasahiro Yamada "Exit menu search mode       </>  <Esc>\n"
710a9064fbSMasahiro Yamada "Search for configuration variables with or without leading CONFIG_\n"
720a9064fbSMasahiro Yamada "                            <F8>RegExpr<Enter>\n"
730a9064fbSMasahiro Yamada "Verbose search help         <F8><F1>\n"
740a9064fbSMasahiro Yamada "----------------------------------------------------------------------\n"
750a9064fbSMasahiro Yamada "\n"
760a9064fbSMasahiro Yamada "Unless in a data entry window, key <1> may be used instead of <F1>,\n"
770a9064fbSMasahiro Yamada "<2> instead of <F2>, etc.\n"
780a9064fbSMasahiro Yamada "\n"
790a9064fbSMasahiro Yamada "\n"
800a9064fbSMasahiro Yamada "Radiolist (Choice list)\n"
810a9064fbSMasahiro Yamada "-----------------------\n"
820a9064fbSMasahiro Yamada "Use the movement keys listed above to select the option you wish to set\n"
830a9064fbSMasahiro Yamada "and press <Space>.\n"
840a9064fbSMasahiro Yamada "\n"
850a9064fbSMasahiro Yamada "\n"
860a9064fbSMasahiro Yamada "Data entry\n"
870a9064fbSMasahiro Yamada "----------\n"
880a9064fbSMasahiro Yamada "Enter the requested information and press <Enter>.  Hexadecimal values\n"
890a9064fbSMasahiro Yamada "may be entered without the \"0x\" prefix.\n"
900a9064fbSMasahiro Yamada "\n"
910a9064fbSMasahiro Yamada "\n"
920a9064fbSMasahiro Yamada "Text Box (Help Window)\n"
930a9064fbSMasahiro Yamada "----------------------\n"
940a9064fbSMasahiro Yamada "Use movement keys as listed in table above.\n"
950a9064fbSMasahiro Yamada "\n"
960a9064fbSMasahiro Yamada "Press any of <Enter> <Esc> <q> <F5> <F9> to exit.\n"
970a9064fbSMasahiro Yamada "\n"
980a9064fbSMasahiro Yamada "\n"
990a9064fbSMasahiro Yamada "Alternate configuration files\n"
1000a9064fbSMasahiro Yamada "-----------------------------\n"
1010a9064fbSMasahiro Yamada "nconfig supports switching between different configurations.\n"
1020a9064fbSMasahiro Yamada "Press <F6> to save your current configuration.  Press <F7> and enter\n"
1030a9064fbSMasahiro Yamada "a file name to load a previously saved configuration.\n"
1040a9064fbSMasahiro Yamada "\n"
1050a9064fbSMasahiro Yamada "\n"
1060a9064fbSMasahiro Yamada "Terminal configuration\n"
1070a9064fbSMasahiro Yamada "----------------------\n"
1080a9064fbSMasahiro Yamada "If you use nconfig in a xterm window, make sure your TERM environment\n"
1090a9064fbSMasahiro Yamada "variable specifies a terminal configuration which supports at least\n"
1100a9064fbSMasahiro Yamada "16 colors.  Otherwise nconfig will look rather bad.\n"
1110a9064fbSMasahiro Yamada "\n"
1120a9064fbSMasahiro Yamada "If the \"stty size\" command reports the current terminalsize correctly,\n"
1130a9064fbSMasahiro Yamada "nconfig will adapt to sizes larger than the traditional 80x25 \"standard\"\n"
1140a9064fbSMasahiro Yamada "and display longer menus properly.\n"
1150a9064fbSMasahiro Yamada "\n"
1160a9064fbSMasahiro Yamada "\n"
1170a9064fbSMasahiro Yamada "Single menu mode\n"
1180a9064fbSMasahiro Yamada "----------------\n"
1190a9064fbSMasahiro Yamada "If you prefer to have all of the menu entries listed in a single menu,\n"
1200a9064fbSMasahiro Yamada "rather than the default multimenu hierarchy, run nconfig with\n"
1210a9064fbSMasahiro Yamada "NCONFIG_MODE environment variable set to single_menu.  Example:\n"
1220a9064fbSMasahiro Yamada "\n"
1230a9064fbSMasahiro Yamada "make NCONFIG_MODE=single_menu nconfig\n"
1240a9064fbSMasahiro Yamada "\n"
1250a9064fbSMasahiro Yamada "<Enter> will then unfold the appropriate category, or fold it if it\n"
1260a9064fbSMasahiro Yamada "is already unfolded.  Folded menu entries will be designated by a\n"
1270a9064fbSMasahiro Yamada "leading \"++>\" and unfolded entries by a leading \"-->\".\n"
1280a9064fbSMasahiro Yamada "\n"
1290a9064fbSMasahiro Yamada "Note that this mode can eventually be a little more CPU expensive than\n"
1300a9064fbSMasahiro Yamada "the default mode, especially with a larger number of unfolded submenus.\n"
1310a9064fbSMasahiro Yamada "\n"),
1320a9064fbSMasahiro Yamada menu_no_f_instructions[] = N_(
1330a9064fbSMasahiro Yamada "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1340a9064fbSMasahiro Yamada "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
1350a9064fbSMasahiro Yamada "\n"
1360a9064fbSMasahiro Yamada "Use the following keys to navigate the menus:\n"
1370a9064fbSMasahiro Yamada "Move up or down with <Up> and <Down>.\n"
1380a9064fbSMasahiro Yamada "Enter a submenu with <Enter> or <Right>.\n"
1390a9064fbSMasahiro Yamada "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1400a9064fbSMasahiro Yamada "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1410a9064fbSMasahiro Yamada "Pressing <Space> cycles through the available options.\n"
1420a9064fbSMasahiro Yamada "To search for menu entries press </>.\n"
1430a9064fbSMasahiro Yamada "<Esc> always leaves the current window.\n"
1440a9064fbSMasahiro Yamada "\n"
1450a9064fbSMasahiro Yamada "You do not have function keys support.\n"
1460a9064fbSMasahiro Yamada "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
1470a9064fbSMasahiro Yamada "For verbose global help use key <1>.\n"
1480a9064fbSMasahiro Yamada "For help related to the current menu entry press <?> or <h>.\n"),
1490a9064fbSMasahiro Yamada menu_instructions[] = N_(
1500a9064fbSMasahiro Yamada "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1510a9064fbSMasahiro Yamada "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
1520a9064fbSMasahiro Yamada "\n"
1530a9064fbSMasahiro Yamada "Use the following keys to navigate the menus:\n"
1540a9064fbSMasahiro Yamada "Move up or down with <Up> or <Down>.\n"
1550a9064fbSMasahiro Yamada "Enter a submenu with <Enter> or <Right>.\n"
1560a9064fbSMasahiro Yamada "Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1570a9064fbSMasahiro Yamada "Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1580a9064fbSMasahiro Yamada "Pressing <Space> cycles through the available options.\n"
1590a9064fbSMasahiro Yamada "To search for menu entries press </>.\n"
1600a9064fbSMasahiro Yamada "<Esc> always leaves the current window.\n"
1610a9064fbSMasahiro Yamada "\n"
1620a9064fbSMasahiro Yamada "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
1630a9064fbSMasahiro Yamada "For verbose global help press <F1>.\n"
1640a9064fbSMasahiro Yamada "For help related to the current menu entry press <?> or <h>.\n"),
1650a9064fbSMasahiro Yamada radiolist_instructions[] = N_(
1660a9064fbSMasahiro Yamada "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
1670a9064fbSMasahiro Yamada "with <Space>.\n"
1680a9064fbSMasahiro Yamada "For help related to the current entry press <?> or <h>.\n"
1690a9064fbSMasahiro Yamada "For global help press <F1>.\n"),
1700a9064fbSMasahiro Yamada inputbox_instructions_int[] = N_(
1710a9064fbSMasahiro Yamada "Please enter a decimal value.\n"
1720a9064fbSMasahiro Yamada "Fractions will not be accepted.\n"
1730a9064fbSMasahiro Yamada "Press <Enter> to apply, <Esc> to cancel."),
1740a9064fbSMasahiro Yamada inputbox_instructions_hex[] = N_(
1750a9064fbSMasahiro Yamada "Please enter a hexadecimal value.\n"
1760a9064fbSMasahiro Yamada "Press <Enter> to apply, <Esc> to cancel."),
1770a9064fbSMasahiro Yamada inputbox_instructions_string[] = N_(
1780a9064fbSMasahiro Yamada "Please enter a string value.\n"
1790a9064fbSMasahiro Yamada "Press <Enter> to apply, <Esc> to cancel."),
1800a9064fbSMasahiro Yamada setmod_text[] = N_(
1810a9064fbSMasahiro Yamada "This feature depends on another feature which has been configured as a\n"
1820a9064fbSMasahiro Yamada "module.  As a result, the current feature will be built as a module too."),
1830a9064fbSMasahiro Yamada load_config_text[] = N_(
1840a9064fbSMasahiro Yamada "Enter the name of the configuration file you wish to load.\n"
1850a9064fbSMasahiro Yamada "Accept the name shown to restore the configuration you last\n"
1860a9064fbSMasahiro Yamada "retrieved.  Leave empty to abort."),
1870a9064fbSMasahiro Yamada load_config_help[] = N_(
1880a9064fbSMasahiro Yamada "For various reasons, one may wish to keep several different\n"
1890a9064fbSMasahiro Yamada "configurations available on a single machine.\n"
1900a9064fbSMasahiro Yamada "\n"
1910a9064fbSMasahiro Yamada "If you have saved a previous configuration in a file other than the\n"
1920a9064fbSMasahiro Yamada "default one, entering its name here will allow you to load and modify\n"
1930a9064fbSMasahiro Yamada "that configuration.\n"
1940a9064fbSMasahiro Yamada "\n"
1950a9064fbSMasahiro Yamada "Leave empty to abort.\n"),
1960a9064fbSMasahiro Yamada save_config_text[] = N_(
1970a9064fbSMasahiro Yamada "Enter a filename to which this configuration should be saved\n"
1980a9064fbSMasahiro Yamada "as an alternate.  Leave empty to abort."),
1990a9064fbSMasahiro Yamada save_config_help[] = N_(
2000a9064fbSMasahiro Yamada "For various reasons, one may wish to keep several different\n"
2010a9064fbSMasahiro Yamada "configurations available on a single machine.\n"
2020a9064fbSMasahiro Yamada "\n"
2030a9064fbSMasahiro Yamada "Entering a file name here will allow you to later retrieve, modify\n"
2040a9064fbSMasahiro Yamada "and use the current configuration as an alternate to whatever\n"
2050a9064fbSMasahiro Yamada "configuration options you have selected at that time.\n"
2060a9064fbSMasahiro Yamada "\n"
2070a9064fbSMasahiro Yamada "Leave empty to abort.\n"),
2080a9064fbSMasahiro Yamada search_help[] = N_(
2090a9064fbSMasahiro Yamada "Search for symbols (configuration variable names CONFIG_*) and display\n"
2100a9064fbSMasahiro Yamada "their relations.  Regular expressions are supported.\n"
2110a9064fbSMasahiro Yamada "Example:  Search for \"^FOO\".\n"
2120a9064fbSMasahiro Yamada "Result:\n"
2130a9064fbSMasahiro Yamada "-----------------------------------------------------------------\n"
2140a9064fbSMasahiro Yamada "Symbol: FOO [ = m]\n"
2150a9064fbSMasahiro Yamada "Prompt: Foo bus is used to drive the bar HW\n"
2160a9064fbSMasahiro Yamada "Defined at drivers/pci/Kconfig:47\n"
2170a9064fbSMasahiro Yamada "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
2180a9064fbSMasahiro Yamada "Location:\n"
2190a9064fbSMasahiro Yamada "  -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
2200a9064fbSMasahiro Yamada "    -> PCI support (PCI [ = y])\n"
2210a9064fbSMasahiro Yamada "      -> PCI access mode (<choice> [ = y])\n"
2220a9064fbSMasahiro Yamada "Selects: LIBCRC32\n"
2230a9064fbSMasahiro Yamada "Selected by: BAR\n"
2240a9064fbSMasahiro Yamada "-----------------------------------------------------------------\n"
2250a9064fbSMasahiro Yamada "o  The line 'Prompt:' shows the text displayed for this symbol in\n"
2260a9064fbSMasahiro Yamada "   the menu hierarchy.\n"
2270a9064fbSMasahiro Yamada "o  The 'Defined at' line tells at what file / line number the symbol is\n"
2280a9064fbSMasahiro Yamada "   defined.\n"
2290a9064fbSMasahiro Yamada "o  The 'Depends on:' line lists symbols that need to be defined for\n"
2300a9064fbSMasahiro Yamada "   this symbol to be visible and selectable in the menu.\n"
2310a9064fbSMasahiro Yamada "o  The 'Location:' lines tell, where in the menu structure this symbol\n"
2320a9064fbSMasahiro Yamada "   is located.  A location followed by a [ = y] indicates that this is\n"
2330a9064fbSMasahiro Yamada "   a selectable menu item, and the current value is displayed inside\n"
2340a9064fbSMasahiro Yamada "   brackets.\n"
2350a9064fbSMasahiro Yamada "o  The 'Selects:' line tells, what symbol will be automatically selected\n"
2360a9064fbSMasahiro Yamada "   if this symbol is selected (y or m).\n"
2370a9064fbSMasahiro Yamada "o  The 'Selected by' line tells what symbol has selected this symbol.\n"
2380a9064fbSMasahiro Yamada "\n"
2390a9064fbSMasahiro Yamada "Only relevant lines are shown.\n"
2400a9064fbSMasahiro Yamada "\n\n"
2410a9064fbSMasahiro Yamada "Search examples:\n"
2420a9064fbSMasahiro Yamada "USB  => find all symbols containing USB\n"
2430a9064fbSMasahiro Yamada "^USB => find all symbols starting with USB\n"
2440a9064fbSMasahiro Yamada "USB$ => find all symbols ending with USB\n"
2450a9064fbSMasahiro Yamada "\n");
2460a9064fbSMasahiro Yamada 
2470a9064fbSMasahiro Yamada struct mitem {
2480a9064fbSMasahiro Yamada 	char str[256];
2490a9064fbSMasahiro Yamada 	char tag;
2500a9064fbSMasahiro Yamada 	void *usrptr;
2510a9064fbSMasahiro Yamada 	int is_visible;
2520a9064fbSMasahiro Yamada };
2530a9064fbSMasahiro Yamada 
2540a9064fbSMasahiro Yamada #define MAX_MENU_ITEMS 4096
2550a9064fbSMasahiro Yamada static int show_all_items;
2560a9064fbSMasahiro Yamada static int indent;
2570a9064fbSMasahiro Yamada static struct menu *current_menu;
2580a9064fbSMasahiro Yamada static int child_count;
2590a9064fbSMasahiro Yamada static int single_menu_mode;
2600a9064fbSMasahiro Yamada /* the window in which all information appears */
2610a9064fbSMasahiro Yamada static WINDOW *main_window;
2620a9064fbSMasahiro Yamada /* the largest size of the menu window */
2630a9064fbSMasahiro Yamada static int mwin_max_lines;
2640a9064fbSMasahiro Yamada static int mwin_max_cols;
2650a9064fbSMasahiro Yamada /* the window in which we show option buttons */
2660a9064fbSMasahiro Yamada static MENU *curses_menu;
2670a9064fbSMasahiro Yamada static ITEM *curses_menu_items[MAX_MENU_ITEMS];
2680a9064fbSMasahiro Yamada static struct mitem k_menu_items[MAX_MENU_ITEMS];
2690a9064fbSMasahiro Yamada static int items_num;
2700a9064fbSMasahiro Yamada static int global_exit;
2710a9064fbSMasahiro Yamada /* the currently selected button */
2720a9064fbSMasahiro Yamada const char *current_instructions = menu_instructions;
2730a9064fbSMasahiro Yamada 
2740a9064fbSMasahiro Yamada static char *dialog_input_result;
2750a9064fbSMasahiro Yamada static int dialog_input_result_len;
2760a9064fbSMasahiro Yamada 
2770a9064fbSMasahiro Yamada static void conf(struct menu *menu);
2780a9064fbSMasahiro Yamada static void conf_choice(struct menu *menu);
2790a9064fbSMasahiro Yamada static void conf_string(struct menu *menu);
2800a9064fbSMasahiro Yamada static void conf_load(void);
2810a9064fbSMasahiro Yamada static void conf_save(void);
2820a9064fbSMasahiro Yamada static void show_help(struct menu *menu);
2830a9064fbSMasahiro Yamada static int do_exit(void);
2840a9064fbSMasahiro Yamada static void setup_windows(void);
2850a9064fbSMasahiro Yamada static void search_conf(void);
2860a9064fbSMasahiro Yamada 
2870a9064fbSMasahiro Yamada typedef void (*function_key_handler_t)(int *key, struct menu *menu);
2880a9064fbSMasahiro Yamada static void handle_f1(int *key, struct menu *current_item);
2890a9064fbSMasahiro Yamada static void handle_f2(int *key, struct menu *current_item);
2900a9064fbSMasahiro Yamada static void handle_f3(int *key, struct menu *current_item);
2910a9064fbSMasahiro Yamada static void handle_f4(int *key, struct menu *current_item);
2920a9064fbSMasahiro Yamada static void handle_f5(int *key, struct menu *current_item);
2930a9064fbSMasahiro Yamada static void handle_f6(int *key, struct menu *current_item);
2940a9064fbSMasahiro Yamada static void handle_f7(int *key, struct menu *current_item);
2950a9064fbSMasahiro Yamada static void handle_f8(int *key, struct menu *current_item);
2960a9064fbSMasahiro Yamada static void handle_f9(int *key, struct menu *current_item);
2970a9064fbSMasahiro Yamada 
2980a9064fbSMasahiro Yamada struct function_keys {
2990a9064fbSMasahiro Yamada 	const char *key_str;
3000a9064fbSMasahiro Yamada 	const char *func;
3010a9064fbSMasahiro Yamada 	function_key key;
3020a9064fbSMasahiro Yamada 	function_key_handler_t handler;
3030a9064fbSMasahiro Yamada };
3040a9064fbSMasahiro Yamada 
3050a9064fbSMasahiro Yamada static const int function_keys_num = 9;
3060a9064fbSMasahiro Yamada struct function_keys function_keys[] = {
3070a9064fbSMasahiro Yamada 	{
3080a9064fbSMasahiro Yamada 		.key_str = "F1",
3090a9064fbSMasahiro Yamada 		.func = "Help",
3100a9064fbSMasahiro Yamada 		.key = F_HELP,
3110a9064fbSMasahiro Yamada 		.handler = handle_f1,
3120a9064fbSMasahiro Yamada 	},
3130a9064fbSMasahiro Yamada 	{
3140a9064fbSMasahiro Yamada 		.key_str = "F2",
3150a9064fbSMasahiro Yamada 		.func = "SymInfo",
3160a9064fbSMasahiro Yamada 		.key = F_SYMBOL,
3170a9064fbSMasahiro Yamada 		.handler = handle_f2,
3180a9064fbSMasahiro Yamada 	},
3190a9064fbSMasahiro Yamada 	{
3200a9064fbSMasahiro Yamada 		.key_str = "F3",
3210a9064fbSMasahiro Yamada 		.func = "Help 2",
3220a9064fbSMasahiro Yamada 		.key = F_INSTS,
3230a9064fbSMasahiro Yamada 		.handler = handle_f3,
3240a9064fbSMasahiro Yamada 	},
3250a9064fbSMasahiro Yamada 	{
3260a9064fbSMasahiro Yamada 		.key_str = "F4",
3270a9064fbSMasahiro Yamada 		.func = "ShowAll",
3280a9064fbSMasahiro Yamada 		.key = F_CONF,
3290a9064fbSMasahiro Yamada 		.handler = handle_f4,
3300a9064fbSMasahiro Yamada 	},
3310a9064fbSMasahiro Yamada 	{
3320a9064fbSMasahiro Yamada 		.key_str = "F5",
3330a9064fbSMasahiro Yamada 		.func = "Back",
3340a9064fbSMasahiro Yamada 		.key = F_BACK,
3350a9064fbSMasahiro Yamada 		.handler = handle_f5,
3360a9064fbSMasahiro Yamada 	},
3370a9064fbSMasahiro Yamada 	{
3380a9064fbSMasahiro Yamada 		.key_str = "F6",
3390a9064fbSMasahiro Yamada 		.func = "Save",
3400a9064fbSMasahiro Yamada 		.key = F_SAVE,
3410a9064fbSMasahiro Yamada 		.handler = handle_f6,
3420a9064fbSMasahiro Yamada 	},
3430a9064fbSMasahiro Yamada 	{
3440a9064fbSMasahiro Yamada 		.key_str = "F7",
3450a9064fbSMasahiro Yamada 		.func = "Load",
3460a9064fbSMasahiro Yamada 		.key = F_LOAD,
3470a9064fbSMasahiro Yamada 		.handler = handle_f7,
3480a9064fbSMasahiro Yamada 	},
3490a9064fbSMasahiro Yamada 	{
3500a9064fbSMasahiro Yamada 		.key_str = "F8",
3510a9064fbSMasahiro Yamada 		.func = "SymSearch",
3520a9064fbSMasahiro Yamada 		.key = F_SEARCH,
3530a9064fbSMasahiro Yamada 		.handler = handle_f8,
3540a9064fbSMasahiro Yamada 	},
3550a9064fbSMasahiro Yamada 	{
3560a9064fbSMasahiro Yamada 		.key_str = "F9",
3570a9064fbSMasahiro Yamada 		.func = "Exit",
3580a9064fbSMasahiro Yamada 		.key = F_EXIT,
3590a9064fbSMasahiro Yamada 		.handler = handle_f9,
3600a9064fbSMasahiro Yamada 	},
3610a9064fbSMasahiro Yamada };
3620a9064fbSMasahiro Yamada 
3630a9064fbSMasahiro Yamada static void print_function_line(void)
3640a9064fbSMasahiro Yamada {
3650a9064fbSMasahiro Yamada 	int i;
3660a9064fbSMasahiro Yamada 	int offset = 1;
3670a9064fbSMasahiro Yamada 	const int skip = 1;
3680a9064fbSMasahiro Yamada 	int lines = getmaxy(stdscr);
3690a9064fbSMasahiro Yamada 
3700a9064fbSMasahiro Yamada 	for (i = 0; i < function_keys_num; i++) {
3710a9064fbSMasahiro Yamada 		(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
3720a9064fbSMasahiro Yamada 		mvwprintw(main_window, lines-3, offset,
3730a9064fbSMasahiro Yamada 				"%s",
3740a9064fbSMasahiro Yamada 				function_keys[i].key_str);
3750a9064fbSMasahiro Yamada 		(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
3760a9064fbSMasahiro Yamada 		offset += strlen(function_keys[i].key_str);
3770a9064fbSMasahiro Yamada 		mvwprintw(main_window, lines-3,
3780a9064fbSMasahiro Yamada 				offset, "%s",
3790a9064fbSMasahiro Yamada 				function_keys[i].func);
3800a9064fbSMasahiro Yamada 		offset += strlen(function_keys[i].func) + skip;
3810a9064fbSMasahiro Yamada 	}
3820a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[NORMAL]);
3830a9064fbSMasahiro Yamada }
3840a9064fbSMasahiro Yamada 
3850a9064fbSMasahiro Yamada /* help */
3860a9064fbSMasahiro Yamada static void handle_f1(int *key, struct menu *current_item)
3870a9064fbSMasahiro Yamada {
3880a9064fbSMasahiro Yamada 	show_scroll_win(main_window,
3890a9064fbSMasahiro Yamada 			_("Global help"), _(nconf_global_help));
3900a9064fbSMasahiro Yamada 	return;
3910a9064fbSMasahiro Yamada }
3920a9064fbSMasahiro Yamada 
3930a9064fbSMasahiro Yamada /* symbole help */
3940a9064fbSMasahiro Yamada static void handle_f2(int *key, struct menu *current_item)
3950a9064fbSMasahiro Yamada {
3960a9064fbSMasahiro Yamada 	show_help(current_item);
3970a9064fbSMasahiro Yamada 	return;
3980a9064fbSMasahiro Yamada }
3990a9064fbSMasahiro Yamada 
4000a9064fbSMasahiro Yamada /* instructions */
4010a9064fbSMasahiro Yamada static void handle_f3(int *key, struct menu *current_item)
4020a9064fbSMasahiro Yamada {
4030a9064fbSMasahiro Yamada 	show_scroll_win(main_window,
4040a9064fbSMasahiro Yamada 			_("Short help"),
4050a9064fbSMasahiro Yamada 			_(current_instructions));
4060a9064fbSMasahiro Yamada 	return;
4070a9064fbSMasahiro Yamada }
4080a9064fbSMasahiro Yamada 
4090a9064fbSMasahiro Yamada /* config */
4100a9064fbSMasahiro Yamada static void handle_f4(int *key, struct menu *current_item)
4110a9064fbSMasahiro Yamada {
4120a9064fbSMasahiro Yamada 	int res = btn_dialog(main_window,
4130a9064fbSMasahiro Yamada 			_("Show all symbols?"),
4140a9064fbSMasahiro Yamada 			2,
4150a9064fbSMasahiro Yamada 			"   <Show All>   ",
4160a9064fbSMasahiro Yamada 			"<Don't show all>");
4170a9064fbSMasahiro Yamada 	if (res == 0)
4180a9064fbSMasahiro Yamada 		show_all_items = 1;
4190a9064fbSMasahiro Yamada 	else if (res == 1)
4200a9064fbSMasahiro Yamada 		show_all_items = 0;
4210a9064fbSMasahiro Yamada 
4220a9064fbSMasahiro Yamada 	return;
4230a9064fbSMasahiro Yamada }
4240a9064fbSMasahiro Yamada 
4250a9064fbSMasahiro Yamada /* back */
4260a9064fbSMasahiro Yamada static void handle_f5(int *key, struct menu *current_item)
4270a9064fbSMasahiro Yamada {
4280a9064fbSMasahiro Yamada 	*key = KEY_LEFT;
4290a9064fbSMasahiro Yamada 	return;
4300a9064fbSMasahiro Yamada }
4310a9064fbSMasahiro Yamada 
4320a9064fbSMasahiro Yamada /* save */
4330a9064fbSMasahiro Yamada static void handle_f6(int *key, struct menu *current_item)
4340a9064fbSMasahiro Yamada {
4350a9064fbSMasahiro Yamada 	conf_save();
4360a9064fbSMasahiro Yamada 	return;
4370a9064fbSMasahiro Yamada }
4380a9064fbSMasahiro Yamada 
4390a9064fbSMasahiro Yamada /* load */
4400a9064fbSMasahiro Yamada static void handle_f7(int *key, struct menu *current_item)
4410a9064fbSMasahiro Yamada {
4420a9064fbSMasahiro Yamada 	conf_load();
4430a9064fbSMasahiro Yamada 	return;
4440a9064fbSMasahiro Yamada }
4450a9064fbSMasahiro Yamada 
4460a9064fbSMasahiro Yamada /* search */
4470a9064fbSMasahiro Yamada static void handle_f8(int *key, struct menu *current_item)
4480a9064fbSMasahiro Yamada {
4490a9064fbSMasahiro Yamada 	search_conf();
4500a9064fbSMasahiro Yamada 	return;
4510a9064fbSMasahiro Yamada }
4520a9064fbSMasahiro Yamada 
4530a9064fbSMasahiro Yamada /* exit */
4540a9064fbSMasahiro Yamada static void handle_f9(int *key, struct menu *current_item)
4550a9064fbSMasahiro Yamada {
4560a9064fbSMasahiro Yamada 	do_exit();
4570a9064fbSMasahiro Yamada 	return;
4580a9064fbSMasahiro Yamada }
4590a9064fbSMasahiro Yamada 
4600a9064fbSMasahiro Yamada /* return != 0 to indicate the key was handles */
4610a9064fbSMasahiro Yamada static int process_special_keys(int *key, struct menu *menu)
4620a9064fbSMasahiro Yamada {
4630a9064fbSMasahiro Yamada 	int i;
4640a9064fbSMasahiro Yamada 
4650a9064fbSMasahiro Yamada 	if (*key == KEY_RESIZE) {
4660a9064fbSMasahiro Yamada 		setup_windows();
4670a9064fbSMasahiro Yamada 		return 1;
4680a9064fbSMasahiro Yamada 	}
4690a9064fbSMasahiro Yamada 
4700a9064fbSMasahiro Yamada 	for (i = 0; i < function_keys_num; i++) {
4710a9064fbSMasahiro Yamada 		if (*key == KEY_F(function_keys[i].key) ||
4720a9064fbSMasahiro Yamada 		    *key == '0' + function_keys[i].key){
4730a9064fbSMasahiro Yamada 			function_keys[i].handler(key, menu);
4740a9064fbSMasahiro Yamada 			return 1;
4750a9064fbSMasahiro Yamada 		}
4760a9064fbSMasahiro Yamada 	}
4770a9064fbSMasahiro Yamada 
4780a9064fbSMasahiro Yamada 	return 0;
4790a9064fbSMasahiro Yamada }
4800a9064fbSMasahiro Yamada 
4810a9064fbSMasahiro Yamada static void clean_items(void)
4820a9064fbSMasahiro Yamada {
4830a9064fbSMasahiro Yamada 	int i;
4840a9064fbSMasahiro Yamada 	for (i = 0; curses_menu_items[i]; i++)
4850a9064fbSMasahiro Yamada 		free_item(curses_menu_items[i]);
4860a9064fbSMasahiro Yamada 	bzero(curses_menu_items, sizeof(curses_menu_items));
4870a9064fbSMasahiro Yamada 	bzero(k_menu_items, sizeof(k_menu_items));
4880a9064fbSMasahiro Yamada 	items_num = 0;
4890a9064fbSMasahiro Yamada }
4900a9064fbSMasahiro Yamada 
4910a9064fbSMasahiro Yamada typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
4920a9064fbSMasahiro Yamada 	FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
4930a9064fbSMasahiro Yamada 
4940a9064fbSMasahiro Yamada /* return the index of the matched item, or -1 if no such item exists */
4950a9064fbSMasahiro Yamada static int get_mext_match(const char *match_str, match_f flag)
4960a9064fbSMasahiro Yamada {
4970a9064fbSMasahiro Yamada 	int match_start = item_index(current_item(curses_menu));
4980a9064fbSMasahiro Yamada 	int index;
4990a9064fbSMasahiro Yamada 
5000a9064fbSMasahiro Yamada 	if (flag == FIND_NEXT_MATCH_DOWN)
5010a9064fbSMasahiro Yamada 		++match_start;
5020a9064fbSMasahiro Yamada 	else if (flag == FIND_NEXT_MATCH_UP)
5030a9064fbSMasahiro Yamada 		--match_start;
5040a9064fbSMasahiro Yamada 
5050a9064fbSMasahiro Yamada 	index = match_start;
5060a9064fbSMasahiro Yamada 	index = (index + items_num) % items_num;
5070a9064fbSMasahiro Yamada 	while (true) {
5080a9064fbSMasahiro Yamada 		char *str = k_menu_items[index].str;
5090a9064fbSMasahiro Yamada 		if (strcasestr(str, match_str) != 0)
5100a9064fbSMasahiro Yamada 			return index;
5110a9064fbSMasahiro Yamada 		if (flag == FIND_NEXT_MATCH_UP ||
5120a9064fbSMasahiro Yamada 		    flag == MATCH_TINKER_PATTERN_UP)
5130a9064fbSMasahiro Yamada 			--index;
5140a9064fbSMasahiro Yamada 		else
5150a9064fbSMasahiro Yamada 			++index;
5160a9064fbSMasahiro Yamada 		index = (index + items_num) % items_num;
5170a9064fbSMasahiro Yamada 		if (index == match_start)
5180a9064fbSMasahiro Yamada 			return -1;
5190a9064fbSMasahiro Yamada 	}
5200a9064fbSMasahiro Yamada }
5210a9064fbSMasahiro Yamada 
5220a9064fbSMasahiro Yamada /* Make a new item. */
5230a9064fbSMasahiro Yamada static void item_make(struct menu *menu, char tag, const char *fmt, ...)
5240a9064fbSMasahiro Yamada {
5250a9064fbSMasahiro Yamada 	va_list ap;
5260a9064fbSMasahiro Yamada 
5270a9064fbSMasahiro Yamada 	if (items_num > MAX_MENU_ITEMS-1)
5280a9064fbSMasahiro Yamada 		return;
5290a9064fbSMasahiro Yamada 
5300a9064fbSMasahiro Yamada 	bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
5310a9064fbSMasahiro Yamada 	k_menu_items[items_num].tag = tag;
5320a9064fbSMasahiro Yamada 	k_menu_items[items_num].usrptr = menu;
5330a9064fbSMasahiro Yamada 	if (menu != NULL)
5340a9064fbSMasahiro Yamada 		k_menu_items[items_num].is_visible =
5350a9064fbSMasahiro Yamada 			menu_is_visible(menu);
5360a9064fbSMasahiro Yamada 	else
5370a9064fbSMasahiro Yamada 		k_menu_items[items_num].is_visible = 1;
5380a9064fbSMasahiro Yamada 
5390a9064fbSMasahiro Yamada 	va_start(ap, fmt);
5400a9064fbSMasahiro Yamada 	vsnprintf(k_menu_items[items_num].str,
5410a9064fbSMasahiro Yamada 		  sizeof(k_menu_items[items_num].str),
5420a9064fbSMasahiro Yamada 		  fmt, ap);
5430a9064fbSMasahiro Yamada 	va_end(ap);
5440a9064fbSMasahiro Yamada 
5450a9064fbSMasahiro Yamada 	if (!k_menu_items[items_num].is_visible)
5460a9064fbSMasahiro Yamada 		memcpy(k_menu_items[items_num].str, "XXX", 3);
5470a9064fbSMasahiro Yamada 
5480a9064fbSMasahiro Yamada 	curses_menu_items[items_num] = new_item(
5490a9064fbSMasahiro Yamada 			k_menu_items[items_num].str,
5500a9064fbSMasahiro Yamada 			k_menu_items[items_num].str);
5510a9064fbSMasahiro Yamada 	set_item_userptr(curses_menu_items[items_num],
5520a9064fbSMasahiro Yamada 			&k_menu_items[items_num]);
5530a9064fbSMasahiro Yamada 	/*
5540a9064fbSMasahiro Yamada 	if (!k_menu_items[items_num].is_visible)
5550a9064fbSMasahiro Yamada 		item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
5560a9064fbSMasahiro Yamada 	*/
5570a9064fbSMasahiro Yamada 
5580a9064fbSMasahiro Yamada 	items_num++;
5590a9064fbSMasahiro Yamada 	curses_menu_items[items_num] = NULL;
5600a9064fbSMasahiro Yamada }
5610a9064fbSMasahiro Yamada 
5620a9064fbSMasahiro Yamada /* very hackish. adds a string to the last item added */
5630a9064fbSMasahiro Yamada static void item_add_str(const char *fmt, ...)
5640a9064fbSMasahiro Yamada {
5650a9064fbSMasahiro Yamada 	va_list ap;
5660a9064fbSMasahiro Yamada 	int index = items_num-1;
5670a9064fbSMasahiro Yamada 	char new_str[256];
5680a9064fbSMasahiro Yamada 	char tmp_str[256];
5690a9064fbSMasahiro Yamada 
5700a9064fbSMasahiro Yamada 	if (index < 0)
5710a9064fbSMasahiro Yamada 		return;
5720a9064fbSMasahiro Yamada 
5730a9064fbSMasahiro Yamada 	va_start(ap, fmt);
5740a9064fbSMasahiro Yamada 	vsnprintf(new_str, sizeof(new_str), fmt, ap);
5750a9064fbSMasahiro Yamada 	va_end(ap);
5760a9064fbSMasahiro Yamada 	snprintf(tmp_str, sizeof(tmp_str), "%s%s",
5770a9064fbSMasahiro Yamada 			k_menu_items[index].str, new_str);
5780a9064fbSMasahiro Yamada 	strncpy(k_menu_items[index].str,
5790a9064fbSMasahiro Yamada 		tmp_str,
5800a9064fbSMasahiro Yamada 		sizeof(k_menu_items[index].str));
5810a9064fbSMasahiro Yamada 
5820a9064fbSMasahiro Yamada 	free_item(curses_menu_items[index]);
5830a9064fbSMasahiro Yamada 	curses_menu_items[index] = new_item(
5840a9064fbSMasahiro Yamada 			k_menu_items[index].str,
5850a9064fbSMasahiro Yamada 			k_menu_items[index].str);
5860a9064fbSMasahiro Yamada 	set_item_userptr(curses_menu_items[index],
5870a9064fbSMasahiro Yamada 			&k_menu_items[index]);
5880a9064fbSMasahiro Yamada }
5890a9064fbSMasahiro Yamada 
5900a9064fbSMasahiro Yamada /* get the tag of the currently selected item */
5910a9064fbSMasahiro Yamada static char item_tag(void)
5920a9064fbSMasahiro Yamada {
5930a9064fbSMasahiro Yamada 	ITEM *cur;
5940a9064fbSMasahiro Yamada 	struct mitem *mcur;
5950a9064fbSMasahiro Yamada 
5960a9064fbSMasahiro Yamada 	cur = current_item(curses_menu);
5970a9064fbSMasahiro Yamada 	if (cur == NULL)
5980a9064fbSMasahiro Yamada 		return 0;
5990a9064fbSMasahiro Yamada 	mcur = (struct mitem *) item_userptr(cur);
6000a9064fbSMasahiro Yamada 	return mcur->tag;
6010a9064fbSMasahiro Yamada }
6020a9064fbSMasahiro Yamada 
6030a9064fbSMasahiro Yamada static int curses_item_index(void)
6040a9064fbSMasahiro Yamada {
6050a9064fbSMasahiro Yamada 	return  item_index(current_item(curses_menu));
6060a9064fbSMasahiro Yamada }
6070a9064fbSMasahiro Yamada 
6080a9064fbSMasahiro Yamada static void *item_data(void)
6090a9064fbSMasahiro Yamada {
6100a9064fbSMasahiro Yamada 	ITEM *cur;
6110a9064fbSMasahiro Yamada 	struct mitem *mcur;
6120a9064fbSMasahiro Yamada 
6130a9064fbSMasahiro Yamada 	cur = current_item(curses_menu);
6140a9064fbSMasahiro Yamada 	if (!cur)
6150a9064fbSMasahiro Yamada 		return NULL;
6160a9064fbSMasahiro Yamada 	mcur = (struct mitem *) item_userptr(cur);
6170a9064fbSMasahiro Yamada 	return mcur->usrptr;
6180a9064fbSMasahiro Yamada 
6190a9064fbSMasahiro Yamada }
6200a9064fbSMasahiro Yamada 
6210a9064fbSMasahiro Yamada static int item_is_tag(char tag)
6220a9064fbSMasahiro Yamada {
6230a9064fbSMasahiro Yamada 	return item_tag() == tag;
6240a9064fbSMasahiro Yamada }
6250a9064fbSMasahiro Yamada 
6260a9064fbSMasahiro Yamada static char filename[PATH_MAX+1];
6270a9064fbSMasahiro Yamada static char menu_backtitle[PATH_MAX+128];
6280a9064fbSMasahiro Yamada static const char *set_config_filename(const char *config_filename)
6290a9064fbSMasahiro Yamada {
6300a9064fbSMasahiro Yamada 	int size;
6310a9064fbSMasahiro Yamada 
6320a9064fbSMasahiro Yamada 	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
6330a9064fbSMasahiro Yamada 			"%s - %s", config_filename, rootmenu.prompt->text);
6340a9064fbSMasahiro Yamada 	if (size >= sizeof(menu_backtitle))
6350a9064fbSMasahiro Yamada 		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
6360a9064fbSMasahiro Yamada 
6370a9064fbSMasahiro Yamada 	size = snprintf(filename, sizeof(filename), "%s", config_filename);
6380a9064fbSMasahiro Yamada 	if (size >= sizeof(filename))
6390a9064fbSMasahiro Yamada 		filename[sizeof(filename)-1] = '\0';
6400a9064fbSMasahiro Yamada 	return menu_backtitle;
6410a9064fbSMasahiro Yamada }
6420a9064fbSMasahiro Yamada 
6430a9064fbSMasahiro Yamada /* return = 0 means we are successful.
6440a9064fbSMasahiro Yamada  * -1 means go on doing what you were doing
6450a9064fbSMasahiro Yamada  */
6460a9064fbSMasahiro Yamada static int do_exit(void)
6470a9064fbSMasahiro Yamada {
6480a9064fbSMasahiro Yamada 	int res;
6490a9064fbSMasahiro Yamada 	if (!conf_get_changed()) {
6500a9064fbSMasahiro Yamada 		global_exit = 1;
6510a9064fbSMasahiro Yamada 		return 0;
6520a9064fbSMasahiro Yamada 	}
6530a9064fbSMasahiro Yamada 	res = btn_dialog(main_window,
6540a9064fbSMasahiro Yamada 			_("Do you wish to save your new configuration?\n"
6550a9064fbSMasahiro Yamada 				"<ESC> to cancel and resume nconfig."),
6560a9064fbSMasahiro Yamada 			2,
6570a9064fbSMasahiro Yamada 			"   <save>   ",
6580a9064fbSMasahiro Yamada 			"<don't save>");
6590a9064fbSMasahiro Yamada 	if (res == KEY_EXIT) {
6600a9064fbSMasahiro Yamada 		global_exit = 0;
6610a9064fbSMasahiro Yamada 		return -1;
6620a9064fbSMasahiro Yamada 	}
6630a9064fbSMasahiro Yamada 
6640a9064fbSMasahiro Yamada 	/* if we got here, the user really wants to exit */
6650a9064fbSMasahiro Yamada 	switch (res) {
6660a9064fbSMasahiro Yamada 	case 0:
6670a9064fbSMasahiro Yamada 		res = conf_write(filename);
6680a9064fbSMasahiro Yamada 		if (res)
6690a9064fbSMasahiro Yamada 			btn_dialog(
6700a9064fbSMasahiro Yamada 				main_window,
6710a9064fbSMasahiro Yamada 				_("Error during writing of configuration.\n"
6720a9064fbSMasahiro Yamada 				  "Your configuration changes were NOT saved."),
6730a9064fbSMasahiro Yamada 				  1,
6740a9064fbSMasahiro Yamada 				  "<OK>");
6750a9064fbSMasahiro Yamada 		break;
6760a9064fbSMasahiro Yamada 	default:
6770a9064fbSMasahiro Yamada 		btn_dialog(
6780a9064fbSMasahiro Yamada 			main_window,
6790a9064fbSMasahiro Yamada 			_("Your configuration changes were NOT saved."),
6800a9064fbSMasahiro Yamada 			1,
6810a9064fbSMasahiro Yamada 			"<OK>");
6820a9064fbSMasahiro Yamada 		break;
6830a9064fbSMasahiro Yamada 	}
6840a9064fbSMasahiro Yamada 	global_exit = 1;
6850a9064fbSMasahiro Yamada 	return 0;
6860a9064fbSMasahiro Yamada }
6870a9064fbSMasahiro Yamada 
6880a9064fbSMasahiro Yamada 
6890a9064fbSMasahiro Yamada static void search_conf(void)
6900a9064fbSMasahiro Yamada {
6910a9064fbSMasahiro Yamada 	struct symbol **sym_arr;
6920a9064fbSMasahiro Yamada 	struct gstr res;
6930a9064fbSMasahiro Yamada 	struct gstr title;
6940a9064fbSMasahiro Yamada 	char *dialog_input;
6950a9064fbSMasahiro Yamada 	int dres;
6960a9064fbSMasahiro Yamada 
6970a9064fbSMasahiro Yamada 	title = str_new();
6980a9064fbSMasahiro Yamada 	str_printf( &title, _("Enter (sub)string or regexp to search for "
6990a9064fbSMasahiro Yamada 			      "(with or without \"%s\")"), CONFIG_);
7000a9064fbSMasahiro Yamada 
7010a9064fbSMasahiro Yamada again:
7020a9064fbSMasahiro Yamada 	dres = dialog_inputbox(main_window,
7030a9064fbSMasahiro Yamada 			_("Search Configuration Parameter"),
7040a9064fbSMasahiro Yamada 			str_get(&title),
7050a9064fbSMasahiro Yamada 			"", &dialog_input_result, &dialog_input_result_len);
7060a9064fbSMasahiro Yamada 	switch (dres) {
7070a9064fbSMasahiro Yamada 	case 0:
7080a9064fbSMasahiro Yamada 		break;
7090a9064fbSMasahiro Yamada 	case 1:
7100a9064fbSMasahiro Yamada 		show_scroll_win(main_window,
7110a9064fbSMasahiro Yamada 				_("Search Configuration"), search_help);
7120a9064fbSMasahiro Yamada 		goto again;
7130a9064fbSMasahiro Yamada 	default:
7140a9064fbSMasahiro Yamada 		str_free(&title);
7150a9064fbSMasahiro Yamada 		return;
7160a9064fbSMasahiro Yamada 	}
7170a9064fbSMasahiro Yamada 
7180a9064fbSMasahiro Yamada 	/* strip the prefix if necessary */
7190a9064fbSMasahiro Yamada 	dialog_input = dialog_input_result;
7200a9064fbSMasahiro Yamada 	if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
7210a9064fbSMasahiro Yamada 		dialog_input += strlen(CONFIG_);
7220a9064fbSMasahiro Yamada 
7230a9064fbSMasahiro Yamada 	sym_arr = sym_re_search(dialog_input);
7240a9064fbSMasahiro Yamada 	res = get_relations_str(sym_arr, NULL);
7250a9064fbSMasahiro Yamada 	free(sym_arr);
7260a9064fbSMasahiro Yamada 	show_scroll_win(main_window,
7270a9064fbSMasahiro Yamada 			_("Search Results"), str_get(&res));
7280a9064fbSMasahiro Yamada 	str_free(&res);
7290a9064fbSMasahiro Yamada 	str_free(&title);
7300a9064fbSMasahiro Yamada }
7310a9064fbSMasahiro Yamada 
7320a9064fbSMasahiro Yamada 
7330a9064fbSMasahiro Yamada static void build_conf(struct menu *menu)
7340a9064fbSMasahiro Yamada {
7350a9064fbSMasahiro Yamada 	struct symbol *sym;
7360a9064fbSMasahiro Yamada 	struct property *prop;
7370a9064fbSMasahiro Yamada 	struct menu *child;
7380a9064fbSMasahiro Yamada 	int type, tmp, doint = 2;
7390a9064fbSMasahiro Yamada 	tristate val;
7400a9064fbSMasahiro Yamada 	char ch;
7410a9064fbSMasahiro Yamada 
7420a9064fbSMasahiro Yamada 	if (!menu || (!show_all_items && !menu_is_visible(menu)))
7430a9064fbSMasahiro Yamada 		return;
7440a9064fbSMasahiro Yamada 
7450a9064fbSMasahiro Yamada 	sym = menu->sym;
7460a9064fbSMasahiro Yamada 	prop = menu->prompt;
7470a9064fbSMasahiro Yamada 	if (!sym) {
7480a9064fbSMasahiro Yamada 		if (prop && menu != current_menu) {
7490a9064fbSMasahiro Yamada 			const char *prompt = menu_get_prompt(menu);
7500a9064fbSMasahiro Yamada 			enum prop_type ptype;
7510a9064fbSMasahiro Yamada 			ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
7520a9064fbSMasahiro Yamada 			switch (ptype) {
7530a9064fbSMasahiro Yamada 			case P_MENU:
7540a9064fbSMasahiro Yamada 				child_count++;
7550a9064fbSMasahiro Yamada 				prompt = _(prompt);
7560a9064fbSMasahiro Yamada 				if (single_menu_mode) {
7570a9064fbSMasahiro Yamada 					item_make(menu, 'm',
7580a9064fbSMasahiro Yamada 						"%s%*c%s",
7590a9064fbSMasahiro Yamada 						menu->data ? "-->" : "++>",
7600a9064fbSMasahiro Yamada 						indent + 1, ' ', prompt);
7610a9064fbSMasahiro Yamada 				} else
7620a9064fbSMasahiro Yamada 					item_make(menu, 'm',
7630a9064fbSMasahiro Yamada 						  "   %*c%s  %s",
7640a9064fbSMasahiro Yamada 						  indent + 1, ' ', prompt,
7650a9064fbSMasahiro Yamada 						  menu_is_empty(menu) ? "----" : "--->");
7660a9064fbSMasahiro Yamada 
7670a9064fbSMasahiro Yamada 				if (single_menu_mode && menu->data)
7680a9064fbSMasahiro Yamada 					goto conf_childs;
7690a9064fbSMasahiro Yamada 				return;
7700a9064fbSMasahiro Yamada 			case P_COMMENT:
7710a9064fbSMasahiro Yamada 				if (prompt) {
7720a9064fbSMasahiro Yamada 					child_count++;
7730a9064fbSMasahiro Yamada 					item_make(menu, ':',
7740a9064fbSMasahiro Yamada 						"   %*c*** %s ***",
7750a9064fbSMasahiro Yamada 						indent + 1, ' ',
7760a9064fbSMasahiro Yamada 						_(prompt));
7770a9064fbSMasahiro Yamada 				}
7780a9064fbSMasahiro Yamada 				break;
7790a9064fbSMasahiro Yamada 			default:
7800a9064fbSMasahiro Yamada 				if (prompt) {
7810a9064fbSMasahiro Yamada 					child_count++;
7820a9064fbSMasahiro Yamada 					item_make(menu, ':', "---%*c%s",
7830a9064fbSMasahiro Yamada 						indent + 1, ' ',
7840a9064fbSMasahiro Yamada 						_(prompt));
7850a9064fbSMasahiro Yamada 				}
7860a9064fbSMasahiro Yamada 			}
7870a9064fbSMasahiro Yamada 		} else
7880a9064fbSMasahiro Yamada 			doint = 0;
7890a9064fbSMasahiro Yamada 		goto conf_childs;
7900a9064fbSMasahiro Yamada 	}
7910a9064fbSMasahiro Yamada 
7920a9064fbSMasahiro Yamada 	type = sym_get_type(sym);
7930a9064fbSMasahiro Yamada 	if (sym_is_choice(sym)) {
7940a9064fbSMasahiro Yamada 		struct symbol *def_sym = sym_get_choice_value(sym);
7950a9064fbSMasahiro Yamada 		struct menu *def_menu = NULL;
7960a9064fbSMasahiro Yamada 
7970a9064fbSMasahiro Yamada 		child_count++;
7980a9064fbSMasahiro Yamada 		for (child = menu->list; child; child = child->next) {
7990a9064fbSMasahiro Yamada 			if (menu_is_visible(child) && child->sym == def_sym)
8000a9064fbSMasahiro Yamada 				def_menu = child;
8010a9064fbSMasahiro Yamada 		}
8020a9064fbSMasahiro Yamada 
8030a9064fbSMasahiro Yamada 		val = sym_get_tristate_value(sym);
8040a9064fbSMasahiro Yamada 		if (sym_is_changable(sym)) {
8050a9064fbSMasahiro Yamada 			switch (type) {
8060a9064fbSMasahiro Yamada 			case S_BOOLEAN:
8070a9064fbSMasahiro Yamada 				item_make(menu, 't', "[%c]",
8080a9064fbSMasahiro Yamada 						val == no ? ' ' : '*');
8090a9064fbSMasahiro Yamada 				break;
8100a9064fbSMasahiro Yamada 			case S_TRISTATE:
8110a9064fbSMasahiro Yamada 				switch (val) {
8120a9064fbSMasahiro Yamada 				case yes:
8130a9064fbSMasahiro Yamada 					ch = '*';
8140a9064fbSMasahiro Yamada 					break;
8150a9064fbSMasahiro Yamada 				case mod:
8160a9064fbSMasahiro Yamada 					ch = 'M';
8170a9064fbSMasahiro Yamada 					break;
8180a9064fbSMasahiro Yamada 				default:
8190a9064fbSMasahiro Yamada 					ch = ' ';
8200a9064fbSMasahiro Yamada 					break;
8210a9064fbSMasahiro Yamada 				}
8220a9064fbSMasahiro Yamada 				item_make(menu, 't', "<%c>", ch);
8230a9064fbSMasahiro Yamada 				break;
8240a9064fbSMasahiro Yamada 			}
8250a9064fbSMasahiro Yamada 		} else {
8260a9064fbSMasahiro Yamada 			item_make(menu, def_menu ? 't' : ':', "   ");
8270a9064fbSMasahiro Yamada 		}
8280a9064fbSMasahiro Yamada 
8290a9064fbSMasahiro Yamada 		item_add_str("%*c%s", indent + 1,
8300a9064fbSMasahiro Yamada 				' ', _(menu_get_prompt(menu)));
8310a9064fbSMasahiro Yamada 		if (val == yes) {
8320a9064fbSMasahiro Yamada 			if (def_menu) {
8330a9064fbSMasahiro Yamada 				item_add_str(" (%s)",
8340a9064fbSMasahiro Yamada 					_(menu_get_prompt(def_menu)));
8350a9064fbSMasahiro Yamada 				item_add_str("  --->");
8360a9064fbSMasahiro Yamada 				if (def_menu->list) {
8370a9064fbSMasahiro Yamada 					indent += 2;
8380a9064fbSMasahiro Yamada 					build_conf(def_menu);
8390a9064fbSMasahiro Yamada 					indent -= 2;
8400a9064fbSMasahiro Yamada 				}
8410a9064fbSMasahiro Yamada 			}
8420a9064fbSMasahiro Yamada 			return;
8430a9064fbSMasahiro Yamada 		}
8440a9064fbSMasahiro Yamada 	} else {
8450a9064fbSMasahiro Yamada 		if (menu == current_menu) {
8460a9064fbSMasahiro Yamada 			item_make(menu, ':',
8470a9064fbSMasahiro Yamada 				"---%*c%s", indent + 1,
8480a9064fbSMasahiro Yamada 				' ', _(menu_get_prompt(menu)));
8490a9064fbSMasahiro Yamada 			goto conf_childs;
8500a9064fbSMasahiro Yamada 		}
8510a9064fbSMasahiro Yamada 		child_count++;
8520a9064fbSMasahiro Yamada 		val = sym_get_tristate_value(sym);
8530a9064fbSMasahiro Yamada 		if (sym_is_choice_value(sym) && val == yes) {
8540a9064fbSMasahiro Yamada 			item_make(menu, ':', "   ");
8550a9064fbSMasahiro Yamada 		} else {
8560a9064fbSMasahiro Yamada 			switch (type) {
8570a9064fbSMasahiro Yamada 			case S_BOOLEAN:
8580a9064fbSMasahiro Yamada 				if (sym_is_changable(sym))
8590a9064fbSMasahiro Yamada 					item_make(menu, 't', "[%c]",
8600a9064fbSMasahiro Yamada 						val == no ? ' ' : '*');
8610a9064fbSMasahiro Yamada 				else
8620a9064fbSMasahiro Yamada 					item_make(menu, 't', "-%c-",
8630a9064fbSMasahiro Yamada 						val == no ? ' ' : '*');
8640a9064fbSMasahiro Yamada 				break;
8650a9064fbSMasahiro Yamada 			case S_TRISTATE:
8660a9064fbSMasahiro Yamada 				switch (val) {
8670a9064fbSMasahiro Yamada 				case yes:
8680a9064fbSMasahiro Yamada 					ch = '*';
8690a9064fbSMasahiro Yamada 					break;
8700a9064fbSMasahiro Yamada 				case mod:
8710a9064fbSMasahiro Yamada 					ch = 'M';
8720a9064fbSMasahiro Yamada 					break;
8730a9064fbSMasahiro Yamada 				default:
8740a9064fbSMasahiro Yamada 					ch = ' ';
8750a9064fbSMasahiro Yamada 					break;
8760a9064fbSMasahiro Yamada 				}
8770a9064fbSMasahiro Yamada 				if (sym_is_changable(sym)) {
8780a9064fbSMasahiro Yamada 					if (sym->rev_dep.tri == mod)
8790a9064fbSMasahiro Yamada 						item_make(menu,
8800a9064fbSMasahiro Yamada 							't', "{%c}", ch);
8810a9064fbSMasahiro Yamada 					else
8820a9064fbSMasahiro Yamada 						item_make(menu,
8830a9064fbSMasahiro Yamada 							't', "<%c>", ch);
8840a9064fbSMasahiro Yamada 				} else
8850a9064fbSMasahiro Yamada 					item_make(menu, 't', "-%c-", ch);
8860a9064fbSMasahiro Yamada 				break;
8870a9064fbSMasahiro Yamada 			default:
8880a9064fbSMasahiro Yamada 				tmp = 2 + strlen(sym_get_string_value(sym));
8890a9064fbSMasahiro Yamada 				item_make(menu, 's', "    (%s)",
8900a9064fbSMasahiro Yamada 						sym_get_string_value(sym));
8910a9064fbSMasahiro Yamada 				tmp = indent - tmp + 4;
8920a9064fbSMasahiro Yamada 				if (tmp < 0)
8930a9064fbSMasahiro Yamada 					tmp = 0;
8940a9064fbSMasahiro Yamada 				item_add_str("%*c%s%s", tmp, ' ',
8950a9064fbSMasahiro Yamada 						_(menu_get_prompt(menu)),
8960a9064fbSMasahiro Yamada 						(sym_has_value(sym) ||
8970a9064fbSMasahiro Yamada 						 !sym_is_changable(sym)) ? "" :
8980a9064fbSMasahiro Yamada 						_(" (NEW)"));
8990a9064fbSMasahiro Yamada 				goto conf_childs;
9000a9064fbSMasahiro Yamada 			}
9010a9064fbSMasahiro Yamada 		}
9020a9064fbSMasahiro Yamada 		item_add_str("%*c%s%s", indent + 1, ' ',
9030a9064fbSMasahiro Yamada 				_(menu_get_prompt(menu)),
9040a9064fbSMasahiro Yamada 				(sym_has_value(sym) || !sym_is_changable(sym)) ?
9050a9064fbSMasahiro Yamada 				"" : _(" (NEW)"));
9060a9064fbSMasahiro Yamada 		if (menu->prompt && menu->prompt->type == P_MENU) {
9070a9064fbSMasahiro Yamada 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");
9080a9064fbSMasahiro Yamada 			return;
9090a9064fbSMasahiro Yamada 		}
9100a9064fbSMasahiro Yamada 	}
9110a9064fbSMasahiro Yamada 
9120a9064fbSMasahiro Yamada conf_childs:
9130a9064fbSMasahiro Yamada 	indent += doint;
9140a9064fbSMasahiro Yamada 	for (child = menu->list; child; child = child->next)
9150a9064fbSMasahiro Yamada 		build_conf(child);
9160a9064fbSMasahiro Yamada 	indent -= doint;
9170a9064fbSMasahiro Yamada }
9180a9064fbSMasahiro Yamada 
9190a9064fbSMasahiro Yamada static void reset_menu(void)
9200a9064fbSMasahiro Yamada {
9210a9064fbSMasahiro Yamada 	unpost_menu(curses_menu);
9220a9064fbSMasahiro Yamada 	clean_items();
9230a9064fbSMasahiro Yamada }
9240a9064fbSMasahiro Yamada 
9250a9064fbSMasahiro Yamada /* adjust the menu to show this item.
9260a9064fbSMasahiro Yamada  * prefer not to scroll the menu if possible*/
9270a9064fbSMasahiro Yamada static void center_item(int selected_index, int *last_top_row)
9280a9064fbSMasahiro Yamada {
9290a9064fbSMasahiro Yamada 	int toprow;
9300a9064fbSMasahiro Yamada 
9310a9064fbSMasahiro Yamada 	set_top_row(curses_menu, *last_top_row);
9320a9064fbSMasahiro Yamada 	toprow = top_row(curses_menu);
9330a9064fbSMasahiro Yamada 	if (selected_index < toprow ||
9340a9064fbSMasahiro Yamada 	    selected_index >= toprow+mwin_max_lines) {
9350a9064fbSMasahiro Yamada 		toprow = max(selected_index-mwin_max_lines/2, 0);
9360a9064fbSMasahiro Yamada 		if (toprow >= item_count(curses_menu)-mwin_max_lines)
9370a9064fbSMasahiro Yamada 			toprow = item_count(curses_menu)-mwin_max_lines;
9380a9064fbSMasahiro Yamada 		set_top_row(curses_menu, toprow);
9390a9064fbSMasahiro Yamada 	}
9400a9064fbSMasahiro Yamada 	set_current_item(curses_menu,
9410a9064fbSMasahiro Yamada 			curses_menu_items[selected_index]);
9420a9064fbSMasahiro Yamada 	*last_top_row = toprow;
9430a9064fbSMasahiro Yamada 	post_menu(curses_menu);
9440a9064fbSMasahiro Yamada 	refresh_all_windows(main_window);
9450a9064fbSMasahiro Yamada }
9460a9064fbSMasahiro Yamada 
9470a9064fbSMasahiro Yamada /* this function assumes reset_menu has been called before */
9480a9064fbSMasahiro Yamada static void show_menu(const char *prompt, const char *instructions,
9490a9064fbSMasahiro Yamada 		int selected_index, int *last_top_row)
9500a9064fbSMasahiro Yamada {
9510a9064fbSMasahiro Yamada 	int maxx, maxy;
9520a9064fbSMasahiro Yamada 	WINDOW *menu_window;
9530a9064fbSMasahiro Yamada 
9540a9064fbSMasahiro Yamada 	current_instructions = instructions;
9550a9064fbSMasahiro Yamada 
9560a9064fbSMasahiro Yamada 	clear();
9570a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[NORMAL]);
9580a9064fbSMasahiro Yamada 	print_in_middle(stdscr, 1, 0, getmaxx(stdscr),
9590a9064fbSMasahiro Yamada 			menu_backtitle,
9600a9064fbSMasahiro Yamada 			attributes[MAIN_HEADING]);
9610a9064fbSMasahiro Yamada 
9620a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
9630a9064fbSMasahiro Yamada 	box(main_window, 0, 0);
9640a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
9650a9064fbSMasahiro Yamada 	mvwprintw(main_window, 0, 3, " %s ", prompt);
9660a9064fbSMasahiro Yamada 	(void) wattrset(main_window, attributes[NORMAL]);
9670a9064fbSMasahiro Yamada 
9680a9064fbSMasahiro Yamada 	set_menu_items(curses_menu, curses_menu_items);
9690a9064fbSMasahiro Yamada 
9700a9064fbSMasahiro Yamada 	/* position the menu at the middle of the screen */
9710a9064fbSMasahiro Yamada 	scale_menu(curses_menu, &maxy, &maxx);
9720a9064fbSMasahiro Yamada 	maxx = min(maxx, mwin_max_cols-2);
9730a9064fbSMasahiro Yamada 	maxy = mwin_max_lines;
9740a9064fbSMasahiro Yamada 	menu_window = derwin(main_window,
9750a9064fbSMasahiro Yamada 			maxy,
9760a9064fbSMasahiro Yamada 			maxx,
9770a9064fbSMasahiro Yamada 			2,
9780a9064fbSMasahiro Yamada 			(mwin_max_cols-maxx)/2);
9790a9064fbSMasahiro Yamada 	keypad(menu_window, TRUE);
9800a9064fbSMasahiro Yamada 	set_menu_win(curses_menu, menu_window);
9810a9064fbSMasahiro Yamada 	set_menu_sub(curses_menu, menu_window);
9820a9064fbSMasahiro Yamada 
9830a9064fbSMasahiro Yamada 	/* must reassert this after changing items, otherwise returns to a
9840a9064fbSMasahiro Yamada 	 * default of 16
9850a9064fbSMasahiro Yamada 	 */
9860a9064fbSMasahiro Yamada 	set_menu_format(curses_menu, maxy, 1);
9870a9064fbSMasahiro Yamada 	center_item(selected_index, last_top_row);
9880a9064fbSMasahiro Yamada 	set_menu_format(curses_menu, maxy, 1);
9890a9064fbSMasahiro Yamada 
9900a9064fbSMasahiro Yamada 	print_function_line();
9910a9064fbSMasahiro Yamada 
9920a9064fbSMasahiro Yamada 	/* Post the menu */
9930a9064fbSMasahiro Yamada 	post_menu(curses_menu);
9940a9064fbSMasahiro Yamada 	refresh_all_windows(main_window);
9950a9064fbSMasahiro Yamada }
9960a9064fbSMasahiro Yamada 
9970a9064fbSMasahiro Yamada static void adj_match_dir(match_f *match_direction)
9980a9064fbSMasahiro Yamada {
9990a9064fbSMasahiro Yamada 	if (*match_direction == FIND_NEXT_MATCH_DOWN)
10000a9064fbSMasahiro Yamada 		*match_direction =
10010a9064fbSMasahiro Yamada 			MATCH_TINKER_PATTERN_DOWN;
10020a9064fbSMasahiro Yamada 	else if (*match_direction == FIND_NEXT_MATCH_UP)
10030a9064fbSMasahiro Yamada 		*match_direction =
10040a9064fbSMasahiro Yamada 			MATCH_TINKER_PATTERN_UP;
10050a9064fbSMasahiro Yamada 	/* else, do no change.. */
10060a9064fbSMasahiro Yamada }
10070a9064fbSMasahiro Yamada 
10080a9064fbSMasahiro Yamada struct match_state
10090a9064fbSMasahiro Yamada {
10100a9064fbSMasahiro Yamada 	int in_search;
10110a9064fbSMasahiro Yamada 	match_f match_direction;
10120a9064fbSMasahiro Yamada 	char pattern[256];
10130a9064fbSMasahiro Yamada };
10140a9064fbSMasahiro Yamada 
10150a9064fbSMasahiro Yamada /* Return 0 means I have handled the key. In such a case, ans should hold the
10160a9064fbSMasahiro Yamada  * item to center, or -1 otherwise.
10170a9064fbSMasahiro Yamada  * Else return -1 .
10180a9064fbSMasahiro Yamada  */
10190a9064fbSMasahiro Yamada static int do_match(int key, struct match_state *state, int *ans)
10200a9064fbSMasahiro Yamada {
10210a9064fbSMasahiro Yamada 	char c = (char) key;
10220a9064fbSMasahiro Yamada 	int terminate_search = 0;
10230a9064fbSMasahiro Yamada 	*ans = -1;
10240a9064fbSMasahiro Yamada 	if (key == '/' || (state->in_search && key == 27)) {
10250a9064fbSMasahiro Yamada 		move(0, 0);
10260a9064fbSMasahiro Yamada 		refresh();
10270a9064fbSMasahiro Yamada 		clrtoeol();
10280a9064fbSMasahiro Yamada 		state->in_search = 1-state->in_search;
10290a9064fbSMasahiro Yamada 		bzero(state->pattern, sizeof(state->pattern));
10300a9064fbSMasahiro Yamada 		state->match_direction = MATCH_TINKER_PATTERN_DOWN;
10310a9064fbSMasahiro Yamada 		return 0;
10320a9064fbSMasahiro Yamada 	} else if (!state->in_search)
10330a9064fbSMasahiro Yamada 		return 1;
10340a9064fbSMasahiro Yamada 
10350a9064fbSMasahiro Yamada 	if (isalnum(c) || isgraph(c) || c == ' ') {
10360a9064fbSMasahiro Yamada 		state->pattern[strlen(state->pattern)] = c;
10370a9064fbSMasahiro Yamada 		state->pattern[strlen(state->pattern)] = '\0';
10380a9064fbSMasahiro Yamada 		adj_match_dir(&state->match_direction);
10390a9064fbSMasahiro Yamada 		*ans = get_mext_match(state->pattern,
10400a9064fbSMasahiro Yamada 				state->match_direction);
10410a9064fbSMasahiro Yamada 	} else if (key == KEY_DOWN) {
10420a9064fbSMasahiro Yamada 		state->match_direction = FIND_NEXT_MATCH_DOWN;
10430a9064fbSMasahiro Yamada 		*ans = get_mext_match(state->pattern,
10440a9064fbSMasahiro Yamada 				state->match_direction);
10450a9064fbSMasahiro Yamada 	} else if (key == KEY_UP) {
10460a9064fbSMasahiro Yamada 		state->match_direction = FIND_NEXT_MATCH_UP;
10470a9064fbSMasahiro Yamada 		*ans = get_mext_match(state->pattern,
10480a9064fbSMasahiro Yamada 				state->match_direction);
10490a9064fbSMasahiro Yamada 	} else if (key == KEY_BACKSPACE || key == 127) {
10500a9064fbSMasahiro Yamada 		state->pattern[strlen(state->pattern)-1] = '\0';
10510a9064fbSMasahiro Yamada 		adj_match_dir(&state->match_direction);
10520a9064fbSMasahiro Yamada 	} else
10530a9064fbSMasahiro Yamada 		terminate_search = 1;
10540a9064fbSMasahiro Yamada 
10550a9064fbSMasahiro Yamada 	if (terminate_search) {
10560a9064fbSMasahiro Yamada 		state->in_search = 0;
10570a9064fbSMasahiro Yamada 		bzero(state->pattern, sizeof(state->pattern));
10580a9064fbSMasahiro Yamada 		move(0, 0);
10590a9064fbSMasahiro Yamada 		refresh();
10600a9064fbSMasahiro Yamada 		clrtoeol();
10610a9064fbSMasahiro Yamada 		return -1;
10620a9064fbSMasahiro Yamada 	}
10630a9064fbSMasahiro Yamada 	return 0;
10640a9064fbSMasahiro Yamada }
10650a9064fbSMasahiro Yamada 
10660a9064fbSMasahiro Yamada static void conf(struct menu *menu)
10670a9064fbSMasahiro Yamada {
10680a9064fbSMasahiro Yamada 	struct menu *submenu = 0;
10690a9064fbSMasahiro Yamada 	const char *prompt = menu_get_prompt(menu);
10700a9064fbSMasahiro Yamada 	struct symbol *sym;
10710a9064fbSMasahiro Yamada 	int res;
10720a9064fbSMasahiro Yamada 	int current_index = 0;
10730a9064fbSMasahiro Yamada 	int last_top_row = 0;
10740a9064fbSMasahiro Yamada 	struct match_state match_state = {
10750a9064fbSMasahiro Yamada 		.in_search = 0,
10760a9064fbSMasahiro Yamada 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
10770a9064fbSMasahiro Yamada 		.pattern = "",
10780a9064fbSMasahiro Yamada 	};
10790a9064fbSMasahiro Yamada 
10800a9064fbSMasahiro Yamada 	while (!global_exit) {
10810a9064fbSMasahiro Yamada 		reset_menu();
10820a9064fbSMasahiro Yamada 		current_menu = menu;
10830a9064fbSMasahiro Yamada 		build_conf(menu);
10840a9064fbSMasahiro Yamada 		if (!child_count)
10850a9064fbSMasahiro Yamada 			break;
10860a9064fbSMasahiro Yamada 
10870a9064fbSMasahiro Yamada 		show_menu(prompt ? _(prompt) : _("Main Menu"),
10880a9064fbSMasahiro Yamada 				_(menu_instructions),
10890a9064fbSMasahiro Yamada 				current_index, &last_top_row);
10900a9064fbSMasahiro Yamada 		keypad((menu_win(curses_menu)), TRUE);
10910a9064fbSMasahiro Yamada 		while (!global_exit) {
10920a9064fbSMasahiro Yamada 			if (match_state.in_search) {
10930a9064fbSMasahiro Yamada 				mvprintw(0, 0,
10940a9064fbSMasahiro Yamada 					"searching: %s", match_state.pattern);
10950a9064fbSMasahiro Yamada 				clrtoeol();
10960a9064fbSMasahiro Yamada 			}
10970a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
10980a9064fbSMasahiro Yamada 			res = wgetch(menu_win(curses_menu));
10990a9064fbSMasahiro Yamada 			if (!res)
11000a9064fbSMasahiro Yamada 				break;
11010a9064fbSMasahiro Yamada 			if (do_match(res, &match_state, &current_index) == 0) {
11020a9064fbSMasahiro Yamada 				if (current_index != -1)
11030a9064fbSMasahiro Yamada 					center_item(current_index,
11040a9064fbSMasahiro Yamada 						    &last_top_row);
11050a9064fbSMasahiro Yamada 				continue;
11060a9064fbSMasahiro Yamada 			}
11070a9064fbSMasahiro Yamada 			if (process_special_keys(&res,
11080a9064fbSMasahiro Yamada 						(struct menu *) item_data()))
11090a9064fbSMasahiro Yamada 				break;
11100a9064fbSMasahiro Yamada 			switch (res) {
11110a9064fbSMasahiro Yamada 			case KEY_DOWN:
11120a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_DOWN_ITEM);
11130a9064fbSMasahiro Yamada 				break;
11140a9064fbSMasahiro Yamada 			case KEY_UP:
11150a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_UP_ITEM);
11160a9064fbSMasahiro Yamada 				break;
11170a9064fbSMasahiro Yamada 			case KEY_NPAGE:
11180a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_DPAGE);
11190a9064fbSMasahiro Yamada 				break;
11200a9064fbSMasahiro Yamada 			case KEY_PPAGE:
11210a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_UPAGE);
11220a9064fbSMasahiro Yamada 				break;
11230a9064fbSMasahiro Yamada 			case KEY_HOME:
11240a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_FIRST_ITEM);
11250a9064fbSMasahiro Yamada 				break;
11260a9064fbSMasahiro Yamada 			case KEY_END:
11270a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_LAST_ITEM);
11280a9064fbSMasahiro Yamada 				break;
11290a9064fbSMasahiro Yamada 			case 'h':
11300a9064fbSMasahiro Yamada 			case '?':
11310a9064fbSMasahiro Yamada 				show_help((struct menu *) item_data());
11320a9064fbSMasahiro Yamada 				break;
11330a9064fbSMasahiro Yamada 			}
11340a9064fbSMasahiro Yamada 			if (res == 10 || res == 27 ||
11350a9064fbSMasahiro Yamada 				res == 32 || res == 'n' || res == 'y' ||
11360a9064fbSMasahiro Yamada 				res == KEY_LEFT || res == KEY_RIGHT ||
11370a9064fbSMasahiro Yamada 				res == 'm')
11380a9064fbSMasahiro Yamada 				break;
11390a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
11400a9064fbSMasahiro Yamada 		}
11410a9064fbSMasahiro Yamada 
11420a9064fbSMasahiro Yamada 		refresh_all_windows(main_window);
11430a9064fbSMasahiro Yamada 		/* if ESC or left*/
11440a9064fbSMasahiro Yamada 		if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
11450a9064fbSMasahiro Yamada 			break;
11460a9064fbSMasahiro Yamada 
11470a9064fbSMasahiro Yamada 		/* remember location in the menu */
11480a9064fbSMasahiro Yamada 		last_top_row = top_row(curses_menu);
11490a9064fbSMasahiro Yamada 		current_index = curses_item_index();
11500a9064fbSMasahiro Yamada 
11510a9064fbSMasahiro Yamada 		if (!item_tag())
11520a9064fbSMasahiro Yamada 			continue;
11530a9064fbSMasahiro Yamada 
11540a9064fbSMasahiro Yamada 		submenu = (struct menu *) item_data();
11550a9064fbSMasahiro Yamada 		if (!submenu || !menu_is_visible(submenu))
11560a9064fbSMasahiro Yamada 			continue;
11570a9064fbSMasahiro Yamada 		sym = submenu->sym;
11580a9064fbSMasahiro Yamada 
11590a9064fbSMasahiro Yamada 		switch (res) {
11600a9064fbSMasahiro Yamada 		case ' ':
11610a9064fbSMasahiro Yamada 			if (item_is_tag('t'))
11620a9064fbSMasahiro Yamada 				sym_toggle_tristate_value(sym);
11630a9064fbSMasahiro Yamada 			else if (item_is_tag('m'))
11640a9064fbSMasahiro Yamada 				conf(submenu);
11650a9064fbSMasahiro Yamada 			break;
11660a9064fbSMasahiro Yamada 		case KEY_RIGHT:
11670a9064fbSMasahiro Yamada 		case 10: /* ENTER WAS PRESSED */
11680a9064fbSMasahiro Yamada 			switch (item_tag()) {
11690a9064fbSMasahiro Yamada 			case 'm':
11700a9064fbSMasahiro Yamada 				if (single_menu_mode)
11710a9064fbSMasahiro Yamada 					submenu->data =
11720a9064fbSMasahiro Yamada 						(void *) (long) !submenu->data;
11730a9064fbSMasahiro Yamada 				else
11740a9064fbSMasahiro Yamada 					conf(submenu);
11750a9064fbSMasahiro Yamada 				break;
11760a9064fbSMasahiro Yamada 			case 't':
11770a9064fbSMasahiro Yamada 				if (sym_is_choice(sym) &&
11780a9064fbSMasahiro Yamada 				    sym_get_tristate_value(sym) == yes)
11790a9064fbSMasahiro Yamada 					conf_choice(submenu);
11800a9064fbSMasahiro Yamada 				else if (submenu->prompt &&
11810a9064fbSMasahiro Yamada 					 submenu->prompt->type == P_MENU)
11820a9064fbSMasahiro Yamada 					conf(submenu);
11830a9064fbSMasahiro Yamada 				else if (res == 10)
11840a9064fbSMasahiro Yamada 					sym_toggle_tristate_value(sym);
11850a9064fbSMasahiro Yamada 				break;
11860a9064fbSMasahiro Yamada 			case 's':
11870a9064fbSMasahiro Yamada 				conf_string(submenu);
11880a9064fbSMasahiro Yamada 				break;
11890a9064fbSMasahiro Yamada 			}
11900a9064fbSMasahiro Yamada 			break;
11910a9064fbSMasahiro Yamada 		case 'y':
11920a9064fbSMasahiro Yamada 			if (item_is_tag('t')) {
11930a9064fbSMasahiro Yamada 				if (sym_set_tristate_value(sym, yes))
11940a9064fbSMasahiro Yamada 					break;
11950a9064fbSMasahiro Yamada 				if (sym_set_tristate_value(sym, mod))
11960a9064fbSMasahiro Yamada 					btn_dialog(main_window, setmod_text, 0);
11970a9064fbSMasahiro Yamada 			}
11980a9064fbSMasahiro Yamada 			break;
11990a9064fbSMasahiro Yamada 		case 'n':
12000a9064fbSMasahiro Yamada 			if (item_is_tag('t'))
12010a9064fbSMasahiro Yamada 				sym_set_tristate_value(sym, no);
12020a9064fbSMasahiro Yamada 			break;
12030a9064fbSMasahiro Yamada 		case 'm':
12040a9064fbSMasahiro Yamada 			if (item_is_tag('t'))
12050a9064fbSMasahiro Yamada 				sym_set_tristate_value(sym, mod);
12060a9064fbSMasahiro Yamada 			break;
12070a9064fbSMasahiro Yamada 		}
12080a9064fbSMasahiro Yamada 	}
12090a9064fbSMasahiro Yamada }
12100a9064fbSMasahiro Yamada 
12110a9064fbSMasahiro Yamada static void conf_message_callback(const char *fmt, va_list ap)
12120a9064fbSMasahiro Yamada {
12130a9064fbSMasahiro Yamada 	char buf[1024];
12140a9064fbSMasahiro Yamada 
12150a9064fbSMasahiro Yamada 	vsnprintf(buf, sizeof(buf), fmt, ap);
12160a9064fbSMasahiro Yamada 	btn_dialog(main_window, buf, 1, "<OK>");
12170a9064fbSMasahiro Yamada }
12180a9064fbSMasahiro Yamada 
12190a9064fbSMasahiro Yamada static void show_help(struct menu *menu)
12200a9064fbSMasahiro Yamada {
12210a9064fbSMasahiro Yamada 	struct gstr help;
12220a9064fbSMasahiro Yamada 
12230a9064fbSMasahiro Yamada 	if (!menu)
12240a9064fbSMasahiro Yamada 		return;
12250a9064fbSMasahiro Yamada 
12260a9064fbSMasahiro Yamada 	help = str_new();
12270a9064fbSMasahiro Yamada 	menu_get_ext_help(menu, &help);
12280a9064fbSMasahiro Yamada 	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
12290a9064fbSMasahiro Yamada 	str_free(&help);
12300a9064fbSMasahiro Yamada }
12310a9064fbSMasahiro Yamada 
12320a9064fbSMasahiro Yamada static void conf_choice(struct menu *menu)
12330a9064fbSMasahiro Yamada {
12340a9064fbSMasahiro Yamada 	const char *prompt = _(menu_get_prompt(menu));
12350a9064fbSMasahiro Yamada 	struct menu *child = 0;
12360a9064fbSMasahiro Yamada 	struct symbol *active;
12370a9064fbSMasahiro Yamada 	int selected_index = 0;
12380a9064fbSMasahiro Yamada 	int last_top_row = 0;
12390a9064fbSMasahiro Yamada 	int res, i = 0;
12400a9064fbSMasahiro Yamada 	struct match_state match_state = {
12410a9064fbSMasahiro Yamada 		.in_search = 0,
12420a9064fbSMasahiro Yamada 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
12430a9064fbSMasahiro Yamada 		.pattern = "",
12440a9064fbSMasahiro Yamada 	};
12450a9064fbSMasahiro Yamada 
12460a9064fbSMasahiro Yamada 	active = sym_get_choice_value(menu->sym);
12470a9064fbSMasahiro Yamada 	/* this is mostly duplicated from the conf() function. */
12480a9064fbSMasahiro Yamada 	while (!global_exit) {
12490a9064fbSMasahiro Yamada 		reset_menu();
12500a9064fbSMasahiro Yamada 
12510a9064fbSMasahiro Yamada 		for (i = 0, child = menu->list; child; child = child->next) {
12520a9064fbSMasahiro Yamada 			if (!show_all_items && !menu_is_visible(child))
12530a9064fbSMasahiro Yamada 				continue;
12540a9064fbSMasahiro Yamada 
12550a9064fbSMasahiro Yamada 			if (child->sym == sym_get_choice_value(menu->sym))
12560a9064fbSMasahiro Yamada 				item_make(child, ':', "<X> %s",
12570a9064fbSMasahiro Yamada 						_(menu_get_prompt(child)));
12580a9064fbSMasahiro Yamada 			else if (child->sym)
12590a9064fbSMasahiro Yamada 				item_make(child, ':', "    %s",
12600a9064fbSMasahiro Yamada 						_(menu_get_prompt(child)));
12610a9064fbSMasahiro Yamada 			else
12620a9064fbSMasahiro Yamada 				item_make(child, ':', "*** %s ***",
12630a9064fbSMasahiro Yamada 						_(menu_get_prompt(child)));
12640a9064fbSMasahiro Yamada 
12650a9064fbSMasahiro Yamada 			if (child->sym == active){
12660a9064fbSMasahiro Yamada 				last_top_row = top_row(curses_menu);
12670a9064fbSMasahiro Yamada 				selected_index = i;
12680a9064fbSMasahiro Yamada 			}
12690a9064fbSMasahiro Yamada 			i++;
12700a9064fbSMasahiro Yamada 		}
12710a9064fbSMasahiro Yamada 		show_menu(prompt ? _(prompt) : _("Choice Menu"),
12720a9064fbSMasahiro Yamada 				_(radiolist_instructions),
12730a9064fbSMasahiro Yamada 				selected_index,
12740a9064fbSMasahiro Yamada 				&last_top_row);
12750a9064fbSMasahiro Yamada 		while (!global_exit) {
12760a9064fbSMasahiro Yamada 			if (match_state.in_search) {
12770a9064fbSMasahiro Yamada 				mvprintw(0, 0, "searching: %s",
12780a9064fbSMasahiro Yamada 					 match_state.pattern);
12790a9064fbSMasahiro Yamada 				clrtoeol();
12800a9064fbSMasahiro Yamada 			}
12810a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
12820a9064fbSMasahiro Yamada 			res = wgetch(menu_win(curses_menu));
12830a9064fbSMasahiro Yamada 			if (!res)
12840a9064fbSMasahiro Yamada 				break;
12850a9064fbSMasahiro Yamada 			if (do_match(res, &match_state, &selected_index) == 0) {
12860a9064fbSMasahiro Yamada 				if (selected_index != -1)
12870a9064fbSMasahiro Yamada 					center_item(selected_index,
12880a9064fbSMasahiro Yamada 						    &last_top_row);
12890a9064fbSMasahiro Yamada 				continue;
12900a9064fbSMasahiro Yamada 			}
12910a9064fbSMasahiro Yamada 			if (process_special_keys(
12920a9064fbSMasahiro Yamada 						&res,
12930a9064fbSMasahiro Yamada 						(struct menu *) item_data()))
12940a9064fbSMasahiro Yamada 				break;
12950a9064fbSMasahiro Yamada 			switch (res) {
12960a9064fbSMasahiro Yamada 			case KEY_DOWN:
12970a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_DOWN_ITEM);
12980a9064fbSMasahiro Yamada 				break;
12990a9064fbSMasahiro Yamada 			case KEY_UP:
13000a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_UP_ITEM);
13010a9064fbSMasahiro Yamada 				break;
13020a9064fbSMasahiro Yamada 			case KEY_NPAGE:
13030a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_DPAGE);
13040a9064fbSMasahiro Yamada 				break;
13050a9064fbSMasahiro Yamada 			case KEY_PPAGE:
13060a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_SCR_UPAGE);
13070a9064fbSMasahiro Yamada 				break;
13080a9064fbSMasahiro Yamada 			case KEY_HOME:
13090a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_FIRST_ITEM);
13100a9064fbSMasahiro Yamada 				break;
13110a9064fbSMasahiro Yamada 			case KEY_END:
13120a9064fbSMasahiro Yamada 				menu_driver(curses_menu, REQ_LAST_ITEM);
13130a9064fbSMasahiro Yamada 				break;
13140a9064fbSMasahiro Yamada 			case 'h':
13150a9064fbSMasahiro Yamada 			case '?':
13160a9064fbSMasahiro Yamada 				show_help((struct menu *) item_data());
13170a9064fbSMasahiro Yamada 				break;
13180a9064fbSMasahiro Yamada 			}
13190a9064fbSMasahiro Yamada 			if (res == 10 || res == 27 || res == ' ' ||
13200a9064fbSMasahiro Yamada 					res == KEY_LEFT){
13210a9064fbSMasahiro Yamada 				break;
13220a9064fbSMasahiro Yamada 			}
13230a9064fbSMasahiro Yamada 			refresh_all_windows(main_window);
13240a9064fbSMasahiro Yamada 		}
13250a9064fbSMasahiro Yamada 		/* if ESC or left */
13260a9064fbSMasahiro Yamada 		if (res == 27 || res == KEY_LEFT)
13270a9064fbSMasahiro Yamada 			break;
13280a9064fbSMasahiro Yamada 
13290a9064fbSMasahiro Yamada 		child = item_data();
13300a9064fbSMasahiro Yamada 		if (!child || !menu_is_visible(child) || !child->sym)
13310a9064fbSMasahiro Yamada 			continue;
13320a9064fbSMasahiro Yamada 		switch (res) {
13330a9064fbSMasahiro Yamada 		case ' ':
13340a9064fbSMasahiro Yamada 		case  10:
13350a9064fbSMasahiro Yamada 		case KEY_RIGHT:
13360a9064fbSMasahiro Yamada 			sym_set_tristate_value(child->sym, yes);
13370a9064fbSMasahiro Yamada 			return;
13380a9064fbSMasahiro Yamada 		case 'h':
13390a9064fbSMasahiro Yamada 		case '?':
13400a9064fbSMasahiro Yamada 			show_help(child);
13410a9064fbSMasahiro Yamada 			active = child->sym;
13420a9064fbSMasahiro Yamada 			break;
13430a9064fbSMasahiro Yamada 		case KEY_EXIT:
13440a9064fbSMasahiro Yamada 			return;
13450a9064fbSMasahiro Yamada 		}
13460a9064fbSMasahiro Yamada 	}
13470a9064fbSMasahiro Yamada }
13480a9064fbSMasahiro Yamada 
13490a9064fbSMasahiro Yamada static void conf_string(struct menu *menu)
13500a9064fbSMasahiro Yamada {
13510a9064fbSMasahiro Yamada 	const char *prompt = menu_get_prompt(menu);
13520a9064fbSMasahiro Yamada 
13530a9064fbSMasahiro Yamada 	while (1) {
13540a9064fbSMasahiro Yamada 		int res;
13550a9064fbSMasahiro Yamada 		const char *heading;
13560a9064fbSMasahiro Yamada 
13570a9064fbSMasahiro Yamada 		switch (sym_get_type(menu->sym)) {
13580a9064fbSMasahiro Yamada 		case S_INT:
13590a9064fbSMasahiro Yamada 			heading = _(inputbox_instructions_int);
13600a9064fbSMasahiro Yamada 			break;
13610a9064fbSMasahiro Yamada 		case S_HEX:
13620a9064fbSMasahiro Yamada 			heading = _(inputbox_instructions_hex);
13630a9064fbSMasahiro Yamada 			break;
13640a9064fbSMasahiro Yamada 		case S_STRING:
13650a9064fbSMasahiro Yamada 			heading = _(inputbox_instructions_string);
13660a9064fbSMasahiro Yamada 			break;
13670a9064fbSMasahiro Yamada 		default:
13680a9064fbSMasahiro Yamada 			heading = _("Internal nconf error!");
13690a9064fbSMasahiro Yamada 		}
13700a9064fbSMasahiro Yamada 		res = dialog_inputbox(main_window,
13710a9064fbSMasahiro Yamada 				prompt ? _(prompt) : _("Main Menu"),
13720a9064fbSMasahiro Yamada 				heading,
13730a9064fbSMasahiro Yamada 				sym_get_string_value(menu->sym),
13740a9064fbSMasahiro Yamada 				&dialog_input_result,
13750a9064fbSMasahiro Yamada 				&dialog_input_result_len);
13760a9064fbSMasahiro Yamada 		switch (res) {
13770a9064fbSMasahiro Yamada 		case 0:
13780a9064fbSMasahiro Yamada 			if (sym_set_string_value(menu->sym,
13790a9064fbSMasahiro Yamada 						dialog_input_result))
13800a9064fbSMasahiro Yamada 				return;
13810a9064fbSMasahiro Yamada 			btn_dialog(main_window,
13820a9064fbSMasahiro Yamada 				_("You have made an invalid entry."), 0);
13830a9064fbSMasahiro Yamada 			break;
13840a9064fbSMasahiro Yamada 		case 1:
13850a9064fbSMasahiro Yamada 			show_help(menu);
13860a9064fbSMasahiro Yamada 			break;
13870a9064fbSMasahiro Yamada 		case KEY_EXIT:
13880a9064fbSMasahiro Yamada 			return;
13890a9064fbSMasahiro Yamada 		}
13900a9064fbSMasahiro Yamada 	}
13910a9064fbSMasahiro Yamada }
13920a9064fbSMasahiro Yamada 
13930a9064fbSMasahiro Yamada static void conf_load(void)
13940a9064fbSMasahiro Yamada {
13950a9064fbSMasahiro Yamada 	while (1) {
13960a9064fbSMasahiro Yamada 		int res;
13970a9064fbSMasahiro Yamada 		res = dialog_inputbox(main_window,
13980a9064fbSMasahiro Yamada 				NULL, load_config_text,
13990a9064fbSMasahiro Yamada 				filename,
14000a9064fbSMasahiro Yamada 				&dialog_input_result,
14010a9064fbSMasahiro Yamada 				&dialog_input_result_len);
14020a9064fbSMasahiro Yamada 		switch (res) {
14030a9064fbSMasahiro Yamada 		case 0:
14040a9064fbSMasahiro Yamada 			if (!dialog_input_result[0])
14050a9064fbSMasahiro Yamada 				return;
14060a9064fbSMasahiro Yamada 			if (!conf_read(dialog_input_result)) {
14070a9064fbSMasahiro Yamada 				set_config_filename(dialog_input_result);
14080a9064fbSMasahiro Yamada 				sym_set_change_count(1);
14090a9064fbSMasahiro Yamada 				return;
14100a9064fbSMasahiro Yamada 			}
14110a9064fbSMasahiro Yamada 			btn_dialog(main_window, _("File does not exist!"), 0);
14120a9064fbSMasahiro Yamada 			break;
14130a9064fbSMasahiro Yamada 		case 1:
14140a9064fbSMasahiro Yamada 			show_scroll_win(main_window,
14150a9064fbSMasahiro Yamada 					_("Load Alternate Configuration"),
14160a9064fbSMasahiro Yamada 					load_config_help);
14170a9064fbSMasahiro Yamada 			break;
14180a9064fbSMasahiro Yamada 		case KEY_EXIT:
14190a9064fbSMasahiro Yamada 			return;
14200a9064fbSMasahiro Yamada 		}
14210a9064fbSMasahiro Yamada 	}
14220a9064fbSMasahiro Yamada }
14230a9064fbSMasahiro Yamada 
14240a9064fbSMasahiro Yamada static void conf_save(void)
14250a9064fbSMasahiro Yamada {
14260a9064fbSMasahiro Yamada 	while (1) {
14270a9064fbSMasahiro Yamada 		int res;
14280a9064fbSMasahiro Yamada 		res = dialog_inputbox(main_window,
14290a9064fbSMasahiro Yamada 				NULL, save_config_text,
14300a9064fbSMasahiro Yamada 				filename,
14310a9064fbSMasahiro Yamada 				&dialog_input_result,
14320a9064fbSMasahiro Yamada 				&dialog_input_result_len);
14330a9064fbSMasahiro Yamada 		switch (res) {
14340a9064fbSMasahiro Yamada 		case 0:
14350a9064fbSMasahiro Yamada 			if (!dialog_input_result[0])
14360a9064fbSMasahiro Yamada 				return;
14370a9064fbSMasahiro Yamada 			res = conf_write(dialog_input_result);
14380a9064fbSMasahiro Yamada 			if (!res) {
14390a9064fbSMasahiro Yamada 				set_config_filename(dialog_input_result);
14400a9064fbSMasahiro Yamada 				return;
14410a9064fbSMasahiro Yamada 			}
14420a9064fbSMasahiro Yamada 			btn_dialog(main_window, _("Can't create file! "
14430a9064fbSMasahiro Yamada 				"Probably a nonexistent directory."),
14440a9064fbSMasahiro Yamada 				1, "<OK>");
14450a9064fbSMasahiro Yamada 			break;
14460a9064fbSMasahiro Yamada 		case 1:
14470a9064fbSMasahiro Yamada 			show_scroll_win(main_window,
14480a9064fbSMasahiro Yamada 				_("Save Alternate Configuration"),
14490a9064fbSMasahiro Yamada 				save_config_help);
14500a9064fbSMasahiro Yamada 			break;
14510a9064fbSMasahiro Yamada 		case KEY_EXIT:
14520a9064fbSMasahiro Yamada 			return;
14530a9064fbSMasahiro Yamada 		}
14540a9064fbSMasahiro Yamada 	}
14550a9064fbSMasahiro Yamada }
14560a9064fbSMasahiro Yamada 
14570a9064fbSMasahiro Yamada void setup_windows(void)
14580a9064fbSMasahiro Yamada {
14590a9064fbSMasahiro Yamada 	int lines, columns;
14600a9064fbSMasahiro Yamada 
14610a9064fbSMasahiro Yamada 	getmaxyx(stdscr, lines, columns);
14620a9064fbSMasahiro Yamada 
14630a9064fbSMasahiro Yamada 	if (main_window != NULL)
14640a9064fbSMasahiro Yamada 		delwin(main_window);
14650a9064fbSMasahiro Yamada 
14660a9064fbSMasahiro Yamada 	/* set up the menu and menu window */
14670a9064fbSMasahiro Yamada 	main_window = newwin(lines-2, columns-2, 2, 1);
14680a9064fbSMasahiro Yamada 	keypad(main_window, TRUE);
14690a9064fbSMasahiro Yamada 	mwin_max_lines = lines-7;
14700a9064fbSMasahiro Yamada 	mwin_max_cols = columns-6;
14710a9064fbSMasahiro Yamada 
14720a9064fbSMasahiro Yamada 	/* panels order is from bottom to top */
14730a9064fbSMasahiro Yamada 	new_panel(main_window);
14740a9064fbSMasahiro Yamada }
14750a9064fbSMasahiro Yamada 
14760a9064fbSMasahiro Yamada int main(int ac, char **av)
14770a9064fbSMasahiro Yamada {
14780a9064fbSMasahiro Yamada 	int lines, columns;
14790a9064fbSMasahiro Yamada 	char *mode;
14800a9064fbSMasahiro Yamada 
14810a9064fbSMasahiro Yamada 	setlocale(LC_ALL, "");
14820a9064fbSMasahiro Yamada 	bindtextdomain(PACKAGE, LOCALEDIR);
14830a9064fbSMasahiro Yamada 	textdomain(PACKAGE);
14840a9064fbSMasahiro Yamada 
1485*9b5f0b1dSMasahiro Yamada 	if (ac > 1 && strcmp(av[1], "-s") == 0) {
1486*9b5f0b1dSMasahiro Yamada 		/* Silence conf_read() until the real callback is set up */
1487*9b5f0b1dSMasahiro Yamada 		conf_set_message_callback(NULL);
1488*9b5f0b1dSMasahiro Yamada 		av++;
1489*9b5f0b1dSMasahiro Yamada 	}
14900a9064fbSMasahiro Yamada 	conf_parse(av[1]);
14910a9064fbSMasahiro Yamada 	conf_read(NULL);
14920a9064fbSMasahiro Yamada 
14930a9064fbSMasahiro Yamada 	mode = getenv("NCONFIG_MODE");
14940a9064fbSMasahiro Yamada 	if (mode) {
14950a9064fbSMasahiro Yamada 		if (!strcasecmp(mode, "single_menu"))
14960a9064fbSMasahiro Yamada 			single_menu_mode = 1;
14970a9064fbSMasahiro Yamada 	}
14980a9064fbSMasahiro Yamada 
14990a9064fbSMasahiro Yamada 	/* Initialize curses */
15000a9064fbSMasahiro Yamada 	initscr();
15010a9064fbSMasahiro Yamada 	/* set color theme */
15020a9064fbSMasahiro Yamada 	set_colors();
15030a9064fbSMasahiro Yamada 
15040a9064fbSMasahiro Yamada 	cbreak();
15050a9064fbSMasahiro Yamada 	noecho();
15060a9064fbSMasahiro Yamada 	keypad(stdscr, TRUE);
15070a9064fbSMasahiro Yamada 	curs_set(0);
15080a9064fbSMasahiro Yamada 
15090a9064fbSMasahiro Yamada 	getmaxyx(stdscr, lines, columns);
15100a9064fbSMasahiro Yamada 	if (columns < 75 || lines < 20) {
15110a9064fbSMasahiro Yamada 		endwin();
15120a9064fbSMasahiro Yamada 		printf("Your terminal should have at "
15130a9064fbSMasahiro Yamada 			"least 20 lines and 75 columns\n");
15140a9064fbSMasahiro Yamada 		return 1;
15150a9064fbSMasahiro Yamada 	}
15160a9064fbSMasahiro Yamada 
15170a9064fbSMasahiro Yamada 	notimeout(stdscr, FALSE);
15180a9064fbSMasahiro Yamada #if NCURSES_REENTRANT
15190a9064fbSMasahiro Yamada 	set_escdelay(1);
15200a9064fbSMasahiro Yamada #else
15210a9064fbSMasahiro Yamada 	ESCDELAY = 1;
15220a9064fbSMasahiro Yamada #endif
15230a9064fbSMasahiro Yamada 
15240a9064fbSMasahiro Yamada 	/* set btns menu */
15250a9064fbSMasahiro Yamada 	curses_menu = new_menu(curses_menu_items);
15260a9064fbSMasahiro Yamada 	menu_opts_off(curses_menu, O_SHOWDESC);
15270a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_SHOWMATCH);
15280a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_ONEVALUE);
15290a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_NONCYCLIC);
15300a9064fbSMasahiro Yamada 	menu_opts_on(curses_menu, O_IGNORECASE);
15310a9064fbSMasahiro Yamada 	set_menu_mark(curses_menu, " ");
15320a9064fbSMasahiro Yamada 	set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
15330a9064fbSMasahiro Yamada 	set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
15340a9064fbSMasahiro Yamada 	set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
15350a9064fbSMasahiro Yamada 
15360a9064fbSMasahiro Yamada 	set_config_filename(conf_get_configname());
15370a9064fbSMasahiro Yamada 	setup_windows();
15380a9064fbSMasahiro Yamada 
15390a9064fbSMasahiro Yamada 	/* check for KEY_FUNC(1) */
15400a9064fbSMasahiro Yamada 	if (has_key(KEY_F(1)) == FALSE) {
15410a9064fbSMasahiro Yamada 		show_scroll_win(main_window,
15420a9064fbSMasahiro Yamada 				_("Instructions"),
15430a9064fbSMasahiro Yamada 				_(menu_no_f_instructions));
15440a9064fbSMasahiro Yamada 	}
15450a9064fbSMasahiro Yamada 
15460a9064fbSMasahiro Yamada 	conf_set_message_callback(conf_message_callback);
15470a9064fbSMasahiro Yamada 	/* do the work */
15480a9064fbSMasahiro Yamada 	while (!global_exit) {
15490a9064fbSMasahiro Yamada 		conf(&rootmenu);
15500a9064fbSMasahiro Yamada 		if (!global_exit && do_exit() == 0)
15510a9064fbSMasahiro Yamada 			break;
15520a9064fbSMasahiro Yamada 	}
15530a9064fbSMasahiro Yamada 	/* ok, we are done */
15540a9064fbSMasahiro Yamada 	unpost_menu(curses_menu);
15550a9064fbSMasahiro Yamada 	free_menu(curses_menu);
15560a9064fbSMasahiro Yamada 	delwin(main_window);
15570a9064fbSMasahiro Yamada 	clear();
15580a9064fbSMasahiro Yamada 	refresh();
15590a9064fbSMasahiro Yamada 	endwin();
15600a9064fbSMasahiro Yamada 	return 0;
15610a9064fbSMasahiro Yamada }
1562