18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com>
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Derived from menuconfig.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#ifndef _GNU_SOURCE
88c2ecf20Sopenharmony_ci#define _GNU_SOURCE
98c2ecf20Sopenharmony_ci#endif
108c2ecf20Sopenharmony_ci#include <string.h>
118c2ecf20Sopenharmony_ci#include <strings.h>
128c2ecf20Sopenharmony_ci#include <stdlib.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include "lkc.h"
158c2ecf20Sopenharmony_ci#include "nconf.h"
168c2ecf20Sopenharmony_ci#include <ctype.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic const char nconf_global_help[] =
198c2ecf20Sopenharmony_ci"Help windows\n"
208c2ecf20Sopenharmony_ci"------------\n"
218c2ecf20Sopenharmony_ci"o  Global help:  Unless in a data entry window, pressing <F1> will give \n"
228c2ecf20Sopenharmony_ci"   you the global help window, which you are just reading.\n"
238c2ecf20Sopenharmony_ci"\n"
248c2ecf20Sopenharmony_ci"o  A short version of the global help is available by pressing <F3>.\n"
258c2ecf20Sopenharmony_ci"\n"
268c2ecf20Sopenharmony_ci"o  Local help:  To get help related to the current menu entry, use any\n"
278c2ecf20Sopenharmony_ci"   of <?> <h>, or if in a data entry window then press <F1>.\n"
288c2ecf20Sopenharmony_ci"\n"
298c2ecf20Sopenharmony_ci"\n"
308c2ecf20Sopenharmony_ci"Menu entries\n"
318c2ecf20Sopenharmony_ci"------------\n"
328c2ecf20Sopenharmony_ci"This interface lets you select features and parameters for the kernel\n"
338c2ecf20Sopenharmony_ci"build.  Kernel features can either be built-in, modularized, or removed.\n"
348c2ecf20Sopenharmony_ci"Parameters must be entered as text or decimal or hexadecimal numbers.\n"
358c2ecf20Sopenharmony_ci"\n"
368c2ecf20Sopenharmony_ci"Menu entries beginning with following braces represent features that\n"
378c2ecf20Sopenharmony_ci"  [ ]  can be built in or removed\n"
388c2ecf20Sopenharmony_ci"  < >  can be built in, modularized or removed\n"
398c2ecf20Sopenharmony_ci"  { }  can be built in or modularized, are selected by another feature\n"
408c2ecf20Sopenharmony_ci"  - -  are selected by another feature\n"
418c2ecf20Sopenharmony_ci"  XXX  cannot be selected.  Symbol Info <F2> tells you why.\n"
428c2ecf20Sopenharmony_ci"*, M or whitespace inside braces means to build in, build as a module\n"
438c2ecf20Sopenharmony_ci"or to exclude the feature respectively.\n"
448c2ecf20Sopenharmony_ci"\n"
458c2ecf20Sopenharmony_ci"To change any of these features, highlight it with the movement keys\n"
468c2ecf20Sopenharmony_ci"listed below and press <y> to build it in, <m> to make it a module or\n"
478c2ecf20Sopenharmony_ci"<n> to remove it.  You may press the <Space> key to cycle through the\n"
488c2ecf20Sopenharmony_ci"available options.\n"
498c2ecf20Sopenharmony_ci"\n"
508c2ecf20Sopenharmony_ci"A trailing \"--->\" designates a submenu, a trailing \"----\" an\n"
518c2ecf20Sopenharmony_ci"empty submenu.\n"
528c2ecf20Sopenharmony_ci"\n"
538c2ecf20Sopenharmony_ci"Menu navigation keys\n"
548c2ecf20Sopenharmony_ci"----------------------------------------------------------------------\n"
558c2ecf20Sopenharmony_ci"Linewise up                 <Up>\n"
568c2ecf20Sopenharmony_ci"Linewise down               <Down>\n"
578c2ecf20Sopenharmony_ci"Pagewise up                 <Page Up>\n"
588c2ecf20Sopenharmony_ci"Pagewise down               <Page Down>\n"
598c2ecf20Sopenharmony_ci"First entry                 <Home>\n"
608c2ecf20Sopenharmony_ci"Last entry                  <End>\n"
618c2ecf20Sopenharmony_ci"Enter a submenu             <Right>  <Enter>\n"
628c2ecf20Sopenharmony_ci"Go back to parent menu      <Left>   <Esc>  <F5>\n"
638c2ecf20Sopenharmony_ci"Close a help window         <Enter>  <Esc>  <F5>\n"
648c2ecf20Sopenharmony_ci"Close entry window, apply   <Enter>\n"
658c2ecf20Sopenharmony_ci"Close entry window, forget  <Esc>  <F5>\n"
668c2ecf20Sopenharmony_ci"Start incremental, case-insensitive search for STRING in menu entries,\n"
678c2ecf20Sopenharmony_ci"    no regex support, STRING is displayed in upper left corner\n"
688c2ecf20Sopenharmony_ci"                            </>STRING\n"
698c2ecf20Sopenharmony_ci"    Remove last character   <Backspace>\n"
708c2ecf20Sopenharmony_ci"    Jump to next hit        <Down>\n"
718c2ecf20Sopenharmony_ci"    Jump to previous hit    <Up>\n"
728c2ecf20Sopenharmony_ci"Exit menu search mode       </>  <Esc>\n"
738c2ecf20Sopenharmony_ci"Search for configuration variables with or without leading CONFIG_\n"
748c2ecf20Sopenharmony_ci"                            <F8>RegExpr<Enter>\n"
758c2ecf20Sopenharmony_ci"Verbose search help         <F8><F1>\n"
768c2ecf20Sopenharmony_ci"----------------------------------------------------------------------\n"
778c2ecf20Sopenharmony_ci"\n"
788c2ecf20Sopenharmony_ci"Unless in a data entry window, key <1> may be used instead of <F1>,\n"
798c2ecf20Sopenharmony_ci"<2> instead of <F2>, etc.\n"
808c2ecf20Sopenharmony_ci"\n"
818c2ecf20Sopenharmony_ci"\n"
828c2ecf20Sopenharmony_ci"Radiolist (Choice list)\n"
838c2ecf20Sopenharmony_ci"-----------------------\n"
848c2ecf20Sopenharmony_ci"Use the movement keys listed above to select the option you wish to set\n"
858c2ecf20Sopenharmony_ci"and press <Space>.\n"
868c2ecf20Sopenharmony_ci"\n"
878c2ecf20Sopenharmony_ci"\n"
888c2ecf20Sopenharmony_ci"Data entry\n"
898c2ecf20Sopenharmony_ci"----------\n"
908c2ecf20Sopenharmony_ci"Enter the requested information and press <Enter>.  Hexadecimal values\n"
918c2ecf20Sopenharmony_ci"may be entered without the \"0x\" prefix.\n"
928c2ecf20Sopenharmony_ci"\n"
938c2ecf20Sopenharmony_ci"\n"
948c2ecf20Sopenharmony_ci"Text Box (Help Window)\n"
958c2ecf20Sopenharmony_ci"----------------------\n"
968c2ecf20Sopenharmony_ci"Use movement keys as listed in table above.\n"
978c2ecf20Sopenharmony_ci"\n"
988c2ecf20Sopenharmony_ci"Press any of <Enter> <Esc> <q> <F5> <F9> to exit.\n"
998c2ecf20Sopenharmony_ci"\n"
1008c2ecf20Sopenharmony_ci"\n"
1018c2ecf20Sopenharmony_ci"Alternate configuration files\n"
1028c2ecf20Sopenharmony_ci"-----------------------------\n"
1038c2ecf20Sopenharmony_ci"nconfig supports switching between different configurations.\n"
1048c2ecf20Sopenharmony_ci"Press <F6> to save your current configuration.  Press <F7> and enter\n"
1058c2ecf20Sopenharmony_ci"a file name to load a previously saved configuration.\n"
1068c2ecf20Sopenharmony_ci"\n"
1078c2ecf20Sopenharmony_ci"\n"
1088c2ecf20Sopenharmony_ci"Terminal configuration\n"
1098c2ecf20Sopenharmony_ci"----------------------\n"
1108c2ecf20Sopenharmony_ci"If you use nconfig in a xterm window, make sure your TERM environment\n"
1118c2ecf20Sopenharmony_ci"variable specifies a terminal configuration which supports at least\n"
1128c2ecf20Sopenharmony_ci"16 colors.  Otherwise nconfig will look rather bad.\n"
1138c2ecf20Sopenharmony_ci"\n"
1148c2ecf20Sopenharmony_ci"If the \"stty size\" command reports the current terminalsize correctly,\n"
1158c2ecf20Sopenharmony_ci"nconfig will adapt to sizes larger than the traditional 80x25 \"standard\"\n"
1168c2ecf20Sopenharmony_ci"and display longer menus properly.\n"
1178c2ecf20Sopenharmony_ci"\n"
1188c2ecf20Sopenharmony_ci"\n"
1198c2ecf20Sopenharmony_ci"Single menu mode\n"
1208c2ecf20Sopenharmony_ci"----------------\n"
1218c2ecf20Sopenharmony_ci"If you prefer to have all of the menu entries listed in a single menu,\n"
1228c2ecf20Sopenharmony_ci"rather than the default multimenu hierarchy, run nconfig with\n"
1238c2ecf20Sopenharmony_ci"NCONFIG_MODE environment variable set to single_menu.  Example:\n"
1248c2ecf20Sopenharmony_ci"\n"
1258c2ecf20Sopenharmony_ci"make NCONFIG_MODE=single_menu nconfig\n"
1268c2ecf20Sopenharmony_ci"\n"
1278c2ecf20Sopenharmony_ci"<Enter> will then unfold the appropriate category, or fold it if it\n"
1288c2ecf20Sopenharmony_ci"is already unfolded.  Folded menu entries will be designated by a\n"
1298c2ecf20Sopenharmony_ci"leading \"++>\" and unfolded entries by a leading \"-->\".\n"
1308c2ecf20Sopenharmony_ci"\n"
1318c2ecf20Sopenharmony_ci"Note that this mode can eventually be a little more CPU expensive than\n"
1328c2ecf20Sopenharmony_ci"the default mode, especially with a larger number of unfolded submenus.\n"
1338c2ecf20Sopenharmony_ci"\n",
1348c2ecf20Sopenharmony_cimenu_no_f_instructions[] =
1358c2ecf20Sopenharmony_ci"Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1368c2ecf20Sopenharmony_ci"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
1378c2ecf20Sopenharmony_ci"\n"
1388c2ecf20Sopenharmony_ci"Use the following keys to navigate the menus:\n"
1398c2ecf20Sopenharmony_ci"Move up or down with <Up> and <Down>.\n"
1408c2ecf20Sopenharmony_ci"Enter a submenu with <Enter> or <Right>.\n"
1418c2ecf20Sopenharmony_ci"Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1428c2ecf20Sopenharmony_ci"Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1438c2ecf20Sopenharmony_ci"Pressing <Space> cycles through the available options.\n"
1448c2ecf20Sopenharmony_ci"To search for menu entries press </>.\n"
1458c2ecf20Sopenharmony_ci"<Esc> always leaves the current window.\n"
1468c2ecf20Sopenharmony_ci"\n"
1478c2ecf20Sopenharmony_ci"You do not have function keys support.\n"
1488c2ecf20Sopenharmony_ci"Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
1498c2ecf20Sopenharmony_ci"For verbose global help use key <1>.\n"
1508c2ecf20Sopenharmony_ci"For help related to the current menu entry press <?> or <h>.\n",
1518c2ecf20Sopenharmony_cimenu_instructions[] =
1528c2ecf20Sopenharmony_ci"Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
1538c2ecf20Sopenharmony_ci"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
1548c2ecf20Sopenharmony_ci"\n"
1558c2ecf20Sopenharmony_ci"Use the following keys to navigate the menus:\n"
1568c2ecf20Sopenharmony_ci"Move up or down with <Up> or <Down>.\n"
1578c2ecf20Sopenharmony_ci"Enter a submenu with <Enter> or <Right>.\n"
1588c2ecf20Sopenharmony_ci"Exit a submenu to its parent menu with <Esc> or <Left>.\n"
1598c2ecf20Sopenharmony_ci"Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
1608c2ecf20Sopenharmony_ci"Pressing <Space> cycles through the available options.\n"
1618c2ecf20Sopenharmony_ci"To search for menu entries press </>.\n"
1628c2ecf20Sopenharmony_ci"<Esc> always leaves the current window.\n"
1638c2ecf20Sopenharmony_ci"\n"
1648c2ecf20Sopenharmony_ci"Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
1658c2ecf20Sopenharmony_ci"For verbose global help press <F1>.\n"
1668c2ecf20Sopenharmony_ci"For help related to the current menu entry press <?> or <h>.\n",
1678c2ecf20Sopenharmony_ciradiolist_instructions[] =
1688c2ecf20Sopenharmony_ci"Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
1698c2ecf20Sopenharmony_ci"with <Space>.\n"
1708c2ecf20Sopenharmony_ci"For help related to the current entry press <?> or <h>.\n"
1718c2ecf20Sopenharmony_ci"For global help press <F1>.\n",
1728c2ecf20Sopenharmony_ciinputbox_instructions_int[] =
1738c2ecf20Sopenharmony_ci"Please enter a decimal value.\n"
1748c2ecf20Sopenharmony_ci"Fractions will not be accepted.\n"
1758c2ecf20Sopenharmony_ci"Press <Enter> to apply, <Esc> to cancel.",
1768c2ecf20Sopenharmony_ciinputbox_instructions_hex[] =
1778c2ecf20Sopenharmony_ci"Please enter a hexadecimal value.\n"
1788c2ecf20Sopenharmony_ci"Press <Enter> to apply, <Esc> to cancel.",
1798c2ecf20Sopenharmony_ciinputbox_instructions_string[] =
1808c2ecf20Sopenharmony_ci"Please enter a string value.\n"
1818c2ecf20Sopenharmony_ci"Press <Enter> to apply, <Esc> to cancel.",
1828c2ecf20Sopenharmony_cisetmod_text[] =
1838c2ecf20Sopenharmony_ci"This feature depends on another feature which has been configured as a\n"
1848c2ecf20Sopenharmony_ci"module.  As a result, the current feature will be built as a module too.",
1858c2ecf20Sopenharmony_ciload_config_text[] =
1868c2ecf20Sopenharmony_ci"Enter the name of the configuration file you wish to load.\n"
1878c2ecf20Sopenharmony_ci"Accept the name shown to restore the configuration you last\n"
1888c2ecf20Sopenharmony_ci"retrieved.  Leave empty to abort.",
1898c2ecf20Sopenharmony_ciload_config_help[] =
1908c2ecf20Sopenharmony_ci"For various reasons, one may wish to keep several different\n"
1918c2ecf20Sopenharmony_ci"configurations available on a single machine.\n"
1928c2ecf20Sopenharmony_ci"\n"
1938c2ecf20Sopenharmony_ci"If you have saved a previous configuration in a file other than the\n"
1948c2ecf20Sopenharmony_ci"default one, entering its name here will allow you to load and modify\n"
1958c2ecf20Sopenharmony_ci"that configuration.\n"
1968c2ecf20Sopenharmony_ci"\n"
1978c2ecf20Sopenharmony_ci"Leave empty to abort.\n",
1988c2ecf20Sopenharmony_cisave_config_text[] =
1998c2ecf20Sopenharmony_ci"Enter a filename to which this configuration should be saved\n"
2008c2ecf20Sopenharmony_ci"as an alternate.  Leave empty to abort.",
2018c2ecf20Sopenharmony_cisave_config_help[] =
2028c2ecf20Sopenharmony_ci"For various reasons, one may wish to keep several different\n"
2038c2ecf20Sopenharmony_ci"configurations available on a single machine.\n"
2048c2ecf20Sopenharmony_ci"\n"
2058c2ecf20Sopenharmony_ci"Entering a file name here will allow you to later retrieve, modify\n"
2068c2ecf20Sopenharmony_ci"and use the current configuration as an alternate to whatever\n"
2078c2ecf20Sopenharmony_ci"configuration options you have selected at that time.\n"
2088c2ecf20Sopenharmony_ci"\n"
2098c2ecf20Sopenharmony_ci"Leave empty to abort.\n",
2108c2ecf20Sopenharmony_cisearch_help[] =
2118c2ecf20Sopenharmony_ci"Search for symbols (configuration variable names CONFIG_*) and display\n"
2128c2ecf20Sopenharmony_ci"their relations.  Regular expressions are supported.\n"
2138c2ecf20Sopenharmony_ci"Example:  Search for \"^FOO\".\n"
2148c2ecf20Sopenharmony_ci"Result:\n"
2158c2ecf20Sopenharmony_ci"-----------------------------------------------------------------\n"
2168c2ecf20Sopenharmony_ci"Symbol: FOO [ = m]\n"
2178c2ecf20Sopenharmony_ci"Prompt: Foo bus is used to drive the bar HW\n"
2188c2ecf20Sopenharmony_ci"Defined at drivers/pci/Kconfig:47\n"
2198c2ecf20Sopenharmony_ci"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
2208c2ecf20Sopenharmony_ci"Location:\n"
2218c2ecf20Sopenharmony_ci"  -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
2228c2ecf20Sopenharmony_ci"    -> PCI support (PCI [ = y])\n"
2238c2ecf20Sopenharmony_ci"      -> PCI access mode (<choice> [ = y])\n"
2248c2ecf20Sopenharmony_ci"Selects: LIBCRC32\n"
2258c2ecf20Sopenharmony_ci"Selected by: BAR\n"
2268c2ecf20Sopenharmony_ci"-----------------------------------------------------------------\n"
2278c2ecf20Sopenharmony_ci"o  The line 'Prompt:' shows the text displayed for this symbol in\n"
2288c2ecf20Sopenharmony_ci"   the menu hierarchy.\n"
2298c2ecf20Sopenharmony_ci"o  The 'Defined at' line tells at what file / line number the symbol is\n"
2308c2ecf20Sopenharmony_ci"   defined.\n"
2318c2ecf20Sopenharmony_ci"o  The 'Depends on:' line lists symbols that need to be defined for\n"
2328c2ecf20Sopenharmony_ci"   this symbol to be visible and selectable in the menu.\n"
2338c2ecf20Sopenharmony_ci"o  The 'Location:' lines tell, where in the menu structure this symbol\n"
2348c2ecf20Sopenharmony_ci"   is located.  A location followed by a [ = y] indicates that this is\n"
2358c2ecf20Sopenharmony_ci"   a selectable menu item, and the current value is displayed inside\n"
2368c2ecf20Sopenharmony_ci"   brackets.\n"
2378c2ecf20Sopenharmony_ci"o  The 'Selects:' line tells, what symbol will be automatically selected\n"
2388c2ecf20Sopenharmony_ci"   if this symbol is selected (y or m).\n"
2398c2ecf20Sopenharmony_ci"o  The 'Selected by' line tells what symbol has selected this symbol.\n"
2408c2ecf20Sopenharmony_ci"\n"
2418c2ecf20Sopenharmony_ci"Only relevant lines are shown.\n"
2428c2ecf20Sopenharmony_ci"\n\n"
2438c2ecf20Sopenharmony_ci"Search examples:\n"
2448c2ecf20Sopenharmony_ci"USB  => find all symbols containing USB\n"
2458c2ecf20Sopenharmony_ci"^USB => find all symbols starting with USB\n"
2468c2ecf20Sopenharmony_ci"USB$ => find all symbols ending with USB\n"
2478c2ecf20Sopenharmony_ci"\n";
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_cistruct mitem {
2508c2ecf20Sopenharmony_ci	char str[256];
2518c2ecf20Sopenharmony_ci	char tag;
2528c2ecf20Sopenharmony_ci	void *usrptr;
2538c2ecf20Sopenharmony_ci	int is_visible;
2548c2ecf20Sopenharmony_ci};
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci#define MAX_MENU_ITEMS 4096
2578c2ecf20Sopenharmony_cistatic int show_all_items;
2588c2ecf20Sopenharmony_cistatic int indent;
2598c2ecf20Sopenharmony_cistatic struct menu *current_menu;
2608c2ecf20Sopenharmony_cistatic int child_count;
2618c2ecf20Sopenharmony_cistatic int single_menu_mode;
2628c2ecf20Sopenharmony_ci/* the window in which all information appears */
2638c2ecf20Sopenharmony_cistatic WINDOW *main_window;
2648c2ecf20Sopenharmony_ci/* the largest size of the menu window */
2658c2ecf20Sopenharmony_cistatic int mwin_max_lines;
2668c2ecf20Sopenharmony_cistatic int mwin_max_cols;
2678c2ecf20Sopenharmony_ci/* the window in which we show option buttons */
2688c2ecf20Sopenharmony_cistatic MENU *curses_menu;
2698c2ecf20Sopenharmony_cistatic ITEM *curses_menu_items[MAX_MENU_ITEMS];
2708c2ecf20Sopenharmony_cistatic struct mitem k_menu_items[MAX_MENU_ITEMS];
2718c2ecf20Sopenharmony_cistatic int items_num;
2728c2ecf20Sopenharmony_cistatic int global_exit;
2738c2ecf20Sopenharmony_ci/* the currently selected button */
2748c2ecf20Sopenharmony_cistatic const char *current_instructions = menu_instructions;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_cistatic char *dialog_input_result;
2778c2ecf20Sopenharmony_cistatic int dialog_input_result_len;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_cistatic void conf(struct menu *menu);
2808c2ecf20Sopenharmony_cistatic void conf_choice(struct menu *menu);
2818c2ecf20Sopenharmony_cistatic void conf_string(struct menu *menu);
2828c2ecf20Sopenharmony_cistatic void conf_load(void);
2838c2ecf20Sopenharmony_cistatic void conf_save(void);
2848c2ecf20Sopenharmony_cistatic void show_help(struct menu *menu);
2858c2ecf20Sopenharmony_cistatic int do_exit(void);
2868c2ecf20Sopenharmony_cistatic void setup_windows(void);
2878c2ecf20Sopenharmony_cistatic void search_conf(void);
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_citypedef void (*function_key_handler_t)(int *key, struct menu *menu);
2908c2ecf20Sopenharmony_cistatic void handle_f1(int *key, struct menu *current_item);
2918c2ecf20Sopenharmony_cistatic void handle_f2(int *key, struct menu *current_item);
2928c2ecf20Sopenharmony_cistatic void handle_f3(int *key, struct menu *current_item);
2938c2ecf20Sopenharmony_cistatic void handle_f4(int *key, struct menu *current_item);
2948c2ecf20Sopenharmony_cistatic void handle_f5(int *key, struct menu *current_item);
2958c2ecf20Sopenharmony_cistatic void handle_f6(int *key, struct menu *current_item);
2968c2ecf20Sopenharmony_cistatic void handle_f7(int *key, struct menu *current_item);
2978c2ecf20Sopenharmony_cistatic void handle_f8(int *key, struct menu *current_item);
2988c2ecf20Sopenharmony_cistatic void handle_f9(int *key, struct menu *current_item);
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_cistruct function_keys {
3018c2ecf20Sopenharmony_ci	const char *key_str;
3028c2ecf20Sopenharmony_ci	const char *func;
3038c2ecf20Sopenharmony_ci	function_key key;
3048c2ecf20Sopenharmony_ci	function_key_handler_t handler;
3058c2ecf20Sopenharmony_ci};
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_cistatic const int function_keys_num = 9;
3088c2ecf20Sopenharmony_cistatic struct function_keys function_keys[] = {
3098c2ecf20Sopenharmony_ci	{
3108c2ecf20Sopenharmony_ci		.key_str = "F1",
3118c2ecf20Sopenharmony_ci		.func = "Help",
3128c2ecf20Sopenharmony_ci		.key = F_HELP,
3138c2ecf20Sopenharmony_ci		.handler = handle_f1,
3148c2ecf20Sopenharmony_ci	},
3158c2ecf20Sopenharmony_ci	{
3168c2ecf20Sopenharmony_ci		.key_str = "F2",
3178c2ecf20Sopenharmony_ci		.func = "SymInfo",
3188c2ecf20Sopenharmony_ci		.key = F_SYMBOL,
3198c2ecf20Sopenharmony_ci		.handler = handle_f2,
3208c2ecf20Sopenharmony_ci	},
3218c2ecf20Sopenharmony_ci	{
3228c2ecf20Sopenharmony_ci		.key_str = "F3",
3238c2ecf20Sopenharmony_ci		.func = "Help 2",
3248c2ecf20Sopenharmony_ci		.key = F_INSTS,
3258c2ecf20Sopenharmony_ci		.handler = handle_f3,
3268c2ecf20Sopenharmony_ci	},
3278c2ecf20Sopenharmony_ci	{
3288c2ecf20Sopenharmony_ci		.key_str = "F4",
3298c2ecf20Sopenharmony_ci		.func = "ShowAll",
3308c2ecf20Sopenharmony_ci		.key = F_CONF,
3318c2ecf20Sopenharmony_ci		.handler = handle_f4,
3328c2ecf20Sopenharmony_ci	},
3338c2ecf20Sopenharmony_ci	{
3348c2ecf20Sopenharmony_ci		.key_str = "F5",
3358c2ecf20Sopenharmony_ci		.func = "Back",
3368c2ecf20Sopenharmony_ci		.key = F_BACK,
3378c2ecf20Sopenharmony_ci		.handler = handle_f5,
3388c2ecf20Sopenharmony_ci	},
3398c2ecf20Sopenharmony_ci	{
3408c2ecf20Sopenharmony_ci		.key_str = "F6",
3418c2ecf20Sopenharmony_ci		.func = "Save",
3428c2ecf20Sopenharmony_ci		.key = F_SAVE,
3438c2ecf20Sopenharmony_ci		.handler = handle_f6,
3448c2ecf20Sopenharmony_ci	},
3458c2ecf20Sopenharmony_ci	{
3468c2ecf20Sopenharmony_ci		.key_str = "F7",
3478c2ecf20Sopenharmony_ci		.func = "Load",
3488c2ecf20Sopenharmony_ci		.key = F_LOAD,
3498c2ecf20Sopenharmony_ci		.handler = handle_f7,
3508c2ecf20Sopenharmony_ci	},
3518c2ecf20Sopenharmony_ci	{
3528c2ecf20Sopenharmony_ci		.key_str = "F8",
3538c2ecf20Sopenharmony_ci		.func = "SymSearch",
3548c2ecf20Sopenharmony_ci		.key = F_SEARCH,
3558c2ecf20Sopenharmony_ci		.handler = handle_f8,
3568c2ecf20Sopenharmony_ci	},
3578c2ecf20Sopenharmony_ci	{
3588c2ecf20Sopenharmony_ci		.key_str = "F9",
3598c2ecf20Sopenharmony_ci		.func = "Exit",
3608c2ecf20Sopenharmony_ci		.key = F_EXIT,
3618c2ecf20Sopenharmony_ci		.handler = handle_f9,
3628c2ecf20Sopenharmony_ci	},
3638c2ecf20Sopenharmony_ci};
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_cistatic void print_function_line(void)
3668c2ecf20Sopenharmony_ci{
3678c2ecf20Sopenharmony_ci	int i;
3688c2ecf20Sopenharmony_ci	int offset = 1;
3698c2ecf20Sopenharmony_ci	const int skip = 1;
3708c2ecf20Sopenharmony_ci	int lines = getmaxy(stdscr);
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	for (i = 0; i < function_keys_num; i++) {
3738c2ecf20Sopenharmony_ci		(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
3748c2ecf20Sopenharmony_ci		mvwprintw(main_window, lines-3, offset,
3758c2ecf20Sopenharmony_ci				"%s",
3768c2ecf20Sopenharmony_ci				function_keys[i].key_str);
3778c2ecf20Sopenharmony_ci		(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
3788c2ecf20Sopenharmony_ci		offset += strlen(function_keys[i].key_str);
3798c2ecf20Sopenharmony_ci		mvwprintw(main_window, lines-3,
3808c2ecf20Sopenharmony_ci				offset, "%s",
3818c2ecf20Sopenharmony_ci				function_keys[i].func);
3828c2ecf20Sopenharmony_ci		offset += strlen(function_keys[i].func) + skip;
3838c2ecf20Sopenharmony_ci	}
3848c2ecf20Sopenharmony_ci	(void) wattrset(main_window, attributes[NORMAL]);
3858c2ecf20Sopenharmony_ci}
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci/* help */
3888c2ecf20Sopenharmony_cistatic void handle_f1(int *key, struct menu *current_item)
3898c2ecf20Sopenharmony_ci{
3908c2ecf20Sopenharmony_ci	show_scroll_win(main_window,
3918c2ecf20Sopenharmony_ci			"Global help", nconf_global_help);
3928c2ecf20Sopenharmony_ci	return;
3938c2ecf20Sopenharmony_ci}
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci/* symbole help */
3968c2ecf20Sopenharmony_cistatic void handle_f2(int *key, struct menu *current_item)
3978c2ecf20Sopenharmony_ci{
3988c2ecf20Sopenharmony_ci	show_help(current_item);
3998c2ecf20Sopenharmony_ci	return;
4008c2ecf20Sopenharmony_ci}
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci/* instructions */
4038c2ecf20Sopenharmony_cistatic void handle_f3(int *key, struct menu *current_item)
4048c2ecf20Sopenharmony_ci{
4058c2ecf20Sopenharmony_ci	show_scroll_win(main_window,
4068c2ecf20Sopenharmony_ci			"Short help",
4078c2ecf20Sopenharmony_ci			current_instructions);
4088c2ecf20Sopenharmony_ci	return;
4098c2ecf20Sopenharmony_ci}
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci/* config */
4128c2ecf20Sopenharmony_cistatic void handle_f4(int *key, struct menu *current_item)
4138c2ecf20Sopenharmony_ci{
4148c2ecf20Sopenharmony_ci	int res = btn_dialog(main_window,
4158c2ecf20Sopenharmony_ci			"Show all symbols?",
4168c2ecf20Sopenharmony_ci			2,
4178c2ecf20Sopenharmony_ci			"   <Show All>   ",
4188c2ecf20Sopenharmony_ci			"<Don't show all>");
4198c2ecf20Sopenharmony_ci	if (res == 0)
4208c2ecf20Sopenharmony_ci		show_all_items = 1;
4218c2ecf20Sopenharmony_ci	else if (res == 1)
4228c2ecf20Sopenharmony_ci		show_all_items = 0;
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	return;
4258c2ecf20Sopenharmony_ci}
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci/* back */
4288c2ecf20Sopenharmony_cistatic void handle_f5(int *key, struct menu *current_item)
4298c2ecf20Sopenharmony_ci{
4308c2ecf20Sopenharmony_ci	*key = KEY_LEFT;
4318c2ecf20Sopenharmony_ci	return;
4328c2ecf20Sopenharmony_ci}
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci/* save */
4358c2ecf20Sopenharmony_cistatic void handle_f6(int *key, struct menu *current_item)
4368c2ecf20Sopenharmony_ci{
4378c2ecf20Sopenharmony_ci	conf_save();
4388c2ecf20Sopenharmony_ci	return;
4398c2ecf20Sopenharmony_ci}
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci/* load */
4428c2ecf20Sopenharmony_cistatic void handle_f7(int *key, struct menu *current_item)
4438c2ecf20Sopenharmony_ci{
4448c2ecf20Sopenharmony_ci	conf_load();
4458c2ecf20Sopenharmony_ci	return;
4468c2ecf20Sopenharmony_ci}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci/* search */
4498c2ecf20Sopenharmony_cistatic void handle_f8(int *key, struct menu *current_item)
4508c2ecf20Sopenharmony_ci{
4518c2ecf20Sopenharmony_ci	search_conf();
4528c2ecf20Sopenharmony_ci	return;
4538c2ecf20Sopenharmony_ci}
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci/* exit */
4568c2ecf20Sopenharmony_cistatic void handle_f9(int *key, struct menu *current_item)
4578c2ecf20Sopenharmony_ci{
4588c2ecf20Sopenharmony_ci	do_exit();
4598c2ecf20Sopenharmony_ci	return;
4608c2ecf20Sopenharmony_ci}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci/* return != 0 to indicate the key was handles */
4638c2ecf20Sopenharmony_cistatic int process_special_keys(int *key, struct menu *menu)
4648c2ecf20Sopenharmony_ci{
4658c2ecf20Sopenharmony_ci	int i;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	if (*key == KEY_RESIZE) {
4688c2ecf20Sopenharmony_ci		setup_windows();
4698c2ecf20Sopenharmony_ci		return 1;
4708c2ecf20Sopenharmony_ci	}
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	for (i = 0; i < function_keys_num; i++) {
4738c2ecf20Sopenharmony_ci		if (*key == KEY_F(function_keys[i].key) ||
4748c2ecf20Sopenharmony_ci		    *key == '0' + function_keys[i].key){
4758c2ecf20Sopenharmony_ci			function_keys[i].handler(key, menu);
4768c2ecf20Sopenharmony_ci			return 1;
4778c2ecf20Sopenharmony_ci		}
4788c2ecf20Sopenharmony_ci	}
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci	return 0;
4818c2ecf20Sopenharmony_ci}
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_cistatic void clean_items(void)
4848c2ecf20Sopenharmony_ci{
4858c2ecf20Sopenharmony_ci	int i;
4868c2ecf20Sopenharmony_ci	for (i = 0; curses_menu_items[i]; i++)
4878c2ecf20Sopenharmony_ci		free_item(curses_menu_items[i]);
4888c2ecf20Sopenharmony_ci	bzero(curses_menu_items, sizeof(curses_menu_items));
4898c2ecf20Sopenharmony_ci	bzero(k_menu_items, sizeof(k_menu_items));
4908c2ecf20Sopenharmony_ci	items_num = 0;
4918c2ecf20Sopenharmony_ci}
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_citypedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
4948c2ecf20Sopenharmony_ci	FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci/* return the index of the matched item, or -1 if no such item exists */
4978c2ecf20Sopenharmony_cistatic int get_mext_match(const char *match_str, match_f flag)
4988c2ecf20Sopenharmony_ci{
4998c2ecf20Sopenharmony_ci	int match_start = item_index(current_item(curses_menu));
5008c2ecf20Sopenharmony_ci	int index;
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	if (flag == FIND_NEXT_MATCH_DOWN)
5038c2ecf20Sopenharmony_ci		++match_start;
5048c2ecf20Sopenharmony_ci	else if (flag == FIND_NEXT_MATCH_UP)
5058c2ecf20Sopenharmony_ci		--match_start;
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	match_start = (match_start + items_num) % items_num;
5088c2ecf20Sopenharmony_ci	index = match_start;
5098c2ecf20Sopenharmony_ci	while (true) {
5108c2ecf20Sopenharmony_ci		char *str = k_menu_items[index].str;
5118c2ecf20Sopenharmony_ci		if (strcasestr(str, match_str) != NULL)
5128c2ecf20Sopenharmony_ci			return index;
5138c2ecf20Sopenharmony_ci		if (flag == FIND_NEXT_MATCH_UP ||
5148c2ecf20Sopenharmony_ci		    flag == MATCH_TINKER_PATTERN_UP)
5158c2ecf20Sopenharmony_ci			--index;
5168c2ecf20Sopenharmony_ci		else
5178c2ecf20Sopenharmony_ci			++index;
5188c2ecf20Sopenharmony_ci		index = (index + items_num) % items_num;
5198c2ecf20Sopenharmony_ci		if (index == match_start)
5208c2ecf20Sopenharmony_ci			return -1;
5218c2ecf20Sopenharmony_ci	}
5228c2ecf20Sopenharmony_ci}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci/* Make a new item. */
5258c2ecf20Sopenharmony_cistatic void item_make(struct menu *menu, char tag, const char *fmt, ...)
5268c2ecf20Sopenharmony_ci{
5278c2ecf20Sopenharmony_ci	va_list ap;
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	if (items_num > MAX_MENU_ITEMS-1)
5308c2ecf20Sopenharmony_ci		return;
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci	bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
5338c2ecf20Sopenharmony_ci	k_menu_items[items_num].tag = tag;
5348c2ecf20Sopenharmony_ci	k_menu_items[items_num].usrptr = menu;
5358c2ecf20Sopenharmony_ci	if (menu != NULL)
5368c2ecf20Sopenharmony_ci		k_menu_items[items_num].is_visible =
5378c2ecf20Sopenharmony_ci			menu_is_visible(menu);
5388c2ecf20Sopenharmony_ci	else
5398c2ecf20Sopenharmony_ci		k_menu_items[items_num].is_visible = 1;
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci	va_start(ap, fmt);
5428c2ecf20Sopenharmony_ci	vsnprintf(k_menu_items[items_num].str,
5438c2ecf20Sopenharmony_ci		  sizeof(k_menu_items[items_num].str),
5448c2ecf20Sopenharmony_ci		  fmt, ap);
5458c2ecf20Sopenharmony_ci	va_end(ap);
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	if (!k_menu_items[items_num].is_visible)
5488c2ecf20Sopenharmony_ci		memcpy(k_menu_items[items_num].str, "XXX", 3);
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci	curses_menu_items[items_num] = new_item(
5518c2ecf20Sopenharmony_ci			k_menu_items[items_num].str,
5528c2ecf20Sopenharmony_ci			k_menu_items[items_num].str);
5538c2ecf20Sopenharmony_ci	set_item_userptr(curses_menu_items[items_num],
5548c2ecf20Sopenharmony_ci			&k_menu_items[items_num]);
5558c2ecf20Sopenharmony_ci	/*
5568c2ecf20Sopenharmony_ci	if (!k_menu_items[items_num].is_visible)
5578c2ecf20Sopenharmony_ci		item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
5588c2ecf20Sopenharmony_ci	*/
5598c2ecf20Sopenharmony_ci
5608c2ecf20Sopenharmony_ci	items_num++;
5618c2ecf20Sopenharmony_ci	curses_menu_items[items_num] = NULL;
5628c2ecf20Sopenharmony_ci}
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci/* very hackish. adds a string to the last item added */
5658c2ecf20Sopenharmony_cistatic void item_add_str(const char *fmt, ...)
5668c2ecf20Sopenharmony_ci{
5678c2ecf20Sopenharmony_ci	va_list ap;
5688c2ecf20Sopenharmony_ci	int index = items_num-1;
5698c2ecf20Sopenharmony_ci	char new_str[256];
5708c2ecf20Sopenharmony_ci	char tmp_str[256];
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci	if (index < 0)
5738c2ecf20Sopenharmony_ci		return;
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_ci	va_start(ap, fmt);
5768c2ecf20Sopenharmony_ci	vsnprintf(new_str, sizeof(new_str), fmt, ap);
5778c2ecf20Sopenharmony_ci	va_end(ap);
5788c2ecf20Sopenharmony_ci	snprintf(tmp_str, sizeof(tmp_str), "%s%s",
5798c2ecf20Sopenharmony_ci			k_menu_items[index].str, new_str);
5808c2ecf20Sopenharmony_ci	strncpy(k_menu_items[index].str,
5818c2ecf20Sopenharmony_ci		tmp_str,
5828c2ecf20Sopenharmony_ci		sizeof(k_menu_items[index].str));
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci	free_item(curses_menu_items[index]);
5858c2ecf20Sopenharmony_ci	curses_menu_items[index] = new_item(
5868c2ecf20Sopenharmony_ci			k_menu_items[index].str,
5878c2ecf20Sopenharmony_ci			k_menu_items[index].str);
5888c2ecf20Sopenharmony_ci	set_item_userptr(curses_menu_items[index],
5898c2ecf20Sopenharmony_ci			&k_menu_items[index]);
5908c2ecf20Sopenharmony_ci}
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_ci/* get the tag of the currently selected item */
5938c2ecf20Sopenharmony_cistatic char item_tag(void)
5948c2ecf20Sopenharmony_ci{
5958c2ecf20Sopenharmony_ci	ITEM *cur;
5968c2ecf20Sopenharmony_ci	struct mitem *mcur;
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci	cur = current_item(curses_menu);
5998c2ecf20Sopenharmony_ci	if (cur == NULL)
6008c2ecf20Sopenharmony_ci		return 0;
6018c2ecf20Sopenharmony_ci	mcur = (struct mitem *) item_userptr(cur);
6028c2ecf20Sopenharmony_ci	return mcur->tag;
6038c2ecf20Sopenharmony_ci}
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_cistatic int curses_item_index(void)
6068c2ecf20Sopenharmony_ci{
6078c2ecf20Sopenharmony_ci	return  item_index(current_item(curses_menu));
6088c2ecf20Sopenharmony_ci}
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_cistatic void *item_data(void)
6118c2ecf20Sopenharmony_ci{
6128c2ecf20Sopenharmony_ci	ITEM *cur;
6138c2ecf20Sopenharmony_ci	struct mitem *mcur;
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_ci	cur = current_item(curses_menu);
6168c2ecf20Sopenharmony_ci	if (!cur)
6178c2ecf20Sopenharmony_ci		return NULL;
6188c2ecf20Sopenharmony_ci	mcur = (struct mitem *) item_userptr(cur);
6198c2ecf20Sopenharmony_ci	return mcur->usrptr;
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_ci}
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_cistatic int item_is_tag(char tag)
6248c2ecf20Sopenharmony_ci{
6258c2ecf20Sopenharmony_ci	return item_tag() == tag;
6268c2ecf20Sopenharmony_ci}
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_cistatic char filename[PATH_MAX+1];
6298c2ecf20Sopenharmony_cistatic char menu_backtitle[PATH_MAX+128];
6308c2ecf20Sopenharmony_cistatic const char *set_config_filename(const char *config_filename)
6318c2ecf20Sopenharmony_ci{
6328c2ecf20Sopenharmony_ci	int size;
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
6358c2ecf20Sopenharmony_ci			"%s - %s", config_filename, rootmenu.prompt->text);
6368c2ecf20Sopenharmony_ci	if (size >= sizeof(menu_backtitle))
6378c2ecf20Sopenharmony_ci		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci	size = snprintf(filename, sizeof(filename), "%s", config_filename);
6408c2ecf20Sopenharmony_ci	if (size >= sizeof(filename))
6418c2ecf20Sopenharmony_ci		filename[sizeof(filename)-1] = '\0';
6428c2ecf20Sopenharmony_ci	return menu_backtitle;
6438c2ecf20Sopenharmony_ci}
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci/* return = 0 means we are successful.
6468c2ecf20Sopenharmony_ci * -1 means go on doing what you were doing
6478c2ecf20Sopenharmony_ci */
6488c2ecf20Sopenharmony_cistatic int do_exit(void)
6498c2ecf20Sopenharmony_ci{
6508c2ecf20Sopenharmony_ci	int res;
6518c2ecf20Sopenharmony_ci	if (!conf_get_changed()) {
6528c2ecf20Sopenharmony_ci		global_exit = 1;
6538c2ecf20Sopenharmony_ci		return 0;
6548c2ecf20Sopenharmony_ci	}
6558c2ecf20Sopenharmony_ci	res = btn_dialog(main_window,
6568c2ecf20Sopenharmony_ci			"Do you wish to save your new configuration?\n"
6578c2ecf20Sopenharmony_ci				"<ESC> to cancel and resume nconfig.",
6588c2ecf20Sopenharmony_ci			2,
6598c2ecf20Sopenharmony_ci			"   <save>   ",
6608c2ecf20Sopenharmony_ci			"<don't save>");
6618c2ecf20Sopenharmony_ci	if (res == KEY_EXIT) {
6628c2ecf20Sopenharmony_ci		global_exit = 0;
6638c2ecf20Sopenharmony_ci		return -1;
6648c2ecf20Sopenharmony_ci	}
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	/* if we got here, the user really wants to exit */
6678c2ecf20Sopenharmony_ci	switch (res) {
6688c2ecf20Sopenharmony_ci	case 0:
6698c2ecf20Sopenharmony_ci		res = conf_write(filename);
6708c2ecf20Sopenharmony_ci		if (res)
6718c2ecf20Sopenharmony_ci			btn_dialog(
6728c2ecf20Sopenharmony_ci				main_window,
6738c2ecf20Sopenharmony_ci				"Error during writing of configuration.\n"
6748c2ecf20Sopenharmony_ci				  "Your configuration changes were NOT saved.",
6758c2ecf20Sopenharmony_ci				  1,
6768c2ecf20Sopenharmony_ci				  "<OK>");
6778c2ecf20Sopenharmony_ci		conf_write_autoconf(0);
6788c2ecf20Sopenharmony_ci		break;
6798c2ecf20Sopenharmony_ci	default:
6808c2ecf20Sopenharmony_ci		btn_dialog(
6818c2ecf20Sopenharmony_ci			main_window,
6828c2ecf20Sopenharmony_ci			"Your configuration changes were NOT saved.",
6838c2ecf20Sopenharmony_ci			1,
6848c2ecf20Sopenharmony_ci			"<OK>");
6858c2ecf20Sopenharmony_ci		break;
6868c2ecf20Sopenharmony_ci	}
6878c2ecf20Sopenharmony_ci	global_exit = 1;
6888c2ecf20Sopenharmony_ci	return 0;
6898c2ecf20Sopenharmony_ci}
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_cistatic void search_conf(void)
6938c2ecf20Sopenharmony_ci{
6948c2ecf20Sopenharmony_ci	struct symbol **sym_arr;
6958c2ecf20Sopenharmony_ci	struct gstr res;
6968c2ecf20Sopenharmony_ci	struct gstr title;
6978c2ecf20Sopenharmony_ci	char *dialog_input;
6988c2ecf20Sopenharmony_ci	int dres;
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_ci	title = str_new();
7018c2ecf20Sopenharmony_ci	str_printf( &title, "Enter (sub)string or regexp to search for "
7028c2ecf20Sopenharmony_ci			      "(with or without \"%s\")", CONFIG_);
7038c2ecf20Sopenharmony_ci
7048c2ecf20Sopenharmony_ciagain:
7058c2ecf20Sopenharmony_ci	dres = dialog_inputbox(main_window,
7068c2ecf20Sopenharmony_ci			"Search Configuration Parameter",
7078c2ecf20Sopenharmony_ci			str_get(&title),
7088c2ecf20Sopenharmony_ci			"", &dialog_input_result, &dialog_input_result_len);
7098c2ecf20Sopenharmony_ci	switch (dres) {
7108c2ecf20Sopenharmony_ci	case 0:
7118c2ecf20Sopenharmony_ci		break;
7128c2ecf20Sopenharmony_ci	case 1:
7138c2ecf20Sopenharmony_ci		show_scroll_win(main_window,
7148c2ecf20Sopenharmony_ci				"Search Configuration", search_help);
7158c2ecf20Sopenharmony_ci		goto again;
7168c2ecf20Sopenharmony_ci	default:
7178c2ecf20Sopenharmony_ci		str_free(&title);
7188c2ecf20Sopenharmony_ci		return;
7198c2ecf20Sopenharmony_ci	}
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_ci	/* strip the prefix if necessary */
7228c2ecf20Sopenharmony_ci	dialog_input = dialog_input_result;
7238c2ecf20Sopenharmony_ci	if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
7248c2ecf20Sopenharmony_ci		dialog_input += strlen(CONFIG_);
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci	sym_arr = sym_re_search(dialog_input);
7278c2ecf20Sopenharmony_ci	res = get_relations_str(sym_arr, NULL);
7288c2ecf20Sopenharmony_ci	free(sym_arr);
7298c2ecf20Sopenharmony_ci	show_scroll_win(main_window,
7308c2ecf20Sopenharmony_ci			"Search Results", str_get(&res));
7318c2ecf20Sopenharmony_ci	str_free(&res);
7328c2ecf20Sopenharmony_ci	str_free(&title);
7338c2ecf20Sopenharmony_ci}
7348c2ecf20Sopenharmony_ci
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_cistatic void build_conf(struct menu *menu)
7378c2ecf20Sopenharmony_ci{
7388c2ecf20Sopenharmony_ci	struct symbol *sym;
7398c2ecf20Sopenharmony_ci	struct property *prop;
7408c2ecf20Sopenharmony_ci	struct menu *child;
7418c2ecf20Sopenharmony_ci	int type, tmp, doint = 2;
7428c2ecf20Sopenharmony_ci	tristate val;
7438c2ecf20Sopenharmony_ci	char ch;
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci	if (!menu || (!show_all_items && !menu_is_visible(menu)))
7468c2ecf20Sopenharmony_ci		return;
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_ci	sym = menu->sym;
7498c2ecf20Sopenharmony_ci	prop = menu->prompt;
7508c2ecf20Sopenharmony_ci	if (!sym) {
7518c2ecf20Sopenharmony_ci		if (prop && menu != current_menu) {
7528c2ecf20Sopenharmony_ci			const char *prompt = menu_get_prompt(menu);
7538c2ecf20Sopenharmony_ci			enum prop_type ptype;
7548c2ecf20Sopenharmony_ci			ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
7558c2ecf20Sopenharmony_ci			switch (ptype) {
7568c2ecf20Sopenharmony_ci			case P_MENU:
7578c2ecf20Sopenharmony_ci				child_count++;
7588c2ecf20Sopenharmony_ci				if (single_menu_mode) {
7598c2ecf20Sopenharmony_ci					item_make(menu, 'm',
7608c2ecf20Sopenharmony_ci						"%s%*c%s",
7618c2ecf20Sopenharmony_ci						menu->data ? "-->" : "++>",
7628c2ecf20Sopenharmony_ci						indent + 1, ' ', prompt);
7638c2ecf20Sopenharmony_ci				} else
7648c2ecf20Sopenharmony_ci					item_make(menu, 'm',
7658c2ecf20Sopenharmony_ci						  "   %*c%s  %s",
7668c2ecf20Sopenharmony_ci						  indent + 1, ' ', prompt,
7678c2ecf20Sopenharmony_ci						  menu_is_empty(menu) ? "----" : "--->");
7688c2ecf20Sopenharmony_ci
7698c2ecf20Sopenharmony_ci				if (single_menu_mode && menu->data)
7708c2ecf20Sopenharmony_ci					goto conf_childs;
7718c2ecf20Sopenharmony_ci				return;
7728c2ecf20Sopenharmony_ci			case P_COMMENT:
7738c2ecf20Sopenharmony_ci				if (prompt) {
7748c2ecf20Sopenharmony_ci					child_count++;
7758c2ecf20Sopenharmony_ci					item_make(menu, ':',
7768c2ecf20Sopenharmony_ci						"   %*c*** %s ***",
7778c2ecf20Sopenharmony_ci						indent + 1, ' ',
7788c2ecf20Sopenharmony_ci						prompt);
7798c2ecf20Sopenharmony_ci				}
7808c2ecf20Sopenharmony_ci				break;
7818c2ecf20Sopenharmony_ci			default:
7828c2ecf20Sopenharmony_ci				if (prompt) {
7838c2ecf20Sopenharmony_ci					child_count++;
7848c2ecf20Sopenharmony_ci					item_make(menu, ':', "---%*c%s",
7858c2ecf20Sopenharmony_ci						indent + 1, ' ',
7868c2ecf20Sopenharmony_ci						prompt);
7878c2ecf20Sopenharmony_ci				}
7888c2ecf20Sopenharmony_ci			}
7898c2ecf20Sopenharmony_ci		} else
7908c2ecf20Sopenharmony_ci			doint = 0;
7918c2ecf20Sopenharmony_ci		goto conf_childs;
7928c2ecf20Sopenharmony_ci	}
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_ci	type = sym_get_type(sym);
7958c2ecf20Sopenharmony_ci	if (sym_is_choice(sym)) {
7968c2ecf20Sopenharmony_ci		struct symbol *def_sym = sym_get_choice_value(sym);
7978c2ecf20Sopenharmony_ci		struct menu *def_menu = NULL;
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_ci		child_count++;
8008c2ecf20Sopenharmony_ci		for (child = menu->list; child; child = child->next) {
8018c2ecf20Sopenharmony_ci			if (menu_is_visible(child) && child->sym == def_sym)
8028c2ecf20Sopenharmony_ci				def_menu = child;
8038c2ecf20Sopenharmony_ci		}
8048c2ecf20Sopenharmony_ci
8058c2ecf20Sopenharmony_ci		val = sym_get_tristate_value(sym);
8068c2ecf20Sopenharmony_ci		if (sym_is_changeable(sym)) {
8078c2ecf20Sopenharmony_ci			switch (type) {
8088c2ecf20Sopenharmony_ci			case S_BOOLEAN:
8098c2ecf20Sopenharmony_ci				item_make(menu, 't', "[%c]",
8108c2ecf20Sopenharmony_ci						val == no ? ' ' : '*');
8118c2ecf20Sopenharmony_ci				break;
8128c2ecf20Sopenharmony_ci			case S_TRISTATE:
8138c2ecf20Sopenharmony_ci				switch (val) {
8148c2ecf20Sopenharmony_ci				case yes:
8158c2ecf20Sopenharmony_ci					ch = '*';
8168c2ecf20Sopenharmony_ci					break;
8178c2ecf20Sopenharmony_ci				case mod:
8188c2ecf20Sopenharmony_ci					ch = 'M';
8198c2ecf20Sopenharmony_ci					break;
8208c2ecf20Sopenharmony_ci				default:
8218c2ecf20Sopenharmony_ci					ch = ' ';
8228c2ecf20Sopenharmony_ci					break;
8238c2ecf20Sopenharmony_ci				}
8248c2ecf20Sopenharmony_ci				item_make(menu, 't', "<%c>", ch);
8258c2ecf20Sopenharmony_ci				break;
8268c2ecf20Sopenharmony_ci			}
8278c2ecf20Sopenharmony_ci		} else {
8288c2ecf20Sopenharmony_ci			item_make(menu, def_menu ? 't' : ':', "   ");
8298c2ecf20Sopenharmony_ci		}
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_ci		item_add_str("%*c%s", indent + 1,
8328c2ecf20Sopenharmony_ci				' ', menu_get_prompt(menu));
8338c2ecf20Sopenharmony_ci		if (val == yes) {
8348c2ecf20Sopenharmony_ci			if (def_menu) {
8358c2ecf20Sopenharmony_ci				item_add_str(" (%s)",
8368c2ecf20Sopenharmony_ci					menu_get_prompt(def_menu));
8378c2ecf20Sopenharmony_ci				item_add_str("  --->");
8388c2ecf20Sopenharmony_ci				if (def_menu->list) {
8398c2ecf20Sopenharmony_ci					indent += 2;
8408c2ecf20Sopenharmony_ci					build_conf(def_menu);
8418c2ecf20Sopenharmony_ci					indent -= 2;
8428c2ecf20Sopenharmony_ci				}
8438c2ecf20Sopenharmony_ci			}
8448c2ecf20Sopenharmony_ci			return;
8458c2ecf20Sopenharmony_ci		}
8468c2ecf20Sopenharmony_ci	} else {
8478c2ecf20Sopenharmony_ci		if (menu == current_menu) {
8488c2ecf20Sopenharmony_ci			item_make(menu, ':',
8498c2ecf20Sopenharmony_ci				"---%*c%s", indent + 1,
8508c2ecf20Sopenharmony_ci				' ', menu_get_prompt(menu));
8518c2ecf20Sopenharmony_ci			goto conf_childs;
8528c2ecf20Sopenharmony_ci		}
8538c2ecf20Sopenharmony_ci		child_count++;
8548c2ecf20Sopenharmony_ci		val = sym_get_tristate_value(sym);
8558c2ecf20Sopenharmony_ci		if (sym_is_choice_value(sym) && val == yes) {
8568c2ecf20Sopenharmony_ci			item_make(menu, ':', "   ");
8578c2ecf20Sopenharmony_ci		} else {
8588c2ecf20Sopenharmony_ci			switch (type) {
8598c2ecf20Sopenharmony_ci			case S_BOOLEAN:
8608c2ecf20Sopenharmony_ci				if (sym_is_changeable(sym))
8618c2ecf20Sopenharmony_ci					item_make(menu, 't', "[%c]",
8628c2ecf20Sopenharmony_ci						val == no ? ' ' : '*');
8638c2ecf20Sopenharmony_ci				else
8648c2ecf20Sopenharmony_ci					item_make(menu, 't', "-%c-",
8658c2ecf20Sopenharmony_ci						val == no ? ' ' : '*');
8668c2ecf20Sopenharmony_ci				break;
8678c2ecf20Sopenharmony_ci			case S_TRISTATE:
8688c2ecf20Sopenharmony_ci				switch (val) {
8698c2ecf20Sopenharmony_ci				case yes:
8708c2ecf20Sopenharmony_ci					ch = '*';
8718c2ecf20Sopenharmony_ci					break;
8728c2ecf20Sopenharmony_ci				case mod:
8738c2ecf20Sopenharmony_ci					ch = 'M';
8748c2ecf20Sopenharmony_ci					break;
8758c2ecf20Sopenharmony_ci				default:
8768c2ecf20Sopenharmony_ci					ch = ' ';
8778c2ecf20Sopenharmony_ci					break;
8788c2ecf20Sopenharmony_ci				}
8798c2ecf20Sopenharmony_ci				if (sym_is_changeable(sym)) {
8808c2ecf20Sopenharmony_ci					if (sym->rev_dep.tri == mod)
8818c2ecf20Sopenharmony_ci						item_make(menu,
8828c2ecf20Sopenharmony_ci							't', "{%c}", ch);
8838c2ecf20Sopenharmony_ci					else
8848c2ecf20Sopenharmony_ci						item_make(menu,
8858c2ecf20Sopenharmony_ci							't', "<%c>", ch);
8868c2ecf20Sopenharmony_ci				} else
8878c2ecf20Sopenharmony_ci					item_make(menu, 't', "-%c-", ch);
8888c2ecf20Sopenharmony_ci				break;
8898c2ecf20Sopenharmony_ci			default:
8908c2ecf20Sopenharmony_ci				tmp = 2 + strlen(sym_get_string_value(sym));
8918c2ecf20Sopenharmony_ci				item_make(menu, 's', "    (%s)",
8928c2ecf20Sopenharmony_ci						sym_get_string_value(sym));
8938c2ecf20Sopenharmony_ci				tmp = indent - tmp + 4;
8948c2ecf20Sopenharmony_ci				if (tmp < 0)
8958c2ecf20Sopenharmony_ci					tmp = 0;
8968c2ecf20Sopenharmony_ci				item_add_str("%*c%s%s", tmp, ' ',
8978c2ecf20Sopenharmony_ci						menu_get_prompt(menu),
8988c2ecf20Sopenharmony_ci						(sym_has_value(sym) ||
8998c2ecf20Sopenharmony_ci						 !sym_is_changeable(sym)) ? "" :
9008c2ecf20Sopenharmony_ci						" (NEW)");
9018c2ecf20Sopenharmony_ci				goto conf_childs;
9028c2ecf20Sopenharmony_ci			}
9038c2ecf20Sopenharmony_ci		}
9048c2ecf20Sopenharmony_ci		item_add_str("%*c%s%s", indent + 1, ' ',
9058c2ecf20Sopenharmony_ci				menu_get_prompt(menu),
9068c2ecf20Sopenharmony_ci				(sym_has_value(sym) || !sym_is_changeable(sym)) ?
9078c2ecf20Sopenharmony_ci				"" : " (NEW)");
9088c2ecf20Sopenharmony_ci		if (menu->prompt && menu->prompt->type == P_MENU) {
9098c2ecf20Sopenharmony_ci			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");
9108c2ecf20Sopenharmony_ci			return;
9118c2ecf20Sopenharmony_ci		}
9128c2ecf20Sopenharmony_ci	}
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ciconf_childs:
9158c2ecf20Sopenharmony_ci	indent += doint;
9168c2ecf20Sopenharmony_ci	for (child = menu->list; child; child = child->next)
9178c2ecf20Sopenharmony_ci		build_conf(child);
9188c2ecf20Sopenharmony_ci	indent -= doint;
9198c2ecf20Sopenharmony_ci}
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_cistatic void reset_menu(void)
9228c2ecf20Sopenharmony_ci{
9238c2ecf20Sopenharmony_ci	unpost_menu(curses_menu);
9248c2ecf20Sopenharmony_ci	clean_items();
9258c2ecf20Sopenharmony_ci}
9268c2ecf20Sopenharmony_ci
9278c2ecf20Sopenharmony_ci/* adjust the menu to show this item.
9288c2ecf20Sopenharmony_ci * prefer not to scroll the menu if possible*/
9298c2ecf20Sopenharmony_cistatic void center_item(int selected_index, int *last_top_row)
9308c2ecf20Sopenharmony_ci{
9318c2ecf20Sopenharmony_ci	int toprow;
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_ci	set_top_row(curses_menu, *last_top_row);
9348c2ecf20Sopenharmony_ci	toprow = top_row(curses_menu);
9358c2ecf20Sopenharmony_ci	if (selected_index < toprow ||
9368c2ecf20Sopenharmony_ci	    selected_index >= toprow+mwin_max_lines) {
9378c2ecf20Sopenharmony_ci		toprow = max(selected_index-mwin_max_lines/2, 0);
9388c2ecf20Sopenharmony_ci		if (toprow >= item_count(curses_menu)-mwin_max_lines)
9398c2ecf20Sopenharmony_ci			toprow = item_count(curses_menu)-mwin_max_lines;
9408c2ecf20Sopenharmony_ci		set_top_row(curses_menu, toprow);
9418c2ecf20Sopenharmony_ci	}
9428c2ecf20Sopenharmony_ci	set_current_item(curses_menu,
9438c2ecf20Sopenharmony_ci			curses_menu_items[selected_index]);
9448c2ecf20Sopenharmony_ci	*last_top_row = toprow;
9458c2ecf20Sopenharmony_ci	post_menu(curses_menu);
9468c2ecf20Sopenharmony_ci	refresh_all_windows(main_window);
9478c2ecf20Sopenharmony_ci}
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_ci/* this function assumes reset_menu has been called before */
9508c2ecf20Sopenharmony_cistatic void show_menu(const char *prompt, const char *instructions,
9518c2ecf20Sopenharmony_ci		int selected_index, int *last_top_row)
9528c2ecf20Sopenharmony_ci{
9538c2ecf20Sopenharmony_ci	int maxx, maxy;
9548c2ecf20Sopenharmony_ci	WINDOW *menu_window;
9558c2ecf20Sopenharmony_ci
9568c2ecf20Sopenharmony_ci	current_instructions = instructions;
9578c2ecf20Sopenharmony_ci
9588c2ecf20Sopenharmony_ci	clear();
9598c2ecf20Sopenharmony_ci	(void) wattrset(main_window, attributes[NORMAL]);
9608c2ecf20Sopenharmony_ci	print_in_middle(stdscr, 1, 0, getmaxx(stdscr),
9618c2ecf20Sopenharmony_ci			menu_backtitle,
9628c2ecf20Sopenharmony_ci			attributes[MAIN_HEADING]);
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
9658c2ecf20Sopenharmony_ci	box(main_window, 0, 0);
9668c2ecf20Sopenharmony_ci	(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
9678c2ecf20Sopenharmony_ci	mvwprintw(main_window, 0, 3, " %s ", prompt);
9688c2ecf20Sopenharmony_ci	(void) wattrset(main_window, attributes[NORMAL]);
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_ci	set_menu_items(curses_menu, curses_menu_items);
9718c2ecf20Sopenharmony_ci
9728c2ecf20Sopenharmony_ci	/* position the menu at the middle of the screen */
9738c2ecf20Sopenharmony_ci	scale_menu(curses_menu, &maxy, &maxx);
9748c2ecf20Sopenharmony_ci	maxx = min(maxx, mwin_max_cols-2);
9758c2ecf20Sopenharmony_ci	maxy = mwin_max_lines;
9768c2ecf20Sopenharmony_ci	menu_window = derwin(main_window,
9778c2ecf20Sopenharmony_ci			maxy,
9788c2ecf20Sopenharmony_ci			maxx,
9798c2ecf20Sopenharmony_ci			2,
9808c2ecf20Sopenharmony_ci			(mwin_max_cols-maxx)/2);
9818c2ecf20Sopenharmony_ci	keypad(menu_window, TRUE);
9828c2ecf20Sopenharmony_ci	set_menu_win(curses_menu, menu_window);
9838c2ecf20Sopenharmony_ci	set_menu_sub(curses_menu, menu_window);
9848c2ecf20Sopenharmony_ci
9858c2ecf20Sopenharmony_ci	/* must reassert this after changing items, otherwise returns to a
9868c2ecf20Sopenharmony_ci	 * default of 16
9878c2ecf20Sopenharmony_ci	 */
9888c2ecf20Sopenharmony_ci	set_menu_format(curses_menu, maxy, 1);
9898c2ecf20Sopenharmony_ci	center_item(selected_index, last_top_row);
9908c2ecf20Sopenharmony_ci	set_menu_format(curses_menu, maxy, 1);
9918c2ecf20Sopenharmony_ci
9928c2ecf20Sopenharmony_ci	print_function_line();
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_ci	/* Post the menu */
9958c2ecf20Sopenharmony_ci	post_menu(curses_menu);
9968c2ecf20Sopenharmony_ci	refresh_all_windows(main_window);
9978c2ecf20Sopenharmony_ci}
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_cistatic void adj_match_dir(match_f *match_direction)
10008c2ecf20Sopenharmony_ci{
10018c2ecf20Sopenharmony_ci	if (*match_direction == FIND_NEXT_MATCH_DOWN)
10028c2ecf20Sopenharmony_ci		*match_direction =
10038c2ecf20Sopenharmony_ci			MATCH_TINKER_PATTERN_DOWN;
10048c2ecf20Sopenharmony_ci	else if (*match_direction == FIND_NEXT_MATCH_UP)
10058c2ecf20Sopenharmony_ci		*match_direction =
10068c2ecf20Sopenharmony_ci			MATCH_TINKER_PATTERN_UP;
10078c2ecf20Sopenharmony_ci	/* else, do no change.. */
10088c2ecf20Sopenharmony_ci}
10098c2ecf20Sopenharmony_ci
10108c2ecf20Sopenharmony_cistruct match_state
10118c2ecf20Sopenharmony_ci{
10128c2ecf20Sopenharmony_ci	int in_search;
10138c2ecf20Sopenharmony_ci	match_f match_direction;
10148c2ecf20Sopenharmony_ci	char pattern[256];
10158c2ecf20Sopenharmony_ci};
10168c2ecf20Sopenharmony_ci
10178c2ecf20Sopenharmony_ci/* Return 0 means I have handled the key. In such a case, ans should hold the
10188c2ecf20Sopenharmony_ci * item to center, or -1 otherwise.
10198c2ecf20Sopenharmony_ci * Else return -1 .
10208c2ecf20Sopenharmony_ci */
10218c2ecf20Sopenharmony_cistatic int do_match(int key, struct match_state *state, int *ans)
10228c2ecf20Sopenharmony_ci{
10238c2ecf20Sopenharmony_ci	char c = (char) key;
10248c2ecf20Sopenharmony_ci	int terminate_search = 0;
10258c2ecf20Sopenharmony_ci	*ans = -1;
10268c2ecf20Sopenharmony_ci	if (key == '/' || (state->in_search && key == 27)) {
10278c2ecf20Sopenharmony_ci		move(0, 0);
10288c2ecf20Sopenharmony_ci		refresh();
10298c2ecf20Sopenharmony_ci		clrtoeol();
10308c2ecf20Sopenharmony_ci		state->in_search = 1-state->in_search;
10318c2ecf20Sopenharmony_ci		bzero(state->pattern, sizeof(state->pattern));
10328c2ecf20Sopenharmony_ci		state->match_direction = MATCH_TINKER_PATTERN_DOWN;
10338c2ecf20Sopenharmony_ci		return 0;
10348c2ecf20Sopenharmony_ci	} else if (!state->in_search)
10358c2ecf20Sopenharmony_ci		return 1;
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci	if (isalnum(c) || isgraph(c) || c == ' ') {
10388c2ecf20Sopenharmony_ci		state->pattern[strlen(state->pattern)] = c;
10398c2ecf20Sopenharmony_ci		state->pattern[strlen(state->pattern)] = '\0';
10408c2ecf20Sopenharmony_ci		adj_match_dir(&state->match_direction);
10418c2ecf20Sopenharmony_ci		*ans = get_mext_match(state->pattern,
10428c2ecf20Sopenharmony_ci				state->match_direction);
10438c2ecf20Sopenharmony_ci	} else if (key == KEY_DOWN) {
10448c2ecf20Sopenharmony_ci		state->match_direction = FIND_NEXT_MATCH_DOWN;
10458c2ecf20Sopenharmony_ci		*ans = get_mext_match(state->pattern,
10468c2ecf20Sopenharmony_ci				state->match_direction);
10478c2ecf20Sopenharmony_ci	} else if (key == KEY_UP) {
10488c2ecf20Sopenharmony_ci		state->match_direction = FIND_NEXT_MATCH_UP;
10498c2ecf20Sopenharmony_ci		*ans = get_mext_match(state->pattern,
10508c2ecf20Sopenharmony_ci				state->match_direction);
10518c2ecf20Sopenharmony_ci	} else if (key == KEY_BACKSPACE || key == 8 || key == 127) {
10528c2ecf20Sopenharmony_ci		state->pattern[strlen(state->pattern)-1] = '\0';
10538c2ecf20Sopenharmony_ci		adj_match_dir(&state->match_direction);
10548c2ecf20Sopenharmony_ci	} else
10558c2ecf20Sopenharmony_ci		terminate_search = 1;
10568c2ecf20Sopenharmony_ci
10578c2ecf20Sopenharmony_ci	if (terminate_search) {
10588c2ecf20Sopenharmony_ci		state->in_search = 0;
10598c2ecf20Sopenharmony_ci		bzero(state->pattern, sizeof(state->pattern));
10608c2ecf20Sopenharmony_ci		move(0, 0);
10618c2ecf20Sopenharmony_ci		refresh();
10628c2ecf20Sopenharmony_ci		clrtoeol();
10638c2ecf20Sopenharmony_ci		return -1;
10648c2ecf20Sopenharmony_ci	}
10658c2ecf20Sopenharmony_ci	return 0;
10668c2ecf20Sopenharmony_ci}
10678c2ecf20Sopenharmony_ci
10688c2ecf20Sopenharmony_cistatic void conf(struct menu *menu)
10698c2ecf20Sopenharmony_ci{
10708c2ecf20Sopenharmony_ci	struct menu *submenu = NULL;
10718c2ecf20Sopenharmony_ci	const char *prompt = menu_get_prompt(menu);
10728c2ecf20Sopenharmony_ci	struct symbol *sym;
10738c2ecf20Sopenharmony_ci	int res;
10748c2ecf20Sopenharmony_ci	int current_index = 0;
10758c2ecf20Sopenharmony_ci	int last_top_row = 0;
10768c2ecf20Sopenharmony_ci	struct match_state match_state = {
10778c2ecf20Sopenharmony_ci		.in_search = 0,
10788c2ecf20Sopenharmony_ci		.match_direction = MATCH_TINKER_PATTERN_DOWN,
10798c2ecf20Sopenharmony_ci		.pattern = "",
10808c2ecf20Sopenharmony_ci	};
10818c2ecf20Sopenharmony_ci
10828c2ecf20Sopenharmony_ci	while (!global_exit) {
10838c2ecf20Sopenharmony_ci		reset_menu();
10848c2ecf20Sopenharmony_ci		current_menu = menu;
10858c2ecf20Sopenharmony_ci		build_conf(menu);
10868c2ecf20Sopenharmony_ci		if (!child_count)
10878c2ecf20Sopenharmony_ci			break;
10888c2ecf20Sopenharmony_ci
10898c2ecf20Sopenharmony_ci		show_menu(prompt ? prompt : "Main Menu",
10908c2ecf20Sopenharmony_ci				menu_instructions,
10918c2ecf20Sopenharmony_ci				current_index, &last_top_row);
10928c2ecf20Sopenharmony_ci		keypad((menu_win(curses_menu)), TRUE);
10938c2ecf20Sopenharmony_ci		while (!global_exit) {
10948c2ecf20Sopenharmony_ci			if (match_state.in_search) {
10958c2ecf20Sopenharmony_ci				mvprintw(0, 0,
10968c2ecf20Sopenharmony_ci					"searching: %s", match_state.pattern);
10978c2ecf20Sopenharmony_ci				clrtoeol();
10988c2ecf20Sopenharmony_ci			}
10998c2ecf20Sopenharmony_ci			refresh_all_windows(main_window);
11008c2ecf20Sopenharmony_ci			res = wgetch(menu_win(curses_menu));
11018c2ecf20Sopenharmony_ci			if (!res)
11028c2ecf20Sopenharmony_ci				break;
11038c2ecf20Sopenharmony_ci			if (do_match(res, &match_state, &current_index) == 0) {
11048c2ecf20Sopenharmony_ci				if (current_index != -1)
11058c2ecf20Sopenharmony_ci					center_item(current_index,
11068c2ecf20Sopenharmony_ci						    &last_top_row);
11078c2ecf20Sopenharmony_ci				continue;
11088c2ecf20Sopenharmony_ci			}
11098c2ecf20Sopenharmony_ci			if (process_special_keys(&res,
11108c2ecf20Sopenharmony_ci						(struct menu *) item_data()))
11118c2ecf20Sopenharmony_ci				break;
11128c2ecf20Sopenharmony_ci			switch (res) {
11138c2ecf20Sopenharmony_ci			case KEY_DOWN:
11148c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_DOWN_ITEM);
11158c2ecf20Sopenharmony_ci				break;
11168c2ecf20Sopenharmony_ci			case KEY_UP:
11178c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_UP_ITEM);
11188c2ecf20Sopenharmony_ci				break;
11198c2ecf20Sopenharmony_ci			case KEY_NPAGE:
11208c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_SCR_DPAGE);
11218c2ecf20Sopenharmony_ci				break;
11228c2ecf20Sopenharmony_ci			case KEY_PPAGE:
11238c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_SCR_UPAGE);
11248c2ecf20Sopenharmony_ci				break;
11258c2ecf20Sopenharmony_ci			case KEY_HOME:
11268c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_FIRST_ITEM);
11278c2ecf20Sopenharmony_ci				break;
11288c2ecf20Sopenharmony_ci			case KEY_END:
11298c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_LAST_ITEM);
11308c2ecf20Sopenharmony_ci				break;
11318c2ecf20Sopenharmony_ci			case 'h':
11328c2ecf20Sopenharmony_ci			case '?':
11338c2ecf20Sopenharmony_ci				show_help((struct menu *) item_data());
11348c2ecf20Sopenharmony_ci				break;
11358c2ecf20Sopenharmony_ci			}
11368c2ecf20Sopenharmony_ci			if (res == 10 || res == 27 ||
11378c2ecf20Sopenharmony_ci				res == 32 || res == 'n' || res == 'y' ||
11388c2ecf20Sopenharmony_ci				res == KEY_LEFT || res == KEY_RIGHT ||
11398c2ecf20Sopenharmony_ci				res == 'm')
11408c2ecf20Sopenharmony_ci				break;
11418c2ecf20Sopenharmony_ci			refresh_all_windows(main_window);
11428c2ecf20Sopenharmony_ci		}
11438c2ecf20Sopenharmony_ci
11448c2ecf20Sopenharmony_ci		refresh_all_windows(main_window);
11458c2ecf20Sopenharmony_ci		/* if ESC or left*/
11468c2ecf20Sopenharmony_ci		if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
11478c2ecf20Sopenharmony_ci			break;
11488c2ecf20Sopenharmony_ci
11498c2ecf20Sopenharmony_ci		/* remember location in the menu */
11508c2ecf20Sopenharmony_ci		last_top_row = top_row(curses_menu);
11518c2ecf20Sopenharmony_ci		current_index = curses_item_index();
11528c2ecf20Sopenharmony_ci
11538c2ecf20Sopenharmony_ci		if (!item_tag())
11548c2ecf20Sopenharmony_ci			continue;
11558c2ecf20Sopenharmony_ci
11568c2ecf20Sopenharmony_ci		submenu = (struct menu *) item_data();
11578c2ecf20Sopenharmony_ci		if (!submenu || !menu_is_visible(submenu))
11588c2ecf20Sopenharmony_ci			continue;
11598c2ecf20Sopenharmony_ci		sym = submenu->sym;
11608c2ecf20Sopenharmony_ci
11618c2ecf20Sopenharmony_ci		switch (res) {
11628c2ecf20Sopenharmony_ci		case ' ':
11638c2ecf20Sopenharmony_ci			if (item_is_tag('t'))
11648c2ecf20Sopenharmony_ci				sym_toggle_tristate_value(sym);
11658c2ecf20Sopenharmony_ci			else if (item_is_tag('m'))
11668c2ecf20Sopenharmony_ci				conf(submenu);
11678c2ecf20Sopenharmony_ci			break;
11688c2ecf20Sopenharmony_ci		case KEY_RIGHT:
11698c2ecf20Sopenharmony_ci		case 10: /* ENTER WAS PRESSED */
11708c2ecf20Sopenharmony_ci			switch (item_tag()) {
11718c2ecf20Sopenharmony_ci			case 'm':
11728c2ecf20Sopenharmony_ci				if (single_menu_mode)
11738c2ecf20Sopenharmony_ci					submenu->data =
11748c2ecf20Sopenharmony_ci						(void *) (long) !submenu->data;
11758c2ecf20Sopenharmony_ci				else
11768c2ecf20Sopenharmony_ci					conf(submenu);
11778c2ecf20Sopenharmony_ci				break;
11788c2ecf20Sopenharmony_ci			case 't':
11798c2ecf20Sopenharmony_ci				if (sym_is_choice(sym) &&
11808c2ecf20Sopenharmony_ci				    sym_get_tristate_value(sym) == yes)
11818c2ecf20Sopenharmony_ci					conf_choice(submenu);
11828c2ecf20Sopenharmony_ci				else if (submenu->prompt &&
11838c2ecf20Sopenharmony_ci					 submenu->prompt->type == P_MENU)
11848c2ecf20Sopenharmony_ci					conf(submenu);
11858c2ecf20Sopenharmony_ci				else if (res == 10)
11868c2ecf20Sopenharmony_ci					sym_toggle_tristate_value(sym);
11878c2ecf20Sopenharmony_ci				break;
11888c2ecf20Sopenharmony_ci			case 's':
11898c2ecf20Sopenharmony_ci				conf_string(submenu);
11908c2ecf20Sopenharmony_ci				break;
11918c2ecf20Sopenharmony_ci			}
11928c2ecf20Sopenharmony_ci			break;
11938c2ecf20Sopenharmony_ci		case 'y':
11948c2ecf20Sopenharmony_ci			if (item_is_tag('t')) {
11958c2ecf20Sopenharmony_ci				if (sym_set_tristate_value(sym, yes))
11968c2ecf20Sopenharmony_ci					break;
11978c2ecf20Sopenharmony_ci				if (sym_set_tristate_value(sym, mod))
11988c2ecf20Sopenharmony_ci					btn_dialog(main_window, setmod_text, 0);
11998c2ecf20Sopenharmony_ci			}
12008c2ecf20Sopenharmony_ci			break;
12018c2ecf20Sopenharmony_ci		case 'n':
12028c2ecf20Sopenharmony_ci			if (item_is_tag('t'))
12038c2ecf20Sopenharmony_ci				sym_set_tristate_value(sym, no);
12048c2ecf20Sopenharmony_ci			break;
12058c2ecf20Sopenharmony_ci		case 'm':
12068c2ecf20Sopenharmony_ci			if (item_is_tag('t'))
12078c2ecf20Sopenharmony_ci				sym_set_tristate_value(sym, mod);
12088c2ecf20Sopenharmony_ci			break;
12098c2ecf20Sopenharmony_ci		}
12108c2ecf20Sopenharmony_ci	}
12118c2ecf20Sopenharmony_ci}
12128c2ecf20Sopenharmony_ci
12138c2ecf20Sopenharmony_cistatic void conf_message_callback(const char *s)
12148c2ecf20Sopenharmony_ci{
12158c2ecf20Sopenharmony_ci	btn_dialog(main_window, s, 1, "<OK>");
12168c2ecf20Sopenharmony_ci}
12178c2ecf20Sopenharmony_ci
12188c2ecf20Sopenharmony_cistatic void show_help(struct menu *menu)
12198c2ecf20Sopenharmony_ci{
12208c2ecf20Sopenharmony_ci	struct gstr help;
12218c2ecf20Sopenharmony_ci
12228c2ecf20Sopenharmony_ci	if (!menu)
12238c2ecf20Sopenharmony_ci		return;
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	help = str_new();
12268c2ecf20Sopenharmony_ci	menu_get_ext_help(menu, &help);
12278c2ecf20Sopenharmony_ci	show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help));
12288c2ecf20Sopenharmony_ci	str_free(&help);
12298c2ecf20Sopenharmony_ci}
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_cistatic void conf_choice(struct menu *menu)
12328c2ecf20Sopenharmony_ci{
12338c2ecf20Sopenharmony_ci	const char *prompt = menu_get_prompt(menu);
12348c2ecf20Sopenharmony_ci	struct menu *child = NULL;
12358c2ecf20Sopenharmony_ci	struct symbol *active;
12368c2ecf20Sopenharmony_ci	int selected_index = 0;
12378c2ecf20Sopenharmony_ci	int last_top_row = 0;
12388c2ecf20Sopenharmony_ci	int res, i = 0;
12398c2ecf20Sopenharmony_ci	struct match_state match_state = {
12408c2ecf20Sopenharmony_ci		.in_search = 0,
12418c2ecf20Sopenharmony_ci		.match_direction = MATCH_TINKER_PATTERN_DOWN,
12428c2ecf20Sopenharmony_ci		.pattern = "",
12438c2ecf20Sopenharmony_ci	};
12448c2ecf20Sopenharmony_ci
12458c2ecf20Sopenharmony_ci	active = sym_get_choice_value(menu->sym);
12468c2ecf20Sopenharmony_ci	/* this is mostly duplicated from the conf() function. */
12478c2ecf20Sopenharmony_ci	while (!global_exit) {
12488c2ecf20Sopenharmony_ci		reset_menu();
12498c2ecf20Sopenharmony_ci
12508c2ecf20Sopenharmony_ci		for (i = 0, child = menu->list; child; child = child->next) {
12518c2ecf20Sopenharmony_ci			if (!show_all_items && !menu_is_visible(child))
12528c2ecf20Sopenharmony_ci				continue;
12538c2ecf20Sopenharmony_ci
12548c2ecf20Sopenharmony_ci			if (child->sym == sym_get_choice_value(menu->sym))
12558c2ecf20Sopenharmony_ci				item_make(child, ':', "<X> %s",
12568c2ecf20Sopenharmony_ci						menu_get_prompt(child));
12578c2ecf20Sopenharmony_ci			else if (child->sym)
12588c2ecf20Sopenharmony_ci				item_make(child, ':', "    %s",
12598c2ecf20Sopenharmony_ci						menu_get_prompt(child));
12608c2ecf20Sopenharmony_ci			else
12618c2ecf20Sopenharmony_ci				item_make(child, ':', "*** %s ***",
12628c2ecf20Sopenharmony_ci						menu_get_prompt(child));
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci			if (child->sym == active){
12658c2ecf20Sopenharmony_ci				last_top_row = top_row(curses_menu);
12668c2ecf20Sopenharmony_ci				selected_index = i;
12678c2ecf20Sopenharmony_ci			}
12688c2ecf20Sopenharmony_ci			i++;
12698c2ecf20Sopenharmony_ci		}
12708c2ecf20Sopenharmony_ci		show_menu(prompt ? prompt : "Choice Menu",
12718c2ecf20Sopenharmony_ci				radiolist_instructions,
12728c2ecf20Sopenharmony_ci				selected_index,
12738c2ecf20Sopenharmony_ci				&last_top_row);
12748c2ecf20Sopenharmony_ci		while (!global_exit) {
12758c2ecf20Sopenharmony_ci			if (match_state.in_search) {
12768c2ecf20Sopenharmony_ci				mvprintw(0, 0, "searching: %s",
12778c2ecf20Sopenharmony_ci					 match_state.pattern);
12788c2ecf20Sopenharmony_ci				clrtoeol();
12798c2ecf20Sopenharmony_ci			}
12808c2ecf20Sopenharmony_ci			refresh_all_windows(main_window);
12818c2ecf20Sopenharmony_ci			res = wgetch(menu_win(curses_menu));
12828c2ecf20Sopenharmony_ci			if (!res)
12838c2ecf20Sopenharmony_ci				break;
12848c2ecf20Sopenharmony_ci			if (do_match(res, &match_state, &selected_index) == 0) {
12858c2ecf20Sopenharmony_ci				if (selected_index != -1)
12868c2ecf20Sopenharmony_ci					center_item(selected_index,
12878c2ecf20Sopenharmony_ci						    &last_top_row);
12888c2ecf20Sopenharmony_ci				continue;
12898c2ecf20Sopenharmony_ci			}
12908c2ecf20Sopenharmony_ci			if (process_special_keys(
12918c2ecf20Sopenharmony_ci						&res,
12928c2ecf20Sopenharmony_ci						(struct menu *) item_data()))
12938c2ecf20Sopenharmony_ci				break;
12948c2ecf20Sopenharmony_ci			switch (res) {
12958c2ecf20Sopenharmony_ci			case KEY_DOWN:
12968c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_DOWN_ITEM);
12978c2ecf20Sopenharmony_ci				break;
12988c2ecf20Sopenharmony_ci			case KEY_UP:
12998c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_UP_ITEM);
13008c2ecf20Sopenharmony_ci				break;
13018c2ecf20Sopenharmony_ci			case KEY_NPAGE:
13028c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_SCR_DPAGE);
13038c2ecf20Sopenharmony_ci				break;
13048c2ecf20Sopenharmony_ci			case KEY_PPAGE:
13058c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_SCR_UPAGE);
13068c2ecf20Sopenharmony_ci				break;
13078c2ecf20Sopenharmony_ci			case KEY_HOME:
13088c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_FIRST_ITEM);
13098c2ecf20Sopenharmony_ci				break;
13108c2ecf20Sopenharmony_ci			case KEY_END:
13118c2ecf20Sopenharmony_ci				menu_driver(curses_menu, REQ_LAST_ITEM);
13128c2ecf20Sopenharmony_ci				break;
13138c2ecf20Sopenharmony_ci			case 'h':
13148c2ecf20Sopenharmony_ci			case '?':
13158c2ecf20Sopenharmony_ci				show_help((struct menu *) item_data());
13168c2ecf20Sopenharmony_ci				break;
13178c2ecf20Sopenharmony_ci			}
13188c2ecf20Sopenharmony_ci			if (res == 10 || res == 27 || res == ' ' ||
13198c2ecf20Sopenharmony_ci					res == KEY_LEFT){
13208c2ecf20Sopenharmony_ci				break;
13218c2ecf20Sopenharmony_ci			}
13228c2ecf20Sopenharmony_ci			refresh_all_windows(main_window);
13238c2ecf20Sopenharmony_ci		}
13248c2ecf20Sopenharmony_ci		/* if ESC or left */
13258c2ecf20Sopenharmony_ci		if (res == 27 || res == KEY_LEFT)
13268c2ecf20Sopenharmony_ci			break;
13278c2ecf20Sopenharmony_ci
13288c2ecf20Sopenharmony_ci		child = item_data();
13298c2ecf20Sopenharmony_ci		if (!child || !menu_is_visible(child) || !child->sym)
13308c2ecf20Sopenharmony_ci			continue;
13318c2ecf20Sopenharmony_ci		switch (res) {
13328c2ecf20Sopenharmony_ci		case ' ':
13338c2ecf20Sopenharmony_ci		case  10:
13348c2ecf20Sopenharmony_ci		case KEY_RIGHT:
13358c2ecf20Sopenharmony_ci			sym_set_tristate_value(child->sym, yes);
13368c2ecf20Sopenharmony_ci			return;
13378c2ecf20Sopenharmony_ci		case 'h':
13388c2ecf20Sopenharmony_ci		case '?':
13398c2ecf20Sopenharmony_ci			show_help(child);
13408c2ecf20Sopenharmony_ci			active = child->sym;
13418c2ecf20Sopenharmony_ci			break;
13428c2ecf20Sopenharmony_ci		case KEY_EXIT:
13438c2ecf20Sopenharmony_ci			return;
13448c2ecf20Sopenharmony_ci		}
13458c2ecf20Sopenharmony_ci	}
13468c2ecf20Sopenharmony_ci}
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_cistatic void conf_string(struct menu *menu)
13498c2ecf20Sopenharmony_ci{
13508c2ecf20Sopenharmony_ci	const char *prompt = menu_get_prompt(menu);
13518c2ecf20Sopenharmony_ci
13528c2ecf20Sopenharmony_ci	while (1) {
13538c2ecf20Sopenharmony_ci		int res;
13548c2ecf20Sopenharmony_ci		const char *heading;
13558c2ecf20Sopenharmony_ci
13568c2ecf20Sopenharmony_ci		switch (sym_get_type(menu->sym)) {
13578c2ecf20Sopenharmony_ci		case S_INT:
13588c2ecf20Sopenharmony_ci			heading = inputbox_instructions_int;
13598c2ecf20Sopenharmony_ci			break;
13608c2ecf20Sopenharmony_ci		case S_HEX:
13618c2ecf20Sopenharmony_ci			heading = inputbox_instructions_hex;
13628c2ecf20Sopenharmony_ci			break;
13638c2ecf20Sopenharmony_ci		case S_STRING:
13648c2ecf20Sopenharmony_ci			heading = inputbox_instructions_string;
13658c2ecf20Sopenharmony_ci			break;
13668c2ecf20Sopenharmony_ci		default:
13678c2ecf20Sopenharmony_ci			heading = "Internal nconf error!";
13688c2ecf20Sopenharmony_ci		}
13698c2ecf20Sopenharmony_ci		res = dialog_inputbox(main_window,
13708c2ecf20Sopenharmony_ci				prompt ? prompt : "Main Menu",
13718c2ecf20Sopenharmony_ci				heading,
13728c2ecf20Sopenharmony_ci				sym_get_string_value(menu->sym),
13738c2ecf20Sopenharmony_ci				&dialog_input_result,
13748c2ecf20Sopenharmony_ci				&dialog_input_result_len);
13758c2ecf20Sopenharmony_ci		switch (res) {
13768c2ecf20Sopenharmony_ci		case 0:
13778c2ecf20Sopenharmony_ci			if (sym_set_string_value(menu->sym,
13788c2ecf20Sopenharmony_ci						dialog_input_result))
13798c2ecf20Sopenharmony_ci				return;
13808c2ecf20Sopenharmony_ci			btn_dialog(main_window,
13818c2ecf20Sopenharmony_ci				"You have made an invalid entry.", 0);
13828c2ecf20Sopenharmony_ci			break;
13838c2ecf20Sopenharmony_ci		case 1:
13848c2ecf20Sopenharmony_ci			show_help(menu);
13858c2ecf20Sopenharmony_ci			break;
13868c2ecf20Sopenharmony_ci		case KEY_EXIT:
13878c2ecf20Sopenharmony_ci			return;
13888c2ecf20Sopenharmony_ci		}
13898c2ecf20Sopenharmony_ci	}
13908c2ecf20Sopenharmony_ci}
13918c2ecf20Sopenharmony_ci
13928c2ecf20Sopenharmony_cistatic void conf_load(void)
13938c2ecf20Sopenharmony_ci{
13948c2ecf20Sopenharmony_ci	while (1) {
13958c2ecf20Sopenharmony_ci		int res;
13968c2ecf20Sopenharmony_ci		res = dialog_inputbox(main_window,
13978c2ecf20Sopenharmony_ci				NULL, load_config_text,
13988c2ecf20Sopenharmony_ci				filename,
13998c2ecf20Sopenharmony_ci				&dialog_input_result,
14008c2ecf20Sopenharmony_ci				&dialog_input_result_len);
14018c2ecf20Sopenharmony_ci		switch (res) {
14028c2ecf20Sopenharmony_ci		case 0:
14038c2ecf20Sopenharmony_ci			if (!dialog_input_result[0])
14048c2ecf20Sopenharmony_ci				return;
14058c2ecf20Sopenharmony_ci			if (!conf_read(dialog_input_result)) {
14068c2ecf20Sopenharmony_ci				set_config_filename(dialog_input_result);
14078c2ecf20Sopenharmony_ci				sym_set_change_count(1);
14088c2ecf20Sopenharmony_ci				return;
14098c2ecf20Sopenharmony_ci			}
14108c2ecf20Sopenharmony_ci			btn_dialog(main_window, "File does not exist!", 0);
14118c2ecf20Sopenharmony_ci			break;
14128c2ecf20Sopenharmony_ci		case 1:
14138c2ecf20Sopenharmony_ci			show_scroll_win(main_window,
14148c2ecf20Sopenharmony_ci					"Load Alternate Configuration",
14158c2ecf20Sopenharmony_ci					load_config_help);
14168c2ecf20Sopenharmony_ci			break;
14178c2ecf20Sopenharmony_ci		case KEY_EXIT:
14188c2ecf20Sopenharmony_ci			return;
14198c2ecf20Sopenharmony_ci		}
14208c2ecf20Sopenharmony_ci	}
14218c2ecf20Sopenharmony_ci}
14228c2ecf20Sopenharmony_ci
14238c2ecf20Sopenharmony_cistatic void conf_save(void)
14248c2ecf20Sopenharmony_ci{
14258c2ecf20Sopenharmony_ci	while (1) {
14268c2ecf20Sopenharmony_ci		int res;
14278c2ecf20Sopenharmony_ci		res = dialog_inputbox(main_window,
14288c2ecf20Sopenharmony_ci				NULL, save_config_text,
14298c2ecf20Sopenharmony_ci				filename,
14308c2ecf20Sopenharmony_ci				&dialog_input_result,
14318c2ecf20Sopenharmony_ci				&dialog_input_result_len);
14328c2ecf20Sopenharmony_ci		switch (res) {
14338c2ecf20Sopenharmony_ci		case 0:
14348c2ecf20Sopenharmony_ci			if (!dialog_input_result[0])
14358c2ecf20Sopenharmony_ci				return;
14368c2ecf20Sopenharmony_ci			res = conf_write(dialog_input_result);
14378c2ecf20Sopenharmony_ci			if (!res) {
14388c2ecf20Sopenharmony_ci				set_config_filename(dialog_input_result);
14398c2ecf20Sopenharmony_ci				return;
14408c2ecf20Sopenharmony_ci			}
14418c2ecf20Sopenharmony_ci			btn_dialog(main_window, "Can't create file!",
14428c2ecf20Sopenharmony_ci				1, "<OK>");
14438c2ecf20Sopenharmony_ci			break;
14448c2ecf20Sopenharmony_ci		case 1:
14458c2ecf20Sopenharmony_ci			show_scroll_win(main_window,
14468c2ecf20Sopenharmony_ci				"Save Alternate Configuration",
14478c2ecf20Sopenharmony_ci				save_config_help);
14488c2ecf20Sopenharmony_ci			break;
14498c2ecf20Sopenharmony_ci		case KEY_EXIT:
14508c2ecf20Sopenharmony_ci			return;
14518c2ecf20Sopenharmony_ci		}
14528c2ecf20Sopenharmony_ci	}
14538c2ecf20Sopenharmony_ci}
14548c2ecf20Sopenharmony_ci
14558c2ecf20Sopenharmony_cistatic void setup_windows(void)
14568c2ecf20Sopenharmony_ci{
14578c2ecf20Sopenharmony_ci	int lines, columns;
14588c2ecf20Sopenharmony_ci
14598c2ecf20Sopenharmony_ci	getmaxyx(stdscr, lines, columns);
14608c2ecf20Sopenharmony_ci
14618c2ecf20Sopenharmony_ci	if (main_window != NULL)
14628c2ecf20Sopenharmony_ci		delwin(main_window);
14638c2ecf20Sopenharmony_ci
14648c2ecf20Sopenharmony_ci	/* set up the menu and menu window */
14658c2ecf20Sopenharmony_ci	main_window = newwin(lines-2, columns-2, 2, 1);
14668c2ecf20Sopenharmony_ci	keypad(main_window, TRUE);
14678c2ecf20Sopenharmony_ci	mwin_max_lines = lines-7;
14688c2ecf20Sopenharmony_ci	mwin_max_cols = columns-6;
14698c2ecf20Sopenharmony_ci
14708c2ecf20Sopenharmony_ci	/* panels order is from bottom to top */
14718c2ecf20Sopenharmony_ci	new_panel(main_window);
14728c2ecf20Sopenharmony_ci}
14738c2ecf20Sopenharmony_ci
14748c2ecf20Sopenharmony_ciint main(int ac, char **av)
14758c2ecf20Sopenharmony_ci{
14768c2ecf20Sopenharmony_ci	int lines, columns;
14778c2ecf20Sopenharmony_ci	char *mode;
14788c2ecf20Sopenharmony_ci
14798c2ecf20Sopenharmony_ci	if (ac > 1 && strcmp(av[1], "-s") == 0) {
14808c2ecf20Sopenharmony_ci		/* Silence conf_read() until the real callback is set up */
14818c2ecf20Sopenharmony_ci		conf_set_message_callback(NULL);
14828c2ecf20Sopenharmony_ci		av++;
14838c2ecf20Sopenharmony_ci	}
14848c2ecf20Sopenharmony_ci	conf_parse(av[1]);
14858c2ecf20Sopenharmony_ci	conf_read(NULL);
14868c2ecf20Sopenharmony_ci
14878c2ecf20Sopenharmony_ci	mode = getenv("NCONFIG_MODE");
14888c2ecf20Sopenharmony_ci	if (mode) {
14898c2ecf20Sopenharmony_ci		if (!strcasecmp(mode, "single_menu"))
14908c2ecf20Sopenharmony_ci			single_menu_mode = 1;
14918c2ecf20Sopenharmony_ci	}
14928c2ecf20Sopenharmony_ci
14938c2ecf20Sopenharmony_ci	/* Initialize curses */
14948c2ecf20Sopenharmony_ci	initscr();
14958c2ecf20Sopenharmony_ci	/* set color theme */
14968c2ecf20Sopenharmony_ci	set_colors();
14978c2ecf20Sopenharmony_ci
14988c2ecf20Sopenharmony_ci	cbreak();
14998c2ecf20Sopenharmony_ci	noecho();
15008c2ecf20Sopenharmony_ci	keypad(stdscr, TRUE);
15018c2ecf20Sopenharmony_ci	curs_set(0);
15028c2ecf20Sopenharmony_ci
15038c2ecf20Sopenharmony_ci	getmaxyx(stdscr, lines, columns);
15048c2ecf20Sopenharmony_ci	if (columns < 75 || lines < 20) {
15058c2ecf20Sopenharmony_ci		endwin();
15068c2ecf20Sopenharmony_ci		printf("Your terminal should have at "
15078c2ecf20Sopenharmony_ci			"least 20 lines and 75 columns\n");
15088c2ecf20Sopenharmony_ci		return 1;
15098c2ecf20Sopenharmony_ci	}
15108c2ecf20Sopenharmony_ci
15118c2ecf20Sopenharmony_ci	notimeout(stdscr, FALSE);
15128c2ecf20Sopenharmony_ci#if NCURSES_REENTRANT
15138c2ecf20Sopenharmony_ci	set_escdelay(1);
15148c2ecf20Sopenharmony_ci#else
15158c2ecf20Sopenharmony_ci	ESCDELAY = 1;
15168c2ecf20Sopenharmony_ci#endif
15178c2ecf20Sopenharmony_ci
15188c2ecf20Sopenharmony_ci	/* set btns menu */
15198c2ecf20Sopenharmony_ci	curses_menu = new_menu(curses_menu_items);
15208c2ecf20Sopenharmony_ci	menu_opts_off(curses_menu, O_SHOWDESC);
15218c2ecf20Sopenharmony_ci	menu_opts_on(curses_menu, O_SHOWMATCH);
15228c2ecf20Sopenharmony_ci	menu_opts_on(curses_menu, O_ONEVALUE);
15238c2ecf20Sopenharmony_ci	menu_opts_on(curses_menu, O_NONCYCLIC);
15248c2ecf20Sopenharmony_ci	menu_opts_on(curses_menu, O_IGNORECASE);
15258c2ecf20Sopenharmony_ci	set_menu_mark(curses_menu, " ");
15268c2ecf20Sopenharmony_ci	set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
15278c2ecf20Sopenharmony_ci	set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
15288c2ecf20Sopenharmony_ci	set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
15298c2ecf20Sopenharmony_ci
15308c2ecf20Sopenharmony_ci	set_config_filename(conf_get_configname());
15318c2ecf20Sopenharmony_ci	setup_windows();
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci	/* check for KEY_FUNC(1) */
15348c2ecf20Sopenharmony_ci	if (has_key(KEY_F(1)) == FALSE) {
15358c2ecf20Sopenharmony_ci		show_scroll_win(main_window,
15368c2ecf20Sopenharmony_ci				"Instructions",
15378c2ecf20Sopenharmony_ci				menu_no_f_instructions);
15388c2ecf20Sopenharmony_ci	}
15398c2ecf20Sopenharmony_ci
15408c2ecf20Sopenharmony_ci	conf_set_message_callback(conf_message_callback);
15418c2ecf20Sopenharmony_ci	/* do the work */
15428c2ecf20Sopenharmony_ci	while (!global_exit) {
15438c2ecf20Sopenharmony_ci		conf(&rootmenu);
15448c2ecf20Sopenharmony_ci		if (!global_exit && do_exit() == 0)
15458c2ecf20Sopenharmony_ci			break;
15468c2ecf20Sopenharmony_ci	}
15478c2ecf20Sopenharmony_ci	/* ok, we are done */
15488c2ecf20Sopenharmony_ci	unpost_menu(curses_menu);
15498c2ecf20Sopenharmony_ci	free_menu(curses_menu);
15508c2ecf20Sopenharmony_ci	delwin(main_window);
15518c2ecf20Sopenharmony_ci	clear();
15528c2ecf20Sopenharmony_ci	refresh();
15538c2ecf20Sopenharmony_ci	endwin();
15548c2ecf20Sopenharmony_ci	return 0;
15558c2ecf20Sopenharmony_ci}
1556