xref: /linux/scripts/kconfig/nconf.c (revision 5e609addb1bd963ce1a1929f2012c8dd04ca8620)
1692d97c3Snir.tzachar@gmail.com /*
2692d97c3Snir.tzachar@gmail.com  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3692d97c3Snir.tzachar@gmail.com  * Released under the terms of the GNU GPL v2.0.
4692d97c3Snir.tzachar@gmail.com  *
5692d97c3Snir.tzachar@gmail.com  * Derived from menuconfig.
6692d97c3Snir.tzachar@gmail.com  *
7692d97c3Snir.tzachar@gmail.com  */
8a72f3e2bSNir Tzachar #define _GNU_SOURCE
9a72f3e2bSNir Tzachar #include <string.h>
105a6f8d2bSArnaud Lacombe 
11692d97c3Snir.tzachar@gmail.com #include "lkc.h"
12692d97c3Snir.tzachar@gmail.com #include "nconf.h"
13a72f3e2bSNir Tzachar #include <ctype.h>
14692d97c3Snir.tzachar@gmail.com 
15692d97c3Snir.tzachar@gmail.com static const char nconf_readme[] = N_(
16692d97c3Snir.tzachar@gmail.com "Overview\n"
17692d97c3Snir.tzachar@gmail.com "--------\n"
18652cf982SArnaud Lacombe "This interface let you select features and parameters for the build.\n"
19652cf982SArnaud Lacombe "Features can either be built-in, modularized, or ignored. Parameters\n"
20652cf982SArnaud Lacombe "must be entered in as decimal or hexadecimal numbers or text.\n"
21692d97c3Snir.tzachar@gmail.com "\n"
22692d97c3Snir.tzachar@gmail.com "Menu items beginning with following braces represent features that\n"
23692d97c3Snir.tzachar@gmail.com "  [ ] can be built in or removed\n"
24692d97c3Snir.tzachar@gmail.com "  < > can be built in, modularized or removed\n"
25692d97c3Snir.tzachar@gmail.com "  { } can be built in or modularized (selected by other feature)\n"
26692d97c3Snir.tzachar@gmail.com "  - - are selected by other feature,\n"
27a72f3e2bSNir Tzachar "  XXX cannot be selected. Use Symbol Info to find out why,\n"
28692d97c3Snir.tzachar@gmail.com "while *, M or whitespace inside braces means to build in, build as\n"
29692d97c3Snir.tzachar@gmail.com "a module or to exclude the feature respectively.\n"
30692d97c3Snir.tzachar@gmail.com "\n"
31692d97c3Snir.tzachar@gmail.com "To change any of these features, highlight it with the cursor\n"
32692d97c3Snir.tzachar@gmail.com "keys and press <Y> to build it in, <M> to make it a module or\n"
33692d97c3Snir.tzachar@gmail.com "<N> to removed it.  You may also press the <Space Bar> to cycle\n"
34692d97c3Snir.tzachar@gmail.com "through the available options (ie. Y->N->M->Y).\n"
35692d97c3Snir.tzachar@gmail.com "\n"
36692d97c3Snir.tzachar@gmail.com "Some additional keyboard hints:\n"
37692d97c3Snir.tzachar@gmail.com "\n"
38692d97c3Snir.tzachar@gmail.com "Menus\n"
39692d97c3Snir.tzachar@gmail.com "----------\n"
40692d97c3Snir.tzachar@gmail.com "o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
41692d97c3Snir.tzachar@gmail.com "   you wish to change use <Enter> or <Space>. Goto submenu by \n"
42692d97c3Snir.tzachar@gmail.com "   pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
43692d97c3Snir.tzachar@gmail.com "   Submenus are designated by \"--->\".\n"
44692d97c3Snir.tzachar@gmail.com "\n"
45a72f3e2bSNir Tzachar "   Searching: pressing '/' triggers interactive search mode.\n"
46a72f3e2bSNir Tzachar "              nconfig performs a case insensitive search for the string\n"
47a72f3e2bSNir Tzachar "              in the menu prompts (no regex support).\n"
48a72f3e2bSNir Tzachar "              Pressing the up/down keys highlights the previous/next\n"
49a72f3e2bSNir Tzachar "              matching item. Backspace removes one character from the\n"
50a72f3e2bSNir Tzachar "              match string. Pressing either '/' again or ESC exits\n"
51a72f3e2bSNir Tzachar "              search mode. All other keys behave normally.\n"
52692d97c3Snir.tzachar@gmail.com "\n"
53692d97c3Snir.tzachar@gmail.com "   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
54692d97c3Snir.tzachar@gmail.com "   unseen options into view.\n"
55692d97c3Snir.tzachar@gmail.com "\n"
56692d97c3Snir.tzachar@gmail.com "o  To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
57692d97c3Snir.tzachar@gmail.com "\n"
58692d97c3Snir.tzachar@gmail.com "o  To get help with an item, press <F1>\n"
59692d97c3Snir.tzachar@gmail.com "   Shortcut: Press <h> or <?>.\n"
60692d97c3Snir.tzachar@gmail.com "\n"
61692d97c3Snir.tzachar@gmail.com "\n"
62692d97c3Snir.tzachar@gmail.com "Radiolists  (Choice lists)\n"
63692d97c3Snir.tzachar@gmail.com "-----------\n"
64692d97c3Snir.tzachar@gmail.com "o  Use the cursor keys to select the option you wish to set and press\n"
65692d97c3Snir.tzachar@gmail.com "   <S> or the <SPACE BAR>.\n"
66692d97c3Snir.tzachar@gmail.com "\n"
67692d97c3Snir.tzachar@gmail.com "   Shortcut: Press the first letter of the option you wish to set then\n"
68692d97c3Snir.tzachar@gmail.com "             press <S> or <SPACE BAR>.\n"
69692d97c3Snir.tzachar@gmail.com "\n"
70692d97c3Snir.tzachar@gmail.com "o  To see available help for the item, press <F1>\n"
71692d97c3Snir.tzachar@gmail.com "   Shortcut: Press <H> or <?>.\n"
72692d97c3Snir.tzachar@gmail.com "\n"
73692d97c3Snir.tzachar@gmail.com "\n"
74692d97c3Snir.tzachar@gmail.com "Data Entry\n"
75692d97c3Snir.tzachar@gmail.com "-----------\n"
76692d97c3Snir.tzachar@gmail.com "o  Enter the requested information and press <ENTER>\n"
77692d97c3Snir.tzachar@gmail.com "   If you are entering hexadecimal values, it is not necessary to\n"
78692d97c3Snir.tzachar@gmail.com "   add the '0x' prefix to the entry.\n"
79692d97c3Snir.tzachar@gmail.com "\n"
80692d97c3Snir.tzachar@gmail.com "o  For help, press <F1>.\n"
81692d97c3Snir.tzachar@gmail.com "\n"
82692d97c3Snir.tzachar@gmail.com "\n"
83692d97c3Snir.tzachar@gmail.com "Text Box    (Help Window)\n"
84692d97c3Snir.tzachar@gmail.com "--------\n"
85692d97c3Snir.tzachar@gmail.com "o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
86d68e818bSBenjamin Poirier "   keys h,j,k,l function here as do <u>, <d> and <SPACE BAR> for\n"
87d68e818bSBenjamin Poirier "   those who are familiar with less and lynx.\n"
88692d97c3Snir.tzachar@gmail.com "\n"
89d68e818bSBenjamin Poirier "o  Press <Enter>, <F1>, <F5>, <F9>, <q> or <Esc> to exit.\n"
90692d97c3Snir.tzachar@gmail.com "\n"
91692d97c3Snir.tzachar@gmail.com "\n"
92692d97c3Snir.tzachar@gmail.com "Alternate Configuration Files\n"
93692d97c3Snir.tzachar@gmail.com "-----------------------------\n"
94692d97c3Snir.tzachar@gmail.com "nconfig supports the use of alternate configuration files for\n"
95692d97c3Snir.tzachar@gmail.com "those who, for various reasons, find it necessary to switch\n"
96652cf982SArnaud Lacombe "between different configurations.\n"
97692d97c3Snir.tzachar@gmail.com "\n"
98692d97c3Snir.tzachar@gmail.com "At the end of the main menu you will find two options.  One is\n"
99692d97c3Snir.tzachar@gmail.com "for saving the current configuration to a file of your choosing.\n"
100692d97c3Snir.tzachar@gmail.com "The other option is for loading a previously saved alternate\n"
101692d97c3Snir.tzachar@gmail.com "configuration.\n"
102692d97c3Snir.tzachar@gmail.com "\n"
103692d97c3Snir.tzachar@gmail.com "Even if you don't use alternate configuration files, but you\n"
104692d97c3Snir.tzachar@gmail.com "find during a nconfig session that you have completely messed\n"
105692d97c3Snir.tzachar@gmail.com "up your settings, you may use the \"Load Alternate...\" option to\n"
106692d97c3Snir.tzachar@gmail.com "restore your previously saved settings from \".config\" without\n"
107692d97c3Snir.tzachar@gmail.com "restarting nconfig.\n"
108692d97c3Snir.tzachar@gmail.com "\n"
109692d97c3Snir.tzachar@gmail.com "Other information\n"
110692d97c3Snir.tzachar@gmail.com "-----------------\n"
111692d97c3Snir.tzachar@gmail.com "If you use nconfig in an XTERM window make sure you have your\n"
112692d97c3Snir.tzachar@gmail.com "$TERM variable set to point to a xterm definition which supports color.\n"
113692d97c3Snir.tzachar@gmail.com "Otherwise, nconfig will look rather bad.  nconfig will not\n"
114692d97c3Snir.tzachar@gmail.com "display correctly in a RXVT window because rxvt displays only one\n"
115692d97c3Snir.tzachar@gmail.com "intensity of color, bright.\n"
116692d97c3Snir.tzachar@gmail.com "\n"
117692d97c3Snir.tzachar@gmail.com "nconfig will display larger menus on screens or xterms which are\n"
118692d97c3Snir.tzachar@gmail.com "set to display more than the standard 25 row by 80 column geometry.\n"
119692d97c3Snir.tzachar@gmail.com "In order for this to work, the \"stty size\" command must be able to\n"
120692d97c3Snir.tzachar@gmail.com "display the screen's current row and column geometry.  I STRONGLY\n"
121692d97c3Snir.tzachar@gmail.com "RECOMMEND that you make sure you do NOT have the shell variables\n"
122692d97c3Snir.tzachar@gmail.com "LINES and COLUMNS exported into your environment.  Some distributions\n"
123692d97c3Snir.tzachar@gmail.com "export those variables via /etc/profile.  Some ncurses programs can\n"
124692d97c3Snir.tzachar@gmail.com "become confused when those variables (LINES & COLUMNS) don't reflect\n"
125692d97c3Snir.tzachar@gmail.com "the true screen size.\n"
126692d97c3Snir.tzachar@gmail.com "\n"
127692d97c3Snir.tzachar@gmail.com "Optional personality available\n"
128692d97c3Snir.tzachar@gmail.com "------------------------------\n"
129652cf982SArnaud Lacombe "If you prefer to have all of the options listed in a single menu, rather\n"
130652cf982SArnaud Lacombe "than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n"
131652cf982SArnaud Lacombe "environment variable set to single_menu. Example:\n"
132692d97c3Snir.tzachar@gmail.com "\n"
133692d97c3Snir.tzachar@gmail.com "make NCONFIG_MODE=single_menu nconfig\n"
134692d97c3Snir.tzachar@gmail.com "\n"
135692d97c3Snir.tzachar@gmail.com "<Enter> will then unroll the appropriate category, or enfold it if it\n"
136692d97c3Snir.tzachar@gmail.com "is already unrolled.\n"
137692d97c3Snir.tzachar@gmail.com "\n"
138692d97c3Snir.tzachar@gmail.com "Note that this mode can eventually be a little more CPU expensive\n"
139692d97c3Snir.tzachar@gmail.com "(especially with a larger number of unrolled categories) than the\n"
140692d97c3Snir.tzachar@gmail.com "default mode.\n"
141692d97c3Snir.tzachar@gmail.com "\n"),
142692d97c3Snir.tzachar@gmail.com menu_no_f_instructions[] = N_(
143692d97c3Snir.tzachar@gmail.com " You do not have function keys support. Please follow the\n"
144692d97c3Snir.tzachar@gmail.com " following instructions:\n"
145692d97c3Snir.tzachar@gmail.com " Arrow keys navigate the menu.\n"
146692d97c3Snir.tzachar@gmail.com " <Enter> or <right-arrow> selects submenus --->.\n"
147692d97c3Snir.tzachar@gmail.com " Capital Letters are hotkeys.\n"
148692d97c3Snir.tzachar@gmail.com " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
149a72f3e2bSNir Tzachar " Pressing SpaceBar toggles between the above options.\n"
150692d97c3Snir.tzachar@gmail.com " Press <Esc> or <left-arrow> to go back one menu,\n"
151692d97c3Snir.tzachar@gmail.com " <?> or <h> for Help, </> for Search.\n"
152a72f3e2bSNir Tzachar " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
153692d97c3Snir.tzachar@gmail.com " Legend: [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
154a72f3e2bSNir Tzachar " <Esc> always leaves the current window.\n"),
155692d97c3Snir.tzachar@gmail.com menu_instructions[] = N_(
156692d97c3Snir.tzachar@gmail.com " Arrow keys navigate the menu.\n"
157692d97c3Snir.tzachar@gmail.com " <Enter> or <right-arrow> selects submenus --->.\n"
158692d97c3Snir.tzachar@gmail.com " Capital Letters are hotkeys.\n"
159692d97c3Snir.tzachar@gmail.com " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
160692d97c3Snir.tzachar@gmail.com " Pressing SpaceBar toggles between the above options\n"
161a72f3e2bSNir Tzachar " Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
162692d97c3Snir.tzachar@gmail.com " <?>, <F1> or <h> for Help, </> for Search.\n"
163a72f3e2bSNir Tzachar " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
164692d97c3Snir.tzachar@gmail.com " Legend: [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
165692d97c3Snir.tzachar@gmail.com " <Esc> always leaves the current window\n"),
166692d97c3Snir.tzachar@gmail.com radiolist_instructions[] = N_(
167692d97c3Snir.tzachar@gmail.com " Use the arrow keys to navigate this window or\n"
168692d97c3Snir.tzachar@gmail.com " press the hotkey of the item you wish to select\n"
169692d97c3Snir.tzachar@gmail.com " followed by the <SPACE BAR>.\n"
170692d97c3Snir.tzachar@gmail.com " Press <?>, <F1> or <h> for additional information about this option.\n"),
171692d97c3Snir.tzachar@gmail.com inputbox_instructions_int[] = N_(
172692d97c3Snir.tzachar@gmail.com "Please enter a decimal value.\n"
173692d97c3Snir.tzachar@gmail.com "Fractions will not be accepted.\n"
174692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."),
175692d97c3Snir.tzachar@gmail.com inputbox_instructions_hex[] = N_(
176692d97c3Snir.tzachar@gmail.com "Please enter a hexadecimal value.\n"
177692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."),
178692d97c3Snir.tzachar@gmail.com inputbox_instructions_string[] = N_(
179692d97c3Snir.tzachar@gmail.com "Please enter a string value.\n"
180692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."),
181692d97c3Snir.tzachar@gmail.com setmod_text[] = N_(
182692d97c3Snir.tzachar@gmail.com "This feature depends on another which\n"
183692d97c3Snir.tzachar@gmail.com "has been configured as a module.\n"
184692d97c3Snir.tzachar@gmail.com "As a result, this feature will be built as a module."),
185692d97c3Snir.tzachar@gmail.com load_config_text[] = N_(
186692d97c3Snir.tzachar@gmail.com "Enter the name of the configuration file you wish to load.\n"
187692d97c3Snir.tzachar@gmail.com "Accept the name shown to restore the configuration you\n"
188692d97c3Snir.tzachar@gmail.com "last retrieved.  Leave blank to abort."),
189692d97c3Snir.tzachar@gmail.com load_config_help[] = N_(
190692d97c3Snir.tzachar@gmail.com "\n"
191652cf982SArnaud Lacombe "For various reasons, one may wish to keep several different\n"
192692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n"
193692d97c3Snir.tzachar@gmail.com "\n"
194692d97c3Snir.tzachar@gmail.com "If you have saved a previous configuration in a file other than the\n"
195652cf982SArnaud Lacombe "default one, entering its name here will allow you to modify that\n"
196652cf982SArnaud Lacombe "configuration.\n"
197692d97c3Snir.tzachar@gmail.com "\n"
198692d97c3Snir.tzachar@gmail.com "If you are uncertain, then you have probably never used alternate\n"
199692d97c3Snir.tzachar@gmail.com "configuration files.  You should therefor leave this blank to abort.\n"),
200692d97c3Snir.tzachar@gmail.com save_config_text[] = N_(
201692d97c3Snir.tzachar@gmail.com "Enter a filename to which this configuration should be saved\n"
202692d97c3Snir.tzachar@gmail.com "as an alternate.  Leave blank to abort."),
203692d97c3Snir.tzachar@gmail.com save_config_help[] = N_(
204692d97c3Snir.tzachar@gmail.com "\n"
205652cf982SArnaud Lacombe "For various reasons, one may wish to keep different configurations\n"
206652cf982SArnaud Lacombe "available on a single machine.\n"
207692d97c3Snir.tzachar@gmail.com "\n"
208692d97c3Snir.tzachar@gmail.com "Entering a file name here will allow you to later retrieve, modify\n"
209692d97c3Snir.tzachar@gmail.com "and use the current configuration as an alternate to whatever\n"
210692d97c3Snir.tzachar@gmail.com "configuration options you have selected at that time.\n"
211692d97c3Snir.tzachar@gmail.com "\n"
212692d97c3Snir.tzachar@gmail.com "If you are uncertain what all this means then you should probably\n"
213692d97c3Snir.tzachar@gmail.com "leave this blank.\n"),
214692d97c3Snir.tzachar@gmail.com search_help[] = N_(
215692d97c3Snir.tzachar@gmail.com "\n"
21659dfa24dSArnaud Lacombe "Search for symbols and display their relations. Regular expressions\n"
21759dfa24dSArnaud Lacombe "are allowed.\n"
218692d97c3Snir.tzachar@gmail.com "Example: search for \"^FOO\"\n"
219692d97c3Snir.tzachar@gmail.com "Result:\n"
220692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
221692d97c3Snir.tzachar@gmail.com "Symbol: FOO [ = m]\n"
222692d97c3Snir.tzachar@gmail.com "Prompt: Foo bus is used to drive the bar HW\n"
223692d97c3Snir.tzachar@gmail.com "Defined at drivers/pci/Kconfig:47\n"
224692d97c3Snir.tzachar@gmail.com "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
225692d97c3Snir.tzachar@gmail.com "Location:\n"
226bb8187d3SPaul Gortmaker "  -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
227692d97c3Snir.tzachar@gmail.com "    -> PCI support (PCI [ = y])\n"
228692d97c3Snir.tzachar@gmail.com "      -> PCI access mode (<choice> [ = y])\n"
229692d97c3Snir.tzachar@gmail.com "Selects: LIBCRC32\n"
230692d97c3Snir.tzachar@gmail.com "Selected by: BAR\n"
231692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
232692d97c3Snir.tzachar@gmail.com "o The line 'Prompt:' shows the text used in the menu structure for\n"
23359dfa24dSArnaud Lacombe "  this symbol\n"
234692d97c3Snir.tzachar@gmail.com "o The 'Defined at' line tell at what file / line number the symbol\n"
235692d97c3Snir.tzachar@gmail.com "  is defined\n"
236692d97c3Snir.tzachar@gmail.com "o The 'Depends on:' line tell what symbols needs to be defined for\n"
237692d97c3Snir.tzachar@gmail.com "  this symbol to be visible in the menu (selectable)\n"
238692d97c3Snir.tzachar@gmail.com "o The 'Location:' lines tell where in the menu structure this symbol\n"
239692d97c3Snir.tzachar@gmail.com "  is located\n"
240692d97c3Snir.tzachar@gmail.com "    A location followed by a [ = y] indicate that this is a selectable\n"
241692d97c3Snir.tzachar@gmail.com "    menu item - and current value is displayed inside brackets.\n"
242692d97c3Snir.tzachar@gmail.com "o The 'Selects:' line tell what symbol will be automatically\n"
243692d97c3Snir.tzachar@gmail.com "  selected if this symbol is selected (y or m)\n"
244692d97c3Snir.tzachar@gmail.com "o The 'Selected by' line tell what symbol has selected this symbol\n"
245692d97c3Snir.tzachar@gmail.com "\n"
246692d97c3Snir.tzachar@gmail.com "Only relevant lines are shown.\n"
247692d97c3Snir.tzachar@gmail.com "\n\n"
248692d97c3Snir.tzachar@gmail.com "Search examples:\n"
24959dfa24dSArnaud Lacombe "Examples: USB  => find all symbols containing USB\n"
25059dfa24dSArnaud Lacombe "          ^USB => find all symbols starting with USB\n"
25159dfa24dSArnaud Lacombe "          USB$ => find all symbols ending with USB\n"
252692d97c3Snir.tzachar@gmail.com "\n");
253692d97c3Snir.tzachar@gmail.com 
254692d97c3Snir.tzachar@gmail.com struct mitem {
255692d97c3Snir.tzachar@gmail.com 	char str[256];
256692d97c3Snir.tzachar@gmail.com 	char tag;
257692d97c3Snir.tzachar@gmail.com 	void *usrptr;
258692d97c3Snir.tzachar@gmail.com 	int is_visible;
259692d97c3Snir.tzachar@gmail.com };
260692d97c3Snir.tzachar@gmail.com 
261692d97c3Snir.tzachar@gmail.com #define MAX_MENU_ITEMS 4096
262692d97c3Snir.tzachar@gmail.com static int show_all_items;
263692d97c3Snir.tzachar@gmail.com static int indent;
264692d97c3Snir.tzachar@gmail.com static struct menu *current_menu;
265692d97c3Snir.tzachar@gmail.com static int child_count;
266692d97c3Snir.tzachar@gmail.com static int single_menu_mode;
267692d97c3Snir.tzachar@gmail.com /* the window in which all information appears */
268692d97c3Snir.tzachar@gmail.com static WINDOW *main_window;
269692d97c3Snir.tzachar@gmail.com /* the largest size of the menu window */
270692d97c3Snir.tzachar@gmail.com static int mwin_max_lines;
271692d97c3Snir.tzachar@gmail.com static int mwin_max_cols;
272692d97c3Snir.tzachar@gmail.com /* the window in which we show option buttons */
273692d97c3Snir.tzachar@gmail.com static MENU *curses_menu;
274692d97c3Snir.tzachar@gmail.com static ITEM *curses_menu_items[MAX_MENU_ITEMS];
275692d97c3Snir.tzachar@gmail.com static struct mitem k_menu_items[MAX_MENU_ITEMS];
276692d97c3Snir.tzachar@gmail.com static int items_num;
277692d97c3Snir.tzachar@gmail.com static int global_exit;
278692d97c3Snir.tzachar@gmail.com /* the currently selected button */
279692d97c3Snir.tzachar@gmail.com const char *current_instructions = menu_instructions;
280692d97c3Snir.tzachar@gmail.com 
2815ea9f64fSCheng Renquan static char *dialog_input_result;
2825ea9f64fSCheng Renquan static int dialog_input_result_len;
2835ea9f64fSCheng Renquan 
284692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu);
285692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu);
286692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu);
287692d97c3Snir.tzachar@gmail.com static void conf_load(void);
288692d97c3Snir.tzachar@gmail.com static void conf_save(void);
289692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu);
290692d97c3Snir.tzachar@gmail.com static int do_exit(void);
291692d97c3Snir.tzachar@gmail.com static void setup_windows(void);
292a72f3e2bSNir Tzachar static void search_conf(void);
293692d97c3Snir.tzachar@gmail.com 
294692d97c3Snir.tzachar@gmail.com typedef void (*function_key_handler_t)(int *key, struct menu *menu);
295692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item);
296692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item);
297692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item);
298692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item);
299692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item);
300692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item);
301692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item);
302692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item);
303a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item);
304692d97c3Snir.tzachar@gmail.com 
305692d97c3Snir.tzachar@gmail.com struct function_keys {
306692d97c3Snir.tzachar@gmail.com 	const char *key_str;
307692d97c3Snir.tzachar@gmail.com 	const char *func;
308692d97c3Snir.tzachar@gmail.com 	function_key key;
309692d97c3Snir.tzachar@gmail.com 	function_key_handler_t handler;
310692d97c3Snir.tzachar@gmail.com };
311692d97c3Snir.tzachar@gmail.com 
312a72f3e2bSNir Tzachar static const int function_keys_num = 9;
313692d97c3Snir.tzachar@gmail.com struct function_keys function_keys[] = {
314692d97c3Snir.tzachar@gmail.com 	{
315692d97c3Snir.tzachar@gmail.com 		.key_str = "F1",
316692d97c3Snir.tzachar@gmail.com 		.func = "Help",
317692d97c3Snir.tzachar@gmail.com 		.key = F_HELP,
318692d97c3Snir.tzachar@gmail.com 		.handler = handle_f1,
319692d97c3Snir.tzachar@gmail.com 	},
320692d97c3Snir.tzachar@gmail.com 	{
321692d97c3Snir.tzachar@gmail.com 		.key_str = "F2",
322a72f3e2bSNir Tzachar 		.func = "Sym Info",
323692d97c3Snir.tzachar@gmail.com 		.key = F_SYMBOL,
324692d97c3Snir.tzachar@gmail.com 		.handler = handle_f2,
325692d97c3Snir.tzachar@gmail.com 	},
326692d97c3Snir.tzachar@gmail.com 	{
327692d97c3Snir.tzachar@gmail.com 		.key_str = "F3",
328a72f3e2bSNir Tzachar 		.func = "Insts",
329692d97c3Snir.tzachar@gmail.com 		.key = F_INSTS,
330692d97c3Snir.tzachar@gmail.com 		.handler = handle_f3,
331692d97c3Snir.tzachar@gmail.com 	},
332692d97c3Snir.tzachar@gmail.com 	{
333692d97c3Snir.tzachar@gmail.com 		.key_str = "F4",
334692d97c3Snir.tzachar@gmail.com 		.func = "Config",
335692d97c3Snir.tzachar@gmail.com 		.key = F_CONF,
336692d97c3Snir.tzachar@gmail.com 		.handler = handle_f4,
337692d97c3Snir.tzachar@gmail.com 	},
338692d97c3Snir.tzachar@gmail.com 	{
339692d97c3Snir.tzachar@gmail.com 		.key_str = "F5",
340692d97c3Snir.tzachar@gmail.com 		.func = "Back",
341692d97c3Snir.tzachar@gmail.com 		.key = F_BACK,
342692d97c3Snir.tzachar@gmail.com 		.handler = handle_f5,
343692d97c3Snir.tzachar@gmail.com 	},
344692d97c3Snir.tzachar@gmail.com 	{
345692d97c3Snir.tzachar@gmail.com 		.key_str = "F6",
346692d97c3Snir.tzachar@gmail.com 		.func = "Save",
347692d97c3Snir.tzachar@gmail.com 		.key = F_SAVE,
348692d97c3Snir.tzachar@gmail.com 		.handler = handle_f6,
349692d97c3Snir.tzachar@gmail.com 	},
350692d97c3Snir.tzachar@gmail.com 	{
351692d97c3Snir.tzachar@gmail.com 		.key_str = "F7",
352692d97c3Snir.tzachar@gmail.com 		.func = "Load",
353692d97c3Snir.tzachar@gmail.com 		.key = F_LOAD,
354692d97c3Snir.tzachar@gmail.com 		.handler = handle_f7,
355692d97c3Snir.tzachar@gmail.com 	},
356692d97c3Snir.tzachar@gmail.com 	{
357692d97c3Snir.tzachar@gmail.com 		.key_str = "F8",
358a72f3e2bSNir Tzachar 		.func = "Sym Search",
359a72f3e2bSNir Tzachar 		.key = F_SEARCH,
360a72f3e2bSNir Tzachar 		.handler = handle_f8,
361a72f3e2bSNir Tzachar 	},
362a72f3e2bSNir Tzachar 	{
363a72f3e2bSNir Tzachar 		.key_str = "F9",
364692d97c3Snir.tzachar@gmail.com 		.func = "Exit",
365692d97c3Snir.tzachar@gmail.com 		.key = F_EXIT,
366a72f3e2bSNir Tzachar 		.handler = handle_f9,
367692d97c3Snir.tzachar@gmail.com 	},
368692d97c3Snir.tzachar@gmail.com };
369692d97c3Snir.tzachar@gmail.com 
370692d97c3Snir.tzachar@gmail.com static void print_function_line(void)
371692d97c3Snir.tzachar@gmail.com {
372692d97c3Snir.tzachar@gmail.com 	int i;
373692d97c3Snir.tzachar@gmail.com 	int offset = 1;
374692d97c3Snir.tzachar@gmail.com 	const int skip = 1;
375692d97c3Snir.tzachar@gmail.com 
376692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
37710175ba6SStephen Boyd 		(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
378692d97c3Snir.tzachar@gmail.com 		mvwprintw(main_window, LINES-3, offset,
379692d97c3Snir.tzachar@gmail.com 				"%s",
380692d97c3Snir.tzachar@gmail.com 				function_keys[i].key_str);
38110175ba6SStephen Boyd 		(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
382692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].key_str);
383692d97c3Snir.tzachar@gmail.com 		mvwprintw(main_window, LINES-3,
384692d97c3Snir.tzachar@gmail.com 				offset, "%s",
385692d97c3Snir.tzachar@gmail.com 				function_keys[i].func);
386692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].func) + skip;
387692d97c3Snir.tzachar@gmail.com 	}
38810175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[NORMAL]);
389692d97c3Snir.tzachar@gmail.com }
390692d97c3Snir.tzachar@gmail.com 
391692d97c3Snir.tzachar@gmail.com /* help */
392692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item)
393692d97c3Snir.tzachar@gmail.com {
394692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
395692d97c3Snir.tzachar@gmail.com 			_("README"), _(nconf_readme));
396692d97c3Snir.tzachar@gmail.com 	return;
397692d97c3Snir.tzachar@gmail.com }
398692d97c3Snir.tzachar@gmail.com 
399692d97c3Snir.tzachar@gmail.com /* symbole help */
400692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item)
401692d97c3Snir.tzachar@gmail.com {
402692d97c3Snir.tzachar@gmail.com 	show_help(current_item);
403692d97c3Snir.tzachar@gmail.com 	return;
404692d97c3Snir.tzachar@gmail.com }
405692d97c3Snir.tzachar@gmail.com 
406692d97c3Snir.tzachar@gmail.com /* instructions */
407692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item)
408692d97c3Snir.tzachar@gmail.com {
409692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
410692d97c3Snir.tzachar@gmail.com 			_("Instructions"),
411692d97c3Snir.tzachar@gmail.com 			_(current_instructions));
412692d97c3Snir.tzachar@gmail.com 	return;
413692d97c3Snir.tzachar@gmail.com }
414692d97c3Snir.tzachar@gmail.com 
415692d97c3Snir.tzachar@gmail.com /* config */
416692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item)
417692d97c3Snir.tzachar@gmail.com {
418692d97c3Snir.tzachar@gmail.com 	int res = btn_dialog(main_window,
419692d97c3Snir.tzachar@gmail.com 			_("Show all symbols?"),
420692d97c3Snir.tzachar@gmail.com 			2,
421692d97c3Snir.tzachar@gmail.com 			"   <Show All>   ",
422692d97c3Snir.tzachar@gmail.com 			"<Don't show all>");
423692d97c3Snir.tzachar@gmail.com 	if (res == 0)
424692d97c3Snir.tzachar@gmail.com 		show_all_items = 1;
425692d97c3Snir.tzachar@gmail.com 	else if (res == 1)
426692d97c3Snir.tzachar@gmail.com 		show_all_items = 0;
427692d97c3Snir.tzachar@gmail.com 
428692d97c3Snir.tzachar@gmail.com 	return;
429692d97c3Snir.tzachar@gmail.com }
430692d97c3Snir.tzachar@gmail.com 
431692d97c3Snir.tzachar@gmail.com /* back */
432692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item)
433692d97c3Snir.tzachar@gmail.com {
434692d97c3Snir.tzachar@gmail.com 	*key = KEY_LEFT;
435692d97c3Snir.tzachar@gmail.com 	return;
436692d97c3Snir.tzachar@gmail.com }
437692d97c3Snir.tzachar@gmail.com 
438692d97c3Snir.tzachar@gmail.com /* save */
439692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item)
440692d97c3Snir.tzachar@gmail.com {
441692d97c3Snir.tzachar@gmail.com 	conf_save();
442692d97c3Snir.tzachar@gmail.com 	return;
443692d97c3Snir.tzachar@gmail.com }
444692d97c3Snir.tzachar@gmail.com 
445692d97c3Snir.tzachar@gmail.com /* load */
446692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item)
447692d97c3Snir.tzachar@gmail.com {
448692d97c3Snir.tzachar@gmail.com 	conf_load();
449692d97c3Snir.tzachar@gmail.com 	return;
450692d97c3Snir.tzachar@gmail.com }
451692d97c3Snir.tzachar@gmail.com 
452a72f3e2bSNir Tzachar /* search */
453692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item)
454692d97c3Snir.tzachar@gmail.com {
455a72f3e2bSNir Tzachar 	search_conf();
456a72f3e2bSNir Tzachar 	return;
457a72f3e2bSNir Tzachar }
458a72f3e2bSNir Tzachar 
459a72f3e2bSNir Tzachar /* exit */
460a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item)
461a72f3e2bSNir Tzachar {
462692d97c3Snir.tzachar@gmail.com 	do_exit();
463692d97c3Snir.tzachar@gmail.com 	return;
464692d97c3Snir.tzachar@gmail.com }
465692d97c3Snir.tzachar@gmail.com 
466692d97c3Snir.tzachar@gmail.com /* return != 0 to indicate the key was handles */
467851190c9SMichal Marek static int process_special_keys(int *key, struct menu *menu)
468692d97c3Snir.tzachar@gmail.com {
469692d97c3Snir.tzachar@gmail.com 	int i;
470692d97c3Snir.tzachar@gmail.com 
471692d97c3Snir.tzachar@gmail.com 	if (*key == KEY_RESIZE) {
472692d97c3Snir.tzachar@gmail.com 		setup_windows();
473692d97c3Snir.tzachar@gmail.com 		return 1;
474692d97c3Snir.tzachar@gmail.com 	}
475692d97c3Snir.tzachar@gmail.com 
476692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
477692d97c3Snir.tzachar@gmail.com 		if (*key == KEY_F(function_keys[i].key) ||
478692d97c3Snir.tzachar@gmail.com 		    *key == '0' + function_keys[i].key){
479692d97c3Snir.tzachar@gmail.com 			function_keys[i].handler(key, menu);
480692d97c3Snir.tzachar@gmail.com 			return 1;
481692d97c3Snir.tzachar@gmail.com 		}
482692d97c3Snir.tzachar@gmail.com 	}
483692d97c3Snir.tzachar@gmail.com 
484692d97c3Snir.tzachar@gmail.com 	return 0;
485692d97c3Snir.tzachar@gmail.com }
486692d97c3Snir.tzachar@gmail.com 
487692d97c3Snir.tzachar@gmail.com static void clean_items(void)
488692d97c3Snir.tzachar@gmail.com {
489692d97c3Snir.tzachar@gmail.com 	int i;
490692d97c3Snir.tzachar@gmail.com 	for (i = 0; curses_menu_items[i]; i++)
491692d97c3Snir.tzachar@gmail.com 		free_item(curses_menu_items[i]);
492692d97c3Snir.tzachar@gmail.com 	bzero(curses_menu_items, sizeof(curses_menu_items));
493692d97c3Snir.tzachar@gmail.com 	bzero(k_menu_items, sizeof(k_menu_items));
494692d97c3Snir.tzachar@gmail.com 	items_num = 0;
495692d97c3Snir.tzachar@gmail.com }
496692d97c3Snir.tzachar@gmail.com 
497a72f3e2bSNir Tzachar typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
498a72f3e2bSNir Tzachar 	FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
499692d97c3Snir.tzachar@gmail.com 
500a72f3e2bSNir Tzachar /* return the index of the matched item, or -1 if no such item exists */
501a72f3e2bSNir Tzachar static int get_mext_match(const char *match_str, match_f flag)
502a72f3e2bSNir Tzachar {
503a72f3e2bSNir Tzachar 	int match_start = item_index(current_item(curses_menu));
504a72f3e2bSNir Tzachar 	int index;
505a72f3e2bSNir Tzachar 
506a72f3e2bSNir Tzachar 	if (flag == FIND_NEXT_MATCH_DOWN)
507a72f3e2bSNir Tzachar 		++match_start;
508a72f3e2bSNir Tzachar 	else if (flag == FIND_NEXT_MATCH_UP)
509a72f3e2bSNir Tzachar 		--match_start;
510a72f3e2bSNir Tzachar 
511a72f3e2bSNir Tzachar 	index = match_start;
512a72f3e2bSNir Tzachar 	index = (index + items_num) % items_num;
513a72f3e2bSNir Tzachar 	while (true) {
514a72f3e2bSNir Tzachar 		char *str = k_menu_items[index].str;
515a72f3e2bSNir Tzachar 		if (strcasestr(str, match_str) != 0)
516a72f3e2bSNir Tzachar 			return index;
517a72f3e2bSNir Tzachar 		if (flag == FIND_NEXT_MATCH_UP ||
518a72f3e2bSNir Tzachar 		    flag == MATCH_TINKER_PATTERN_UP)
519a72f3e2bSNir Tzachar 			--index;
520a72f3e2bSNir Tzachar 		else
521a72f3e2bSNir Tzachar 			++index;
522a72f3e2bSNir Tzachar 		index = (index + items_num) % items_num;
523a72f3e2bSNir Tzachar 		if (index == match_start)
524692d97c3Snir.tzachar@gmail.com 			return -1;
525692d97c3Snir.tzachar@gmail.com 	}
526692d97c3Snir.tzachar@gmail.com }
527692d97c3Snir.tzachar@gmail.com 
528a72f3e2bSNir Tzachar /* Make a new item. */
529851190c9SMichal Marek static void item_make(struct menu *menu, char tag, const char *fmt, ...)
530692d97c3Snir.tzachar@gmail.com {
531692d97c3Snir.tzachar@gmail.com 	va_list ap;
532692d97c3Snir.tzachar@gmail.com 
533692d97c3Snir.tzachar@gmail.com 	if (items_num > MAX_MENU_ITEMS-1)
534692d97c3Snir.tzachar@gmail.com 		return;
535692d97c3Snir.tzachar@gmail.com 
536692d97c3Snir.tzachar@gmail.com 	bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
537692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].tag = tag;
538692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].usrptr = menu;
539692d97c3Snir.tzachar@gmail.com 	if (menu != NULL)
540692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible =
541692d97c3Snir.tzachar@gmail.com 			menu_is_visible(menu);
542692d97c3Snir.tzachar@gmail.com 	else
543692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible = 1;
544692d97c3Snir.tzachar@gmail.com 
545692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
546a72f3e2bSNir Tzachar 	vsnprintf(k_menu_items[items_num].str,
547a72f3e2bSNir Tzachar 		  sizeof(k_menu_items[items_num].str),
548a72f3e2bSNir Tzachar 		  fmt, ap);
549692d97c3Snir.tzachar@gmail.com 	va_end(ap);
550a72f3e2bSNir Tzachar 
551a72f3e2bSNir Tzachar 	if (!k_menu_items[items_num].is_visible)
552a72f3e2bSNir Tzachar 		memcpy(k_menu_items[items_num].str, "XXX", 3);
553692d97c3Snir.tzachar@gmail.com 
554692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = new_item(
555692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str,
556692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str);
557692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[items_num],
558692d97c3Snir.tzachar@gmail.com 			&k_menu_items[items_num]);
559692d97c3Snir.tzachar@gmail.com 	/*
560692d97c3Snir.tzachar@gmail.com 	if (!k_menu_items[items_num].is_visible)
561692d97c3Snir.tzachar@gmail.com 		item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
562692d97c3Snir.tzachar@gmail.com 	*/
563692d97c3Snir.tzachar@gmail.com 
564692d97c3Snir.tzachar@gmail.com 	items_num++;
565692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = NULL;
566692d97c3Snir.tzachar@gmail.com }
567692d97c3Snir.tzachar@gmail.com 
568692d97c3Snir.tzachar@gmail.com /* very hackish. adds a string to the last item added */
569851190c9SMichal Marek static void item_add_str(const char *fmt, ...)
570692d97c3Snir.tzachar@gmail.com {
571692d97c3Snir.tzachar@gmail.com 	va_list ap;
572692d97c3Snir.tzachar@gmail.com 	int index = items_num-1;
573692d97c3Snir.tzachar@gmail.com 	char new_str[256];
574692d97c3Snir.tzachar@gmail.com 	char tmp_str[256];
575692d97c3Snir.tzachar@gmail.com 
576692d97c3Snir.tzachar@gmail.com 	if (index < 0)
577692d97c3Snir.tzachar@gmail.com 		return;
578692d97c3Snir.tzachar@gmail.com 
579692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
580692d97c3Snir.tzachar@gmail.com 	vsnprintf(new_str, sizeof(new_str), fmt, ap);
581692d97c3Snir.tzachar@gmail.com 	va_end(ap);
582692d97c3Snir.tzachar@gmail.com 	snprintf(tmp_str, sizeof(tmp_str), "%s%s",
583692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str, new_str);
584692d97c3Snir.tzachar@gmail.com 	strncpy(k_menu_items[index].str,
585692d97c3Snir.tzachar@gmail.com 		tmp_str,
586692d97c3Snir.tzachar@gmail.com 		sizeof(k_menu_items[index].str));
587692d97c3Snir.tzachar@gmail.com 
588692d97c3Snir.tzachar@gmail.com 	free_item(curses_menu_items[index]);
589692d97c3Snir.tzachar@gmail.com 	curses_menu_items[index] = new_item(
590692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str,
591692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str);
592692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[index],
593692d97c3Snir.tzachar@gmail.com 			&k_menu_items[index]);
594692d97c3Snir.tzachar@gmail.com }
595692d97c3Snir.tzachar@gmail.com 
596692d97c3Snir.tzachar@gmail.com /* get the tag of the currently selected item */
597851190c9SMichal Marek static char item_tag(void)
598692d97c3Snir.tzachar@gmail.com {
599692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
600692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
601692d97c3Snir.tzachar@gmail.com 
602692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
603692d97c3Snir.tzachar@gmail.com 	if (cur == NULL)
604692d97c3Snir.tzachar@gmail.com 		return 0;
605692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
606692d97c3Snir.tzachar@gmail.com 	return mcur->tag;
607692d97c3Snir.tzachar@gmail.com }
608692d97c3Snir.tzachar@gmail.com 
609851190c9SMichal Marek static int curses_item_index(void)
610692d97c3Snir.tzachar@gmail.com {
611692d97c3Snir.tzachar@gmail.com 	return  item_index(current_item(curses_menu));
612692d97c3Snir.tzachar@gmail.com }
613692d97c3Snir.tzachar@gmail.com 
614851190c9SMichal Marek static void *item_data(void)
615692d97c3Snir.tzachar@gmail.com {
616692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
617692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
618692d97c3Snir.tzachar@gmail.com 
619692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
620866af407SAndrej Gelenberg 	if (!cur)
621866af407SAndrej Gelenberg 		return NULL;
622692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
623692d97c3Snir.tzachar@gmail.com 	return mcur->usrptr;
624692d97c3Snir.tzachar@gmail.com 
625692d97c3Snir.tzachar@gmail.com }
626692d97c3Snir.tzachar@gmail.com 
627851190c9SMichal Marek static int item_is_tag(char tag)
628692d97c3Snir.tzachar@gmail.com {
629692d97c3Snir.tzachar@gmail.com 	return item_tag() == tag;
630692d97c3Snir.tzachar@gmail.com }
631692d97c3Snir.tzachar@gmail.com 
632692d97c3Snir.tzachar@gmail.com static char filename[PATH_MAX+1];
633692d97c3Snir.tzachar@gmail.com static char menu_backtitle[PATH_MAX+128];
634851190c9SMichal Marek static const char *set_config_filename(const char *config_filename)
635692d97c3Snir.tzachar@gmail.com {
636692d97c3Snir.tzachar@gmail.com 	int size;
637692d97c3Snir.tzachar@gmail.com 
638692d97c3Snir.tzachar@gmail.com 	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
6390954828fSArnaud Lacombe 			"%s - %s", config_filename, rootmenu.prompt->text);
640692d97c3Snir.tzachar@gmail.com 	if (size >= sizeof(menu_backtitle))
641692d97c3Snir.tzachar@gmail.com 		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
642692d97c3Snir.tzachar@gmail.com 
643692d97c3Snir.tzachar@gmail.com 	size = snprintf(filename, sizeof(filename), "%s", config_filename);
644692d97c3Snir.tzachar@gmail.com 	if (size >= sizeof(filename))
645692d97c3Snir.tzachar@gmail.com 		filename[sizeof(filename)-1] = '\0';
646692d97c3Snir.tzachar@gmail.com 	return menu_backtitle;
647692d97c3Snir.tzachar@gmail.com }
648692d97c3Snir.tzachar@gmail.com 
649692d97c3Snir.tzachar@gmail.com /* return = 0 means we are successful.
650692d97c3Snir.tzachar@gmail.com  * -1 means go on doing what you were doing
651692d97c3Snir.tzachar@gmail.com  */
652692d97c3Snir.tzachar@gmail.com static int do_exit(void)
653692d97c3Snir.tzachar@gmail.com {
654692d97c3Snir.tzachar@gmail.com 	int res;
655692d97c3Snir.tzachar@gmail.com 	if (!conf_get_changed()) {
656692d97c3Snir.tzachar@gmail.com 		global_exit = 1;
657692d97c3Snir.tzachar@gmail.com 		return 0;
658692d97c3Snir.tzachar@gmail.com 	}
659692d97c3Snir.tzachar@gmail.com 	res = btn_dialog(main_window,
660652cf982SArnaud Lacombe 			_("Do you wish to save your new configuration?\n"
661692d97c3Snir.tzachar@gmail.com 				"<ESC> to cancel and resume nconfig."),
662692d97c3Snir.tzachar@gmail.com 			2,
663692d97c3Snir.tzachar@gmail.com 			"   <save>   ",
664692d97c3Snir.tzachar@gmail.com 			"<don't save>");
665692d97c3Snir.tzachar@gmail.com 	if (res == KEY_EXIT) {
666692d97c3Snir.tzachar@gmail.com 		global_exit = 0;
667692d97c3Snir.tzachar@gmail.com 		return -1;
668692d97c3Snir.tzachar@gmail.com 	}
669692d97c3Snir.tzachar@gmail.com 
670692d97c3Snir.tzachar@gmail.com 	/* if we got here, the user really wants to exit */
671692d97c3Snir.tzachar@gmail.com 	switch (res) {
672692d97c3Snir.tzachar@gmail.com 	case 0:
673692d97c3Snir.tzachar@gmail.com 		res = conf_write(filename);
674692d97c3Snir.tzachar@gmail.com 		if (res)
675692d97c3Snir.tzachar@gmail.com 			btn_dialog(
676692d97c3Snir.tzachar@gmail.com 				main_window,
677652cf982SArnaud Lacombe 				_("Error during writing of configuration.\n"
678652cf982SArnaud Lacombe 				  "Your configuration changes were NOT saved."),
679692d97c3Snir.tzachar@gmail.com 				  1,
680692d97c3Snir.tzachar@gmail.com 				  "<OK>");
681692d97c3Snir.tzachar@gmail.com 		break;
682692d97c3Snir.tzachar@gmail.com 	default:
683692d97c3Snir.tzachar@gmail.com 		btn_dialog(
684692d97c3Snir.tzachar@gmail.com 			main_window,
685652cf982SArnaud Lacombe 			_("Your configuration changes were NOT saved."),
686692d97c3Snir.tzachar@gmail.com 			1,
687692d97c3Snir.tzachar@gmail.com 			"<OK>");
688692d97c3Snir.tzachar@gmail.com 		break;
689692d97c3Snir.tzachar@gmail.com 	}
690692d97c3Snir.tzachar@gmail.com 	global_exit = 1;
691692d97c3Snir.tzachar@gmail.com 	return 0;
692692d97c3Snir.tzachar@gmail.com }
693692d97c3Snir.tzachar@gmail.com 
694692d97c3Snir.tzachar@gmail.com 
695692d97c3Snir.tzachar@gmail.com static void search_conf(void)
696692d97c3Snir.tzachar@gmail.com {
697692d97c3Snir.tzachar@gmail.com 	struct symbol **sym_arr;
698692d97c3Snir.tzachar@gmail.com 	struct gstr res;
699692d97c3Snir.tzachar@gmail.com 	char *dialog_input;
700692d97c3Snir.tzachar@gmail.com 	int dres;
701692d97c3Snir.tzachar@gmail.com again:
702692d97c3Snir.tzachar@gmail.com 	dres = dialog_inputbox(main_window,
703692d97c3Snir.tzachar@gmail.com 			_("Search Configuration Parameter"),
704ffb5957bSArnaud Lacombe 			_("Enter " CONFIG_ " (sub)string to search for "
705ffb5957bSArnaud Lacombe 				"(with or without \"" CONFIG_ "\")"),
7065ea9f64fSCheng Renquan 			"", &dialog_input_result, &dialog_input_result_len);
707692d97c3Snir.tzachar@gmail.com 	switch (dres) {
708692d97c3Snir.tzachar@gmail.com 	case 0:
709692d97c3Snir.tzachar@gmail.com 		break;
710692d97c3Snir.tzachar@gmail.com 	case 1:
711692d97c3Snir.tzachar@gmail.com 		show_scroll_win(main_window,
712692d97c3Snir.tzachar@gmail.com 				_("Search Configuration"), search_help);
713692d97c3Snir.tzachar@gmail.com 		goto again;
714692d97c3Snir.tzachar@gmail.com 	default:
715692d97c3Snir.tzachar@gmail.com 		return;
716692d97c3Snir.tzachar@gmail.com 	}
717692d97c3Snir.tzachar@gmail.com 
718ffb5957bSArnaud Lacombe 	/* strip the prefix if necessary */
719692d97c3Snir.tzachar@gmail.com 	dialog_input = dialog_input_result;
720ffb5957bSArnaud Lacombe 	if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
721ffb5957bSArnaud Lacombe 		dialog_input += strlen(CONFIG_);
722692d97c3Snir.tzachar@gmail.com 
723692d97c3Snir.tzachar@gmail.com 	sym_arr = sym_re_search(dialog_input);
724*5e609addSBenjamin Poirier 	res = get_relations_str(sym_arr, NULL);
725692d97c3Snir.tzachar@gmail.com 	free(sym_arr);
726692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
727692d97c3Snir.tzachar@gmail.com 			_("Search Results"), str_get(&res));
728692d97c3Snir.tzachar@gmail.com 	str_free(&res);
729692d97c3Snir.tzachar@gmail.com }
730692d97c3Snir.tzachar@gmail.com 
731692d97c3Snir.tzachar@gmail.com 
732692d97c3Snir.tzachar@gmail.com static void build_conf(struct menu *menu)
733692d97c3Snir.tzachar@gmail.com {
734692d97c3Snir.tzachar@gmail.com 	struct symbol *sym;
735692d97c3Snir.tzachar@gmail.com 	struct property *prop;
736692d97c3Snir.tzachar@gmail.com 	struct menu *child;
737692d97c3Snir.tzachar@gmail.com 	int type, tmp, doint = 2;
738692d97c3Snir.tzachar@gmail.com 	tristate val;
739692d97c3Snir.tzachar@gmail.com 	char ch;
740692d97c3Snir.tzachar@gmail.com 
741692d97c3Snir.tzachar@gmail.com 	if (!menu || (!show_all_items && !menu_is_visible(menu)))
742692d97c3Snir.tzachar@gmail.com 		return;
743692d97c3Snir.tzachar@gmail.com 
744692d97c3Snir.tzachar@gmail.com 	sym = menu->sym;
745692d97c3Snir.tzachar@gmail.com 	prop = menu->prompt;
746692d97c3Snir.tzachar@gmail.com 	if (!sym) {
747692d97c3Snir.tzachar@gmail.com 		if (prop && menu != current_menu) {
748692d97c3Snir.tzachar@gmail.com 			const char *prompt = menu_get_prompt(menu);
749692d97c3Snir.tzachar@gmail.com 			enum prop_type ptype;
750692d97c3Snir.tzachar@gmail.com 			ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
751692d97c3Snir.tzachar@gmail.com 			switch (ptype) {
752692d97c3Snir.tzachar@gmail.com 			case P_MENU:
753692d97c3Snir.tzachar@gmail.com 				child_count++;
754692d97c3Snir.tzachar@gmail.com 				prompt = _(prompt);
755692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode) {
756692d97c3Snir.tzachar@gmail.com 					item_make(menu, 'm',
757692d97c3Snir.tzachar@gmail.com 						"%s%*c%s",
758692d97c3Snir.tzachar@gmail.com 						menu->data ? "-->" : "++>",
759692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ', prompt);
760692d97c3Snir.tzachar@gmail.com 				} else
761692d97c3Snir.tzachar@gmail.com 					item_make(menu, 'm',
762692d97c3Snir.tzachar@gmail.com 						"   %*c%s  --->",
763692d97c3Snir.tzachar@gmail.com 						indent + 1,
764692d97c3Snir.tzachar@gmail.com 						' ', prompt);
765692d97c3Snir.tzachar@gmail.com 
766692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode && menu->data)
767692d97c3Snir.tzachar@gmail.com 					goto conf_childs;
768692d97c3Snir.tzachar@gmail.com 				return;
769692d97c3Snir.tzachar@gmail.com 			case P_COMMENT:
770692d97c3Snir.tzachar@gmail.com 				if (prompt) {
771692d97c3Snir.tzachar@gmail.com 					child_count++;
772692d97c3Snir.tzachar@gmail.com 					item_make(menu, ':',
773692d97c3Snir.tzachar@gmail.com 						"   %*c*** %s ***",
774692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ',
775692d97c3Snir.tzachar@gmail.com 						_(prompt));
776692d97c3Snir.tzachar@gmail.com 				}
777692d97c3Snir.tzachar@gmail.com 				break;
778692d97c3Snir.tzachar@gmail.com 			default:
779692d97c3Snir.tzachar@gmail.com 				if (prompt) {
780692d97c3Snir.tzachar@gmail.com 					child_count++;
781692d97c3Snir.tzachar@gmail.com 					item_make(menu, ':', "---%*c%s",
782692d97c3Snir.tzachar@gmail.com 						indent + 1, ' ',
783692d97c3Snir.tzachar@gmail.com 						_(prompt));
784692d97c3Snir.tzachar@gmail.com 				}
785692d97c3Snir.tzachar@gmail.com 			}
786692d97c3Snir.tzachar@gmail.com 		} else
787692d97c3Snir.tzachar@gmail.com 			doint = 0;
788692d97c3Snir.tzachar@gmail.com 		goto conf_childs;
789692d97c3Snir.tzachar@gmail.com 	}
790692d97c3Snir.tzachar@gmail.com 
791692d97c3Snir.tzachar@gmail.com 	type = sym_get_type(sym);
792692d97c3Snir.tzachar@gmail.com 	if (sym_is_choice(sym)) {
793692d97c3Snir.tzachar@gmail.com 		struct symbol *def_sym = sym_get_choice_value(sym);
794692d97c3Snir.tzachar@gmail.com 		struct menu *def_menu = NULL;
795692d97c3Snir.tzachar@gmail.com 
796692d97c3Snir.tzachar@gmail.com 		child_count++;
797692d97c3Snir.tzachar@gmail.com 		for (child = menu->list; child; child = child->next) {
798692d97c3Snir.tzachar@gmail.com 			if (menu_is_visible(child) && child->sym == def_sym)
799692d97c3Snir.tzachar@gmail.com 				def_menu = child;
800692d97c3Snir.tzachar@gmail.com 		}
801692d97c3Snir.tzachar@gmail.com 
802692d97c3Snir.tzachar@gmail.com 		val = sym_get_tristate_value(sym);
803692d97c3Snir.tzachar@gmail.com 		if (sym_is_changable(sym)) {
804692d97c3Snir.tzachar@gmail.com 			switch (type) {
805692d97c3Snir.tzachar@gmail.com 			case S_BOOLEAN:
806692d97c3Snir.tzachar@gmail.com 				item_make(menu, 't', "[%c]",
807692d97c3Snir.tzachar@gmail.com 						val == no ? ' ' : '*');
808692d97c3Snir.tzachar@gmail.com 				break;
809692d97c3Snir.tzachar@gmail.com 			case S_TRISTATE:
810692d97c3Snir.tzachar@gmail.com 				switch (val) {
811692d97c3Snir.tzachar@gmail.com 				case yes:
812692d97c3Snir.tzachar@gmail.com 					ch = '*';
813692d97c3Snir.tzachar@gmail.com 					break;
814692d97c3Snir.tzachar@gmail.com 				case mod:
815692d97c3Snir.tzachar@gmail.com 					ch = 'M';
816692d97c3Snir.tzachar@gmail.com 					break;
817692d97c3Snir.tzachar@gmail.com 				default:
818692d97c3Snir.tzachar@gmail.com 					ch = ' ';
819692d97c3Snir.tzachar@gmail.com 					break;
820692d97c3Snir.tzachar@gmail.com 				}
821692d97c3Snir.tzachar@gmail.com 				item_make(menu, 't', "<%c>", ch);
822692d97c3Snir.tzachar@gmail.com 				break;
823692d97c3Snir.tzachar@gmail.com 			}
824692d97c3Snir.tzachar@gmail.com 		} else {
825692d97c3Snir.tzachar@gmail.com 			item_make(menu, def_menu ? 't' : ':', "   ");
826692d97c3Snir.tzachar@gmail.com 		}
827692d97c3Snir.tzachar@gmail.com 
828692d97c3Snir.tzachar@gmail.com 		item_add_str("%*c%s", indent + 1,
829692d97c3Snir.tzachar@gmail.com 				' ', _(menu_get_prompt(menu)));
830692d97c3Snir.tzachar@gmail.com 		if (val == yes) {
831692d97c3Snir.tzachar@gmail.com 			if (def_menu) {
832692d97c3Snir.tzachar@gmail.com 				item_add_str(" (%s)",
833692d97c3Snir.tzachar@gmail.com 					_(menu_get_prompt(def_menu)));
834692d97c3Snir.tzachar@gmail.com 				item_add_str("  --->");
835692d97c3Snir.tzachar@gmail.com 				if (def_menu->list) {
836692d97c3Snir.tzachar@gmail.com 					indent += 2;
837692d97c3Snir.tzachar@gmail.com 					build_conf(def_menu);
838692d97c3Snir.tzachar@gmail.com 					indent -= 2;
839692d97c3Snir.tzachar@gmail.com 				}
840692d97c3Snir.tzachar@gmail.com 			}
841692d97c3Snir.tzachar@gmail.com 			return;
842692d97c3Snir.tzachar@gmail.com 		}
843692d97c3Snir.tzachar@gmail.com 	} else {
844692d97c3Snir.tzachar@gmail.com 		if (menu == current_menu) {
845692d97c3Snir.tzachar@gmail.com 			item_make(menu, ':',
846692d97c3Snir.tzachar@gmail.com 				"---%*c%s", indent + 1,
847692d97c3Snir.tzachar@gmail.com 				' ', _(menu_get_prompt(menu)));
848692d97c3Snir.tzachar@gmail.com 			goto conf_childs;
849692d97c3Snir.tzachar@gmail.com 		}
850692d97c3Snir.tzachar@gmail.com 		child_count++;
851692d97c3Snir.tzachar@gmail.com 		val = sym_get_tristate_value(sym);
852692d97c3Snir.tzachar@gmail.com 		if (sym_is_choice_value(sym) && val == yes) {
853692d97c3Snir.tzachar@gmail.com 			item_make(menu, ':', "   ");
854692d97c3Snir.tzachar@gmail.com 		} else {
855692d97c3Snir.tzachar@gmail.com 			switch (type) {
856692d97c3Snir.tzachar@gmail.com 			case S_BOOLEAN:
857692d97c3Snir.tzachar@gmail.com 				if (sym_is_changable(sym))
858692d97c3Snir.tzachar@gmail.com 					item_make(menu, 't', "[%c]",
859692d97c3Snir.tzachar@gmail.com 						val == no ? ' ' : '*');
860692d97c3Snir.tzachar@gmail.com 				else
861692d97c3Snir.tzachar@gmail.com 					item_make(menu, 't', "-%c-",
862692d97c3Snir.tzachar@gmail.com 						val == no ? ' ' : '*');
863692d97c3Snir.tzachar@gmail.com 				break;
864692d97c3Snir.tzachar@gmail.com 			case S_TRISTATE:
865692d97c3Snir.tzachar@gmail.com 				switch (val) {
866692d97c3Snir.tzachar@gmail.com 				case yes:
867692d97c3Snir.tzachar@gmail.com 					ch = '*';
868692d97c3Snir.tzachar@gmail.com 					break;
869692d97c3Snir.tzachar@gmail.com 				case mod:
870692d97c3Snir.tzachar@gmail.com 					ch = 'M';
871692d97c3Snir.tzachar@gmail.com 					break;
872692d97c3Snir.tzachar@gmail.com 				default:
873692d97c3Snir.tzachar@gmail.com 					ch = ' ';
874692d97c3Snir.tzachar@gmail.com 					break;
875692d97c3Snir.tzachar@gmail.com 				}
876692d97c3Snir.tzachar@gmail.com 				if (sym_is_changable(sym)) {
877692d97c3Snir.tzachar@gmail.com 					if (sym->rev_dep.tri == mod)
878692d97c3Snir.tzachar@gmail.com 						item_make(menu,
879692d97c3Snir.tzachar@gmail.com 							't', "{%c}", ch);
880692d97c3Snir.tzachar@gmail.com 					else
881692d97c3Snir.tzachar@gmail.com 						item_make(menu,
882692d97c3Snir.tzachar@gmail.com 							't', "<%c>", ch);
883692d97c3Snir.tzachar@gmail.com 				} else
884692d97c3Snir.tzachar@gmail.com 					item_make(menu, 't', "-%c-", ch);
885692d97c3Snir.tzachar@gmail.com 				break;
886692d97c3Snir.tzachar@gmail.com 			default:
887692d97c3Snir.tzachar@gmail.com 				tmp = 2 + strlen(sym_get_string_value(sym));
888692d97c3Snir.tzachar@gmail.com 				item_make(menu, 's', "    (%s)",
889692d97c3Snir.tzachar@gmail.com 						sym_get_string_value(sym));
890692d97c3Snir.tzachar@gmail.com 				tmp = indent - tmp + 4;
891692d97c3Snir.tzachar@gmail.com 				if (tmp < 0)
892692d97c3Snir.tzachar@gmail.com 					tmp = 0;
893692d97c3Snir.tzachar@gmail.com 				item_add_str("%*c%s%s", tmp, ' ',
894692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(menu)),
895692d97c3Snir.tzachar@gmail.com 						(sym_has_value(sym) ||
896692d97c3Snir.tzachar@gmail.com 						 !sym_is_changable(sym)) ? "" :
897692d97c3Snir.tzachar@gmail.com 						_(" (NEW)"));
898692d97c3Snir.tzachar@gmail.com 				goto conf_childs;
899692d97c3Snir.tzachar@gmail.com 			}
900692d97c3Snir.tzachar@gmail.com 		}
901692d97c3Snir.tzachar@gmail.com 		item_add_str("%*c%s%s", indent + 1, ' ',
902692d97c3Snir.tzachar@gmail.com 				_(menu_get_prompt(menu)),
903692d97c3Snir.tzachar@gmail.com 				(sym_has_value(sym) || !sym_is_changable(sym)) ?
904692d97c3Snir.tzachar@gmail.com 				"" : _(" (NEW)"));
905692d97c3Snir.tzachar@gmail.com 		if (menu->prompt && menu->prompt->type == P_MENU) {
906692d97c3Snir.tzachar@gmail.com 			item_add_str("  --->");
907692d97c3Snir.tzachar@gmail.com 			return;
908692d97c3Snir.tzachar@gmail.com 		}
909692d97c3Snir.tzachar@gmail.com 	}
910692d97c3Snir.tzachar@gmail.com 
911692d97c3Snir.tzachar@gmail.com conf_childs:
912692d97c3Snir.tzachar@gmail.com 	indent += doint;
913692d97c3Snir.tzachar@gmail.com 	for (child = menu->list; child; child = child->next)
914692d97c3Snir.tzachar@gmail.com 		build_conf(child);
915692d97c3Snir.tzachar@gmail.com 	indent -= doint;
916692d97c3Snir.tzachar@gmail.com }
917692d97c3Snir.tzachar@gmail.com 
918692d97c3Snir.tzachar@gmail.com static void reset_menu(void)
919692d97c3Snir.tzachar@gmail.com {
920692d97c3Snir.tzachar@gmail.com 	unpost_menu(curses_menu);
921692d97c3Snir.tzachar@gmail.com 	clean_items();
922692d97c3Snir.tzachar@gmail.com }
923692d97c3Snir.tzachar@gmail.com 
924692d97c3Snir.tzachar@gmail.com /* adjust the menu to show this item.
925692d97c3Snir.tzachar@gmail.com  * prefer not to scroll the menu if possible*/
926692d97c3Snir.tzachar@gmail.com static void center_item(int selected_index, int *last_top_row)
927692d97c3Snir.tzachar@gmail.com {
928692d97c3Snir.tzachar@gmail.com 	int toprow;
929692d97c3Snir.tzachar@gmail.com 
930692d97c3Snir.tzachar@gmail.com 	set_top_row(curses_menu, *last_top_row);
931692d97c3Snir.tzachar@gmail.com 	toprow = top_row(curses_menu);
932a72f3e2bSNir Tzachar 	if (selected_index < toprow ||
933a72f3e2bSNir Tzachar 	    selected_index >= toprow+mwin_max_lines) {
934a72f3e2bSNir Tzachar 		toprow = max(selected_index-mwin_max_lines/2, 0);
935a72f3e2bSNir Tzachar 		if (toprow >= item_count(curses_menu)-mwin_max_lines)
936692d97c3Snir.tzachar@gmail.com 			toprow = item_count(curses_menu)-mwin_max_lines;
937692d97c3Snir.tzachar@gmail.com 		set_top_row(curses_menu, toprow);
938a72f3e2bSNir Tzachar 	}
939692d97c3Snir.tzachar@gmail.com 	set_current_item(curses_menu,
940692d97c3Snir.tzachar@gmail.com 			curses_menu_items[selected_index]);
941692d97c3Snir.tzachar@gmail.com 	*last_top_row = toprow;
942692d97c3Snir.tzachar@gmail.com 	post_menu(curses_menu);
943692d97c3Snir.tzachar@gmail.com 	refresh_all_windows(main_window);
944692d97c3Snir.tzachar@gmail.com }
945692d97c3Snir.tzachar@gmail.com 
946692d97c3Snir.tzachar@gmail.com /* this function assumes reset_menu has been called before */
947692d97c3Snir.tzachar@gmail.com static void show_menu(const char *prompt, const char *instructions,
948692d97c3Snir.tzachar@gmail.com 		int selected_index, int *last_top_row)
949692d97c3Snir.tzachar@gmail.com {
950692d97c3Snir.tzachar@gmail.com 	int maxx, maxy;
951692d97c3Snir.tzachar@gmail.com 	WINDOW *menu_window;
952692d97c3Snir.tzachar@gmail.com 
953692d97c3Snir.tzachar@gmail.com 	current_instructions = instructions;
954692d97c3Snir.tzachar@gmail.com 
955692d97c3Snir.tzachar@gmail.com 	clear();
95610175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[NORMAL]);
957692d97c3Snir.tzachar@gmail.com 	print_in_middle(stdscr, 1, 0, COLS,
958692d97c3Snir.tzachar@gmail.com 			menu_backtitle,
959692d97c3Snir.tzachar@gmail.com 			attributes[MAIN_HEADING]);
960692d97c3Snir.tzachar@gmail.com 
96110175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
962692d97c3Snir.tzachar@gmail.com 	box(main_window, 0, 0);
96310175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
964692d97c3Snir.tzachar@gmail.com 	mvwprintw(main_window, 0, 3, " %s ", prompt);
96510175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[NORMAL]);
966692d97c3Snir.tzachar@gmail.com 
967692d97c3Snir.tzachar@gmail.com 	set_menu_items(curses_menu, curses_menu_items);
968692d97c3Snir.tzachar@gmail.com 
969692d97c3Snir.tzachar@gmail.com 	/* position the menu at the middle of the screen */
970692d97c3Snir.tzachar@gmail.com 	scale_menu(curses_menu, &maxy, &maxx);
97168c16eddSNir Tzachar 	maxx = min(maxx, mwin_max_cols-2);
972a72f3e2bSNir Tzachar 	maxy = mwin_max_lines;
973692d97c3Snir.tzachar@gmail.com 	menu_window = derwin(main_window,
974692d97c3Snir.tzachar@gmail.com 			maxy,
975692d97c3Snir.tzachar@gmail.com 			maxx,
976692d97c3Snir.tzachar@gmail.com 			2,
977692d97c3Snir.tzachar@gmail.com 			(mwin_max_cols-maxx)/2);
978692d97c3Snir.tzachar@gmail.com 	keypad(menu_window, TRUE);
979692d97c3Snir.tzachar@gmail.com 	set_menu_win(curses_menu, menu_window);
980692d97c3Snir.tzachar@gmail.com 	set_menu_sub(curses_menu, menu_window);
981692d97c3Snir.tzachar@gmail.com 
982692d97c3Snir.tzachar@gmail.com 	/* must reassert this after changing items, otherwise returns to a
983692d97c3Snir.tzachar@gmail.com 	 * default of 16
984692d97c3Snir.tzachar@gmail.com 	 */
985692d97c3Snir.tzachar@gmail.com 	set_menu_format(curses_menu, maxy, 1);
986692d97c3Snir.tzachar@gmail.com 	center_item(selected_index, last_top_row);
987692d97c3Snir.tzachar@gmail.com 	set_menu_format(curses_menu, maxy, 1);
988692d97c3Snir.tzachar@gmail.com 
989692d97c3Snir.tzachar@gmail.com 	print_function_line();
990692d97c3Snir.tzachar@gmail.com 
991692d97c3Snir.tzachar@gmail.com 	/* Post the menu */
992692d97c3Snir.tzachar@gmail.com 	post_menu(curses_menu);
993692d97c3Snir.tzachar@gmail.com 	refresh_all_windows(main_window);
994692d97c3Snir.tzachar@gmail.com }
995692d97c3Snir.tzachar@gmail.com 
996a72f3e2bSNir Tzachar static void adj_match_dir(match_f *match_direction)
997a72f3e2bSNir Tzachar {
998a72f3e2bSNir Tzachar 	if (*match_direction == FIND_NEXT_MATCH_DOWN)
999a72f3e2bSNir Tzachar 		*match_direction =
1000a72f3e2bSNir Tzachar 			MATCH_TINKER_PATTERN_DOWN;
1001a72f3e2bSNir Tzachar 	else if (*match_direction == FIND_NEXT_MATCH_UP)
1002a72f3e2bSNir Tzachar 		*match_direction =
1003a72f3e2bSNir Tzachar 			MATCH_TINKER_PATTERN_UP;
1004a72f3e2bSNir Tzachar 	/* else, do no change.. */
1005a72f3e2bSNir Tzachar }
1006a72f3e2bSNir Tzachar 
1007a72f3e2bSNir Tzachar struct match_state
1008a72f3e2bSNir Tzachar {
1009a72f3e2bSNir Tzachar 	int in_search;
1010a72f3e2bSNir Tzachar 	match_f match_direction;
1011a72f3e2bSNir Tzachar 	char pattern[256];
1012a72f3e2bSNir Tzachar };
1013a72f3e2bSNir Tzachar 
1014a72f3e2bSNir Tzachar /* Return 0 means I have handled the key. In such a case, ans should hold the
1015a72f3e2bSNir Tzachar  * item to center, or -1 otherwise.
1016a72f3e2bSNir Tzachar  * Else return -1 .
1017a72f3e2bSNir Tzachar  */
1018a72f3e2bSNir Tzachar static int do_match(int key, struct match_state *state, int *ans)
1019a72f3e2bSNir Tzachar {
1020a72f3e2bSNir Tzachar 	char c = (char) key;
1021a72f3e2bSNir Tzachar 	int terminate_search = 0;
1022a72f3e2bSNir Tzachar 	*ans = -1;
1023a72f3e2bSNir Tzachar 	if (key == '/' || (state->in_search && key == 27)) {
1024a72f3e2bSNir Tzachar 		move(0, 0);
1025a72f3e2bSNir Tzachar 		refresh();
1026a72f3e2bSNir Tzachar 		clrtoeol();
1027a72f3e2bSNir Tzachar 		state->in_search = 1-state->in_search;
1028a72f3e2bSNir Tzachar 		bzero(state->pattern, sizeof(state->pattern));
1029a72f3e2bSNir Tzachar 		state->match_direction = MATCH_TINKER_PATTERN_DOWN;
1030a72f3e2bSNir Tzachar 		return 0;
1031a72f3e2bSNir Tzachar 	} else if (!state->in_search)
1032a72f3e2bSNir Tzachar 		return 1;
1033a72f3e2bSNir Tzachar 
1034a72f3e2bSNir Tzachar 	if (isalnum(c) || isgraph(c) || c == ' ') {
1035a72f3e2bSNir Tzachar 		state->pattern[strlen(state->pattern)] = c;
1036a72f3e2bSNir Tzachar 		state->pattern[strlen(state->pattern)] = '\0';
1037a72f3e2bSNir Tzachar 		adj_match_dir(&state->match_direction);
1038a72f3e2bSNir Tzachar 		*ans = get_mext_match(state->pattern,
1039a72f3e2bSNir Tzachar 				state->match_direction);
1040a72f3e2bSNir Tzachar 	} else if (key == KEY_DOWN) {
1041a72f3e2bSNir Tzachar 		state->match_direction = FIND_NEXT_MATCH_DOWN;
1042a72f3e2bSNir Tzachar 		*ans = get_mext_match(state->pattern,
1043a72f3e2bSNir Tzachar 				state->match_direction);
1044a72f3e2bSNir Tzachar 	} else if (key == KEY_UP) {
1045a72f3e2bSNir Tzachar 		state->match_direction = FIND_NEXT_MATCH_UP;
1046a72f3e2bSNir Tzachar 		*ans = get_mext_match(state->pattern,
1047a72f3e2bSNir Tzachar 				state->match_direction);
1048a72f3e2bSNir Tzachar 	} else if (key == KEY_BACKSPACE || key == 127) {
1049a72f3e2bSNir Tzachar 		state->pattern[strlen(state->pattern)-1] = '\0';
1050a72f3e2bSNir Tzachar 		adj_match_dir(&state->match_direction);
1051a72f3e2bSNir Tzachar 	} else
1052a72f3e2bSNir Tzachar 		terminate_search = 1;
1053a72f3e2bSNir Tzachar 
1054a72f3e2bSNir Tzachar 	if (terminate_search) {
1055a72f3e2bSNir Tzachar 		state->in_search = 0;
1056a72f3e2bSNir Tzachar 		bzero(state->pattern, sizeof(state->pattern));
1057a72f3e2bSNir Tzachar 		move(0, 0);
1058a72f3e2bSNir Tzachar 		refresh();
1059a72f3e2bSNir Tzachar 		clrtoeol();
1060a72f3e2bSNir Tzachar 		return -1;
1061a72f3e2bSNir Tzachar 	}
1062a72f3e2bSNir Tzachar 	return 0;
1063a72f3e2bSNir Tzachar }
1064692d97c3Snir.tzachar@gmail.com 
1065692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu)
1066692d97c3Snir.tzachar@gmail.com {
1067692d97c3Snir.tzachar@gmail.com 	struct menu *submenu = 0;
1068692d97c3Snir.tzachar@gmail.com 	const char *prompt = menu_get_prompt(menu);
1069692d97c3Snir.tzachar@gmail.com 	struct symbol *sym;
1070692d97c3Snir.tzachar@gmail.com 	int res;
1071692d97c3Snir.tzachar@gmail.com 	int current_index = 0;
1072692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1073a72f3e2bSNir Tzachar 	struct match_state match_state = {
1074a72f3e2bSNir Tzachar 		.in_search = 0,
1075a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1076a72f3e2bSNir Tzachar 		.pattern = "",
1077a72f3e2bSNir Tzachar 	};
1078692d97c3Snir.tzachar@gmail.com 
1079692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1080692d97c3Snir.tzachar@gmail.com 		reset_menu();
1081692d97c3Snir.tzachar@gmail.com 		current_menu = menu;
1082692d97c3Snir.tzachar@gmail.com 		build_conf(menu);
1083692d97c3Snir.tzachar@gmail.com 		if (!child_count)
1084692d97c3Snir.tzachar@gmail.com 			break;
1085692d97c3Snir.tzachar@gmail.com 
1086692d97c3Snir.tzachar@gmail.com 		show_menu(prompt ? _(prompt) : _("Main Menu"),
1087692d97c3Snir.tzachar@gmail.com 				_(menu_instructions),
1088692d97c3Snir.tzachar@gmail.com 				current_index, &last_top_row);
1089692d97c3Snir.tzachar@gmail.com 		keypad((menu_win(curses_menu)), TRUE);
1090a72f3e2bSNir Tzachar 		while (!global_exit) {
1091a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1092a72f3e2bSNir Tzachar 				mvprintw(0, 0,
1093a72f3e2bSNir Tzachar 					"searching: %s", match_state.pattern);
1094a72f3e2bSNir Tzachar 				clrtoeol();
1095a72f3e2bSNir Tzachar 			}
1096a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1097a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1098a72f3e2bSNir Tzachar 			if (!res)
1099a72f3e2bSNir Tzachar 				break;
1100a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &current_index) == 0) {
1101a72f3e2bSNir Tzachar 				if (current_index != -1)
1102a72f3e2bSNir Tzachar 					center_item(current_index,
1103a72f3e2bSNir Tzachar 						    &last_top_row);
1104a72f3e2bSNir Tzachar 				continue;
1105a72f3e2bSNir Tzachar 			}
1106692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(&res,
1107692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1108692d97c3Snir.tzachar@gmail.com 				break;
1109692d97c3Snir.tzachar@gmail.com 			switch (res) {
1110692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
1111692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1112692d97c3Snir.tzachar@gmail.com 				break;
1113692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
1114692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1115692d97c3Snir.tzachar@gmail.com 				break;
1116692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1117692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1118692d97c3Snir.tzachar@gmail.com 				break;
1119692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1120692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1121692d97c3Snir.tzachar@gmail.com 				break;
1122692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1123692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1124692d97c3Snir.tzachar@gmail.com 				break;
1125692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1126692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1127692d97c3Snir.tzachar@gmail.com 				break;
1128692d97c3Snir.tzachar@gmail.com 			case 'h':
1129692d97c3Snir.tzachar@gmail.com 			case '?':
1130692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1131692d97c3Snir.tzachar@gmail.com 				break;
1132692d97c3Snir.tzachar@gmail.com 			}
1133692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 ||
1134692d97c3Snir.tzachar@gmail.com 				res == 32 || res == 'n' || res == 'y' ||
1135692d97c3Snir.tzachar@gmail.com 				res == KEY_LEFT || res == KEY_RIGHT ||
1136a72f3e2bSNir Tzachar 				res == 'm')
1137692d97c3Snir.tzachar@gmail.com 				break;
1138692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1139692d97c3Snir.tzachar@gmail.com 		}
1140692d97c3Snir.tzachar@gmail.com 
1141692d97c3Snir.tzachar@gmail.com 		refresh_all_windows(main_window);
1142692d97c3Snir.tzachar@gmail.com 		/* if ESC or left*/
1143692d97c3Snir.tzachar@gmail.com 		if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1144692d97c3Snir.tzachar@gmail.com 			break;
1145692d97c3Snir.tzachar@gmail.com 
1146692d97c3Snir.tzachar@gmail.com 		/* remember location in the menu */
1147692d97c3Snir.tzachar@gmail.com 		last_top_row = top_row(curses_menu);
1148692d97c3Snir.tzachar@gmail.com 		current_index = curses_item_index();
1149692d97c3Snir.tzachar@gmail.com 
1150692d97c3Snir.tzachar@gmail.com 		if (!item_tag())
1151692d97c3Snir.tzachar@gmail.com 			continue;
1152692d97c3Snir.tzachar@gmail.com 
1153692d97c3Snir.tzachar@gmail.com 		submenu = (struct menu *) item_data();
1154692d97c3Snir.tzachar@gmail.com 		if (!submenu || !menu_is_visible(submenu))
1155692d97c3Snir.tzachar@gmail.com 			continue;
1156692d97c3Snir.tzachar@gmail.com 		sym = submenu->sym;
1157692d97c3Snir.tzachar@gmail.com 
1158692d97c3Snir.tzachar@gmail.com 		switch (res) {
1159692d97c3Snir.tzachar@gmail.com 		case ' ':
1160692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1161692d97c3Snir.tzachar@gmail.com 				sym_toggle_tristate_value(sym);
1162692d97c3Snir.tzachar@gmail.com 			else if (item_is_tag('m'))
1163692d97c3Snir.tzachar@gmail.com 				conf(submenu);
1164692d97c3Snir.tzachar@gmail.com 			break;
1165692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1166692d97c3Snir.tzachar@gmail.com 		case 10: /* ENTER WAS PRESSED */
1167692d97c3Snir.tzachar@gmail.com 			switch (item_tag()) {
1168692d97c3Snir.tzachar@gmail.com 			case 'm':
1169692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode)
1170692d97c3Snir.tzachar@gmail.com 					submenu->data =
1171692d97c3Snir.tzachar@gmail.com 						(void *) (long) !submenu->data;
1172692d97c3Snir.tzachar@gmail.com 				else
1173692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1174692d97c3Snir.tzachar@gmail.com 				break;
1175692d97c3Snir.tzachar@gmail.com 			case 't':
1176692d97c3Snir.tzachar@gmail.com 				if (sym_is_choice(sym) &&
1177692d97c3Snir.tzachar@gmail.com 				    sym_get_tristate_value(sym) == yes)
1178692d97c3Snir.tzachar@gmail.com 					conf_choice(submenu);
1179692d97c3Snir.tzachar@gmail.com 				else if (submenu->prompt &&
1180692d97c3Snir.tzachar@gmail.com 					 submenu->prompt->type == P_MENU)
1181692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1182692d97c3Snir.tzachar@gmail.com 				else if (res == 10)
1183692d97c3Snir.tzachar@gmail.com 					sym_toggle_tristate_value(sym);
1184692d97c3Snir.tzachar@gmail.com 				break;
1185692d97c3Snir.tzachar@gmail.com 			case 's':
1186692d97c3Snir.tzachar@gmail.com 				conf_string(submenu);
1187692d97c3Snir.tzachar@gmail.com 				break;
1188692d97c3Snir.tzachar@gmail.com 			}
1189692d97c3Snir.tzachar@gmail.com 			break;
1190692d97c3Snir.tzachar@gmail.com 		case 'y':
1191692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t')) {
1192692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, yes))
1193692d97c3Snir.tzachar@gmail.com 					break;
1194692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, mod))
1195692d97c3Snir.tzachar@gmail.com 					btn_dialog(main_window, setmod_text, 0);
1196692d97c3Snir.tzachar@gmail.com 			}
1197692d97c3Snir.tzachar@gmail.com 			break;
1198692d97c3Snir.tzachar@gmail.com 		case 'n':
1199692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1200692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, no);
1201692d97c3Snir.tzachar@gmail.com 			break;
1202692d97c3Snir.tzachar@gmail.com 		case 'm':
1203692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1204692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, mod);
1205692d97c3Snir.tzachar@gmail.com 			break;
1206692d97c3Snir.tzachar@gmail.com 		}
1207692d97c3Snir.tzachar@gmail.com 	}
1208692d97c3Snir.tzachar@gmail.com }
1209692d97c3Snir.tzachar@gmail.com 
121042368c37SMichal Marek static void conf_message_callback(const char *fmt, va_list ap)
121142368c37SMichal Marek {
121242368c37SMichal Marek 	char buf[1024];
121342368c37SMichal Marek 
121442368c37SMichal Marek 	vsnprintf(buf, sizeof(buf), fmt, ap);
121542368c37SMichal Marek 	btn_dialog(main_window, buf, 1, "<OK>");
121642368c37SMichal Marek }
121742368c37SMichal Marek 
1218692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu)
1219692d97c3Snir.tzachar@gmail.com {
1220f98ee769SArnaud Lacombe 	struct gstr help;
1221f98ee769SArnaud Lacombe 
1222f98ee769SArnaud Lacombe 	if (!menu)
1223f98ee769SArnaud Lacombe 		return;
1224f98ee769SArnaud Lacombe 
1225f98ee769SArnaud Lacombe 	help = str_new();
122654168578SArnaud Lacombe 	menu_get_ext_help(menu, &help);
1227692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1228692d97c3Snir.tzachar@gmail.com 	str_free(&help);
1229692d97c3Snir.tzachar@gmail.com }
1230692d97c3Snir.tzachar@gmail.com 
1231692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu)
1232692d97c3Snir.tzachar@gmail.com {
1233692d97c3Snir.tzachar@gmail.com 	const char *prompt = _(menu_get_prompt(menu));
1234692d97c3Snir.tzachar@gmail.com 	struct menu *child = 0;
1235692d97c3Snir.tzachar@gmail.com 	struct symbol *active;
1236692d97c3Snir.tzachar@gmail.com 	int selected_index = 0;
1237692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1238692d97c3Snir.tzachar@gmail.com 	int res, i = 0;
1239a72f3e2bSNir Tzachar 	struct match_state match_state = {
1240a72f3e2bSNir Tzachar 		.in_search = 0,
1241a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1242a72f3e2bSNir Tzachar 		.pattern = "",
1243a72f3e2bSNir Tzachar 	};
1244692d97c3Snir.tzachar@gmail.com 
1245692d97c3Snir.tzachar@gmail.com 	active = sym_get_choice_value(menu->sym);
1246692d97c3Snir.tzachar@gmail.com 	/* this is mostly duplicated from the conf() function. */
1247692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1248692d97c3Snir.tzachar@gmail.com 		reset_menu();
1249692d97c3Snir.tzachar@gmail.com 
1250692d97c3Snir.tzachar@gmail.com 		for (i = 0, child = menu->list; child; child = child->next) {
1251692d97c3Snir.tzachar@gmail.com 			if (!show_all_items && !menu_is_visible(child))
1252692d97c3Snir.tzachar@gmail.com 				continue;
1253692d97c3Snir.tzachar@gmail.com 
1254692d97c3Snir.tzachar@gmail.com 			if (child->sym == sym_get_choice_value(menu->sym))
1255692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "<X> %s",
1256692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(child)));
125739177ec3SPeter Korsgaard 			else if (child->sym)
1258692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "    %s",
1259692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(child)));
126039177ec3SPeter Korsgaard 			else
126139177ec3SPeter Korsgaard 				item_make(child, ':', "*** %s ***",
126239177ec3SPeter Korsgaard 						_(menu_get_prompt(child)));
126339177ec3SPeter Korsgaard 
1264692d97c3Snir.tzachar@gmail.com 			if (child->sym == active){
1265692d97c3Snir.tzachar@gmail.com 				last_top_row = top_row(curses_menu);
1266692d97c3Snir.tzachar@gmail.com 				selected_index = i;
1267692d97c3Snir.tzachar@gmail.com 			}
1268692d97c3Snir.tzachar@gmail.com 			i++;
1269692d97c3Snir.tzachar@gmail.com 		}
1270692d97c3Snir.tzachar@gmail.com 		show_menu(prompt ? _(prompt) : _("Choice Menu"),
1271692d97c3Snir.tzachar@gmail.com 				_(radiolist_instructions),
1272692d97c3Snir.tzachar@gmail.com 				selected_index,
1273692d97c3Snir.tzachar@gmail.com 				&last_top_row);
1274a72f3e2bSNir Tzachar 		while (!global_exit) {
1275a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1276a72f3e2bSNir Tzachar 				mvprintw(0, 0, "searching: %s",
1277a72f3e2bSNir Tzachar 					 match_state.pattern);
1278a72f3e2bSNir Tzachar 				clrtoeol();
1279a72f3e2bSNir Tzachar 			}
1280a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1281a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1282a72f3e2bSNir Tzachar 			if (!res)
1283a72f3e2bSNir Tzachar 				break;
1284a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &selected_index) == 0) {
1285a72f3e2bSNir Tzachar 				if (selected_index != -1)
1286a72f3e2bSNir Tzachar 					center_item(selected_index,
1287a72f3e2bSNir Tzachar 						    &last_top_row);
1288a72f3e2bSNir Tzachar 				continue;
1289a72f3e2bSNir Tzachar 			}
1290692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(
1291692d97c3Snir.tzachar@gmail.com 						&res,
1292692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1293692d97c3Snir.tzachar@gmail.com 				break;
1294692d97c3Snir.tzachar@gmail.com 			switch (res) {
1295692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
1296692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1297692d97c3Snir.tzachar@gmail.com 				break;
1298692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
1299692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1300692d97c3Snir.tzachar@gmail.com 				break;
1301692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1302692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1303692d97c3Snir.tzachar@gmail.com 				break;
1304692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1305692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1306692d97c3Snir.tzachar@gmail.com 				break;
1307692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1308692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1309692d97c3Snir.tzachar@gmail.com 				break;
1310692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1311692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1312692d97c3Snir.tzachar@gmail.com 				break;
1313692d97c3Snir.tzachar@gmail.com 			case 'h':
1314692d97c3Snir.tzachar@gmail.com 			case '?':
1315692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1316692d97c3Snir.tzachar@gmail.com 				break;
1317692d97c3Snir.tzachar@gmail.com 			}
1318692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 || res == ' ' ||
1319a72f3e2bSNir Tzachar 					res == KEY_LEFT){
1320692d97c3Snir.tzachar@gmail.com 				break;
1321692d97c3Snir.tzachar@gmail.com 			}
1322692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1323692d97c3Snir.tzachar@gmail.com 		}
1324692d97c3Snir.tzachar@gmail.com 		/* if ESC or left */
1325692d97c3Snir.tzachar@gmail.com 		if (res == 27 || res == KEY_LEFT)
1326692d97c3Snir.tzachar@gmail.com 			break;
1327692d97c3Snir.tzachar@gmail.com 
1328692d97c3Snir.tzachar@gmail.com 		child = item_data();
132939177ec3SPeter Korsgaard 		if (!child || !menu_is_visible(child) || !child->sym)
1330692d97c3Snir.tzachar@gmail.com 			continue;
1331692d97c3Snir.tzachar@gmail.com 		switch (res) {
1332692d97c3Snir.tzachar@gmail.com 		case ' ':
1333692d97c3Snir.tzachar@gmail.com 		case  10:
1334692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1335692d97c3Snir.tzachar@gmail.com 			sym_set_tristate_value(child->sym, yes);
1336692d97c3Snir.tzachar@gmail.com 			return;
1337692d97c3Snir.tzachar@gmail.com 		case 'h':
1338692d97c3Snir.tzachar@gmail.com 		case '?':
1339692d97c3Snir.tzachar@gmail.com 			show_help(child);
1340692d97c3Snir.tzachar@gmail.com 			active = child->sym;
1341692d97c3Snir.tzachar@gmail.com 			break;
1342692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1343692d97c3Snir.tzachar@gmail.com 			return;
1344692d97c3Snir.tzachar@gmail.com 		}
1345692d97c3Snir.tzachar@gmail.com 	}
1346692d97c3Snir.tzachar@gmail.com }
1347692d97c3Snir.tzachar@gmail.com 
1348692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu)
1349692d97c3Snir.tzachar@gmail.com {
1350692d97c3Snir.tzachar@gmail.com 	const char *prompt = menu_get_prompt(menu);
1351692d97c3Snir.tzachar@gmail.com 
1352692d97c3Snir.tzachar@gmail.com 	while (1) {
1353692d97c3Snir.tzachar@gmail.com 		int res;
1354692d97c3Snir.tzachar@gmail.com 		const char *heading;
1355692d97c3Snir.tzachar@gmail.com 
1356692d97c3Snir.tzachar@gmail.com 		switch (sym_get_type(menu->sym)) {
1357692d97c3Snir.tzachar@gmail.com 		case S_INT:
1358692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_int);
1359692d97c3Snir.tzachar@gmail.com 			break;
1360692d97c3Snir.tzachar@gmail.com 		case S_HEX:
1361692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_hex);
1362692d97c3Snir.tzachar@gmail.com 			break;
1363692d97c3Snir.tzachar@gmail.com 		case S_STRING:
1364692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_string);
1365692d97c3Snir.tzachar@gmail.com 			break;
1366692d97c3Snir.tzachar@gmail.com 		default:
1367692d97c3Snir.tzachar@gmail.com 			heading = _("Internal nconf error!");
1368692d97c3Snir.tzachar@gmail.com 		}
1369692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1370692d97c3Snir.tzachar@gmail.com 				prompt ? _(prompt) : _("Main Menu"),
1371692d97c3Snir.tzachar@gmail.com 				heading,
1372692d97c3Snir.tzachar@gmail.com 				sym_get_string_value(menu->sym),
13735ea9f64fSCheng Renquan 				&dialog_input_result,
13745ea9f64fSCheng Renquan 				&dialog_input_result_len);
1375692d97c3Snir.tzachar@gmail.com 		switch (res) {
1376692d97c3Snir.tzachar@gmail.com 		case 0:
1377692d97c3Snir.tzachar@gmail.com 			if (sym_set_string_value(menu->sym,
1378692d97c3Snir.tzachar@gmail.com 						dialog_input_result))
1379692d97c3Snir.tzachar@gmail.com 				return;
1380692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window,
1381692d97c3Snir.tzachar@gmail.com 				_("You have made an invalid entry."), 0);
1382692d97c3Snir.tzachar@gmail.com 			break;
1383692d97c3Snir.tzachar@gmail.com 		case 1:
1384692d97c3Snir.tzachar@gmail.com 			show_help(menu);
1385692d97c3Snir.tzachar@gmail.com 			break;
1386692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1387692d97c3Snir.tzachar@gmail.com 			return;
1388692d97c3Snir.tzachar@gmail.com 		}
1389692d97c3Snir.tzachar@gmail.com 	}
1390692d97c3Snir.tzachar@gmail.com }
1391692d97c3Snir.tzachar@gmail.com 
1392692d97c3Snir.tzachar@gmail.com static void conf_load(void)
1393692d97c3Snir.tzachar@gmail.com {
1394692d97c3Snir.tzachar@gmail.com 	while (1) {
1395692d97c3Snir.tzachar@gmail.com 		int res;
1396692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1397692d97c3Snir.tzachar@gmail.com 				NULL, load_config_text,
1398692d97c3Snir.tzachar@gmail.com 				filename,
13995ea9f64fSCheng Renquan 				&dialog_input_result,
14005ea9f64fSCheng Renquan 				&dialog_input_result_len);
1401692d97c3Snir.tzachar@gmail.com 		switch (res) {
1402692d97c3Snir.tzachar@gmail.com 		case 0:
1403692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1404692d97c3Snir.tzachar@gmail.com 				return;
1405692d97c3Snir.tzachar@gmail.com 			if (!conf_read(dialog_input_result)) {
1406692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
1407692d97c3Snir.tzachar@gmail.com 				sym_set_change_count(1);
1408692d97c3Snir.tzachar@gmail.com 				return;
1409692d97c3Snir.tzachar@gmail.com 			}
1410692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window, _("File does not exist!"), 0);
1411692d97c3Snir.tzachar@gmail.com 			break;
1412692d97c3Snir.tzachar@gmail.com 		case 1:
1413692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1414692d97c3Snir.tzachar@gmail.com 					_("Load Alternate Configuration"),
1415692d97c3Snir.tzachar@gmail.com 					load_config_help);
1416692d97c3Snir.tzachar@gmail.com 			break;
1417692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1418692d97c3Snir.tzachar@gmail.com 			return;
1419692d97c3Snir.tzachar@gmail.com 		}
1420692d97c3Snir.tzachar@gmail.com 	}
1421692d97c3Snir.tzachar@gmail.com }
1422692d97c3Snir.tzachar@gmail.com 
1423692d97c3Snir.tzachar@gmail.com static void conf_save(void)
1424692d97c3Snir.tzachar@gmail.com {
1425692d97c3Snir.tzachar@gmail.com 	while (1) {
1426692d97c3Snir.tzachar@gmail.com 		int res;
1427692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1428692d97c3Snir.tzachar@gmail.com 				NULL, save_config_text,
1429692d97c3Snir.tzachar@gmail.com 				filename,
14305ea9f64fSCheng Renquan 				&dialog_input_result,
14315ea9f64fSCheng Renquan 				&dialog_input_result_len);
1432692d97c3Snir.tzachar@gmail.com 		switch (res) {
1433692d97c3Snir.tzachar@gmail.com 		case 0:
1434692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1435692d97c3Snir.tzachar@gmail.com 				return;
1436692d97c3Snir.tzachar@gmail.com 			res = conf_write(dialog_input_result);
1437692d97c3Snir.tzachar@gmail.com 			if (!res) {
1438692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
1439692d97c3Snir.tzachar@gmail.com 				return;
1440692d97c3Snir.tzachar@gmail.com 			}
1441692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window, _("Can't create file! "
1442692d97c3Snir.tzachar@gmail.com 				"Probably a nonexistent directory."),
1443692d97c3Snir.tzachar@gmail.com 				1, "<OK>");
1444692d97c3Snir.tzachar@gmail.com 			break;
1445692d97c3Snir.tzachar@gmail.com 		case 1:
1446692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1447692d97c3Snir.tzachar@gmail.com 				_("Save Alternate Configuration"),
1448692d97c3Snir.tzachar@gmail.com 				save_config_help);
1449692d97c3Snir.tzachar@gmail.com 			break;
1450692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1451692d97c3Snir.tzachar@gmail.com 			return;
1452692d97c3Snir.tzachar@gmail.com 		}
1453692d97c3Snir.tzachar@gmail.com 	}
1454692d97c3Snir.tzachar@gmail.com }
1455692d97c3Snir.tzachar@gmail.com 
1456692d97c3Snir.tzachar@gmail.com void setup_windows(void)
1457692d97c3Snir.tzachar@gmail.com {
1458692d97c3Snir.tzachar@gmail.com 	if (main_window != NULL)
1459692d97c3Snir.tzachar@gmail.com 		delwin(main_window);
1460692d97c3Snir.tzachar@gmail.com 
1461692d97c3Snir.tzachar@gmail.com 	/* set up the menu and menu window */
1462692d97c3Snir.tzachar@gmail.com 	main_window = newwin(LINES-2, COLS-2, 2, 1);
1463692d97c3Snir.tzachar@gmail.com 	keypad(main_window, TRUE);
1464a72f3e2bSNir Tzachar 	mwin_max_lines = LINES-7;
1465692d97c3Snir.tzachar@gmail.com 	mwin_max_cols = COLS-6;
1466692d97c3Snir.tzachar@gmail.com 
1467692d97c3Snir.tzachar@gmail.com 	/* panels order is from bottom to top */
1468692d97c3Snir.tzachar@gmail.com 	new_panel(main_window);
1469692d97c3Snir.tzachar@gmail.com }
1470692d97c3Snir.tzachar@gmail.com 
1471692d97c3Snir.tzachar@gmail.com int main(int ac, char **av)
1472692d97c3Snir.tzachar@gmail.com {
1473692d97c3Snir.tzachar@gmail.com 	char *mode;
1474692d97c3Snir.tzachar@gmail.com 
1475692d97c3Snir.tzachar@gmail.com 	setlocale(LC_ALL, "");
1476692d97c3Snir.tzachar@gmail.com 	bindtextdomain(PACKAGE, LOCALEDIR);
1477692d97c3Snir.tzachar@gmail.com 	textdomain(PACKAGE);
1478692d97c3Snir.tzachar@gmail.com 
1479692d97c3Snir.tzachar@gmail.com 	conf_parse(av[1]);
1480692d97c3Snir.tzachar@gmail.com 	conf_read(NULL);
1481692d97c3Snir.tzachar@gmail.com 
1482692d97c3Snir.tzachar@gmail.com 	mode = getenv("NCONFIG_MODE");
1483692d97c3Snir.tzachar@gmail.com 	if (mode) {
1484692d97c3Snir.tzachar@gmail.com 		if (!strcasecmp(mode, "single_menu"))
1485692d97c3Snir.tzachar@gmail.com 			single_menu_mode = 1;
1486692d97c3Snir.tzachar@gmail.com 	}
1487692d97c3Snir.tzachar@gmail.com 
1488692d97c3Snir.tzachar@gmail.com 	/* Initialize curses */
1489692d97c3Snir.tzachar@gmail.com 	initscr();
1490692d97c3Snir.tzachar@gmail.com 	/* set color theme */
1491692d97c3Snir.tzachar@gmail.com 	set_colors();
1492692d97c3Snir.tzachar@gmail.com 
1493692d97c3Snir.tzachar@gmail.com 	cbreak();
1494692d97c3Snir.tzachar@gmail.com 	noecho();
1495692d97c3Snir.tzachar@gmail.com 	keypad(stdscr, TRUE);
1496692d97c3Snir.tzachar@gmail.com 	curs_set(0);
1497692d97c3Snir.tzachar@gmail.com 
1498692d97c3Snir.tzachar@gmail.com 	if (COLS < 75 || LINES < 20) {
1499692d97c3Snir.tzachar@gmail.com 		endwin();
1500692d97c3Snir.tzachar@gmail.com 		printf("Your terminal should have at "
1501692d97c3Snir.tzachar@gmail.com 			"least 20 lines and 75 columns\n");
1502692d97c3Snir.tzachar@gmail.com 		return 1;
1503692d97c3Snir.tzachar@gmail.com 	}
1504692d97c3Snir.tzachar@gmail.com 
1505692d97c3Snir.tzachar@gmail.com 	notimeout(stdscr, FALSE);
1506d7c67a2eSYaakov Selkowitz #if NCURSES_REENTRANT
1507d7c67a2eSYaakov Selkowitz 	set_escdelay(1);
1508d7c67a2eSYaakov Selkowitz #else
1509692d97c3Snir.tzachar@gmail.com 	ESCDELAY = 1;
1510d7c67a2eSYaakov Selkowitz #endif
1511692d97c3Snir.tzachar@gmail.com 
1512692d97c3Snir.tzachar@gmail.com 	/* set btns menu */
1513692d97c3Snir.tzachar@gmail.com 	curses_menu = new_menu(curses_menu_items);
1514692d97c3Snir.tzachar@gmail.com 	menu_opts_off(curses_menu, O_SHOWDESC);
1515a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_SHOWMATCH);
1516692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_ONEVALUE);
1517692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_NONCYCLIC);
1518a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_IGNORECASE);
1519692d97c3Snir.tzachar@gmail.com 	set_menu_mark(curses_menu, " ");
1520692d97c3Snir.tzachar@gmail.com 	set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1521692d97c3Snir.tzachar@gmail.com 	set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1522692d97c3Snir.tzachar@gmail.com 	set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1523692d97c3Snir.tzachar@gmail.com 
1524692d97c3Snir.tzachar@gmail.com 	set_config_filename(conf_get_configname());
1525692d97c3Snir.tzachar@gmail.com 	setup_windows();
1526692d97c3Snir.tzachar@gmail.com 
1527692d97c3Snir.tzachar@gmail.com 	/* check for KEY_FUNC(1) */
1528692d97c3Snir.tzachar@gmail.com 	if (has_key(KEY_F(1)) == FALSE) {
1529692d97c3Snir.tzachar@gmail.com 		show_scroll_win(main_window,
1530692d97c3Snir.tzachar@gmail.com 				_("Instructions"),
1531692d97c3Snir.tzachar@gmail.com 				_(menu_no_f_instructions));
1532692d97c3Snir.tzachar@gmail.com 	}
1533692d97c3Snir.tzachar@gmail.com 
153442368c37SMichal Marek 	conf_set_message_callback(conf_message_callback);
1535692d97c3Snir.tzachar@gmail.com 	/* do the work */
1536692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1537692d97c3Snir.tzachar@gmail.com 		conf(&rootmenu);
1538692d97c3Snir.tzachar@gmail.com 		if (!global_exit && do_exit() == 0)
1539692d97c3Snir.tzachar@gmail.com 			break;
1540692d97c3Snir.tzachar@gmail.com 	}
1541692d97c3Snir.tzachar@gmail.com 	/* ok, we are done */
1542692d97c3Snir.tzachar@gmail.com 	unpost_menu(curses_menu);
1543692d97c3Snir.tzachar@gmail.com 	free_menu(curses_menu);
1544692d97c3Snir.tzachar@gmail.com 	delwin(main_window);
1545692d97c3Snir.tzachar@gmail.com 	clear();
1546692d97c3Snir.tzachar@gmail.com 	refresh();
1547692d97c3Snir.tzachar@gmail.com 	endwin();
1548692d97c3Snir.tzachar@gmail.com 	return 0;
1549692d97c3Snir.tzachar@gmail.com }
1550692d97c3Snir.tzachar@gmail.com 
1551