xref: /linux/scripts/kconfig/nconf.c (revision 5a6f8d2bd9e3392569ed6f29ea4d7210652f929b)
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>
10*5a6f8d2bSArnaud 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"
86692d97c3Snir.tzachar@gmail.com "   keys h,j,k,l function here as do <SPACE BAR> for those\n"
87692d97c3Snir.tzachar@gmail.com "   who are familiar with less and lynx.\n"
88692d97c3Snir.tzachar@gmail.com "\n"
89692d97c3Snir.tzachar@gmail.com "o  Press <Enter>, <F1>, <F5>, <F7> 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 nohelp_text[] = N_(
186652cf982SArnaud Lacombe "There is no help available for this option.\n"),
187692d97c3Snir.tzachar@gmail.com load_config_text[] = N_(
188692d97c3Snir.tzachar@gmail.com "Enter the name of the configuration file you wish to load.\n"
189692d97c3Snir.tzachar@gmail.com "Accept the name shown to restore the configuration you\n"
190692d97c3Snir.tzachar@gmail.com "last retrieved.  Leave blank to abort."),
191692d97c3Snir.tzachar@gmail.com load_config_help[] = N_(
192692d97c3Snir.tzachar@gmail.com "\n"
193652cf982SArnaud Lacombe "For various reasons, one may wish to keep several different\n"
194692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n"
195692d97c3Snir.tzachar@gmail.com "\n"
196692d97c3Snir.tzachar@gmail.com "If you have saved a previous configuration in a file other than the\n"
197652cf982SArnaud Lacombe "default one, entering its name here will allow you to modify that\n"
198652cf982SArnaud Lacombe "configuration.\n"
199692d97c3Snir.tzachar@gmail.com "\n"
200692d97c3Snir.tzachar@gmail.com "If you are uncertain, then you have probably never used alternate\n"
201692d97c3Snir.tzachar@gmail.com "configuration files.  You should therefor leave this blank to abort.\n"),
202692d97c3Snir.tzachar@gmail.com save_config_text[] = N_(
203692d97c3Snir.tzachar@gmail.com "Enter a filename to which this configuration should be saved\n"
204692d97c3Snir.tzachar@gmail.com "as an alternate.  Leave blank to abort."),
205692d97c3Snir.tzachar@gmail.com save_config_help[] = N_(
206692d97c3Snir.tzachar@gmail.com "\n"
207652cf982SArnaud Lacombe "For various reasons, one may wish to keep different configurations\n"
208652cf982SArnaud Lacombe "available on a single machine.\n"
209692d97c3Snir.tzachar@gmail.com "\n"
210692d97c3Snir.tzachar@gmail.com "Entering a file name here will allow you to later retrieve, modify\n"
211692d97c3Snir.tzachar@gmail.com "and use the current configuration as an alternate to whatever\n"
212692d97c3Snir.tzachar@gmail.com "configuration options you have selected at that time.\n"
213692d97c3Snir.tzachar@gmail.com "\n"
214692d97c3Snir.tzachar@gmail.com "If you are uncertain what all this means then you should probably\n"
215692d97c3Snir.tzachar@gmail.com "leave this blank.\n"),
216692d97c3Snir.tzachar@gmail.com search_help[] = N_(
217692d97c3Snir.tzachar@gmail.com "\n"
21859dfa24dSArnaud Lacombe "Search for symbols and display their relations. Regular expressions\n"
21959dfa24dSArnaud Lacombe "are allowed.\n"
220692d97c3Snir.tzachar@gmail.com "Example: search for \"^FOO\"\n"
221692d97c3Snir.tzachar@gmail.com "Result:\n"
222692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
223692d97c3Snir.tzachar@gmail.com "Symbol: FOO [ = m]\n"
224692d97c3Snir.tzachar@gmail.com "Prompt: Foo bus is used to drive the bar HW\n"
225692d97c3Snir.tzachar@gmail.com "Defined at drivers/pci/Kconfig:47\n"
226692d97c3Snir.tzachar@gmail.com "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
227692d97c3Snir.tzachar@gmail.com "Location:\n"
228692d97c3Snir.tzachar@gmail.com "  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
229692d97c3Snir.tzachar@gmail.com "    -> PCI support (PCI [ = y])\n"
230692d97c3Snir.tzachar@gmail.com "      -> PCI access mode (<choice> [ = y])\n"
231692d97c3Snir.tzachar@gmail.com "Selects: LIBCRC32\n"
232692d97c3Snir.tzachar@gmail.com "Selected by: BAR\n"
233692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n"
234692d97c3Snir.tzachar@gmail.com "o The line 'Prompt:' shows the text used in the menu structure for\n"
23559dfa24dSArnaud Lacombe "  this symbol\n"
236692d97c3Snir.tzachar@gmail.com "o The 'Defined at' line tell at what file / line number the symbol\n"
237692d97c3Snir.tzachar@gmail.com "  is defined\n"
238692d97c3Snir.tzachar@gmail.com "o The 'Depends on:' line tell what symbols needs to be defined for\n"
239692d97c3Snir.tzachar@gmail.com "  this symbol to be visible in the menu (selectable)\n"
240692d97c3Snir.tzachar@gmail.com "o The 'Location:' lines tell where in the menu structure this symbol\n"
241692d97c3Snir.tzachar@gmail.com "  is located\n"
242692d97c3Snir.tzachar@gmail.com "    A location followed by a [ = y] indicate that this is a selectable\n"
243692d97c3Snir.tzachar@gmail.com "    menu item - and current value is displayed inside brackets.\n"
244692d97c3Snir.tzachar@gmail.com "o The 'Selects:' line tell what symbol will be automatically\n"
245692d97c3Snir.tzachar@gmail.com "  selected if this symbol is selected (y or m)\n"
246692d97c3Snir.tzachar@gmail.com "o The 'Selected by' line tell what symbol has selected this symbol\n"
247692d97c3Snir.tzachar@gmail.com "\n"
248692d97c3Snir.tzachar@gmail.com "Only relevant lines are shown.\n"
249692d97c3Snir.tzachar@gmail.com "\n\n"
250692d97c3Snir.tzachar@gmail.com "Search examples:\n"
25159dfa24dSArnaud Lacombe "Examples: USB  => find all symbols containing USB\n"
25259dfa24dSArnaud Lacombe "          ^USB => find all symbols starting with USB\n"
25359dfa24dSArnaud Lacombe "          USB$ => find all symbols ending with USB\n"
254692d97c3Snir.tzachar@gmail.com "\n");
255692d97c3Snir.tzachar@gmail.com 
256692d97c3Snir.tzachar@gmail.com struct mitem {
257692d97c3Snir.tzachar@gmail.com 	char str[256];
258692d97c3Snir.tzachar@gmail.com 	char tag;
259692d97c3Snir.tzachar@gmail.com 	void *usrptr;
260692d97c3Snir.tzachar@gmail.com 	int is_visible;
261692d97c3Snir.tzachar@gmail.com };
262692d97c3Snir.tzachar@gmail.com 
263692d97c3Snir.tzachar@gmail.com #define MAX_MENU_ITEMS 4096
264692d97c3Snir.tzachar@gmail.com static int show_all_items;
265692d97c3Snir.tzachar@gmail.com static int indent;
266692d97c3Snir.tzachar@gmail.com static struct menu *current_menu;
267692d97c3Snir.tzachar@gmail.com static int child_count;
268692d97c3Snir.tzachar@gmail.com static int single_menu_mode;
269692d97c3Snir.tzachar@gmail.com /* the window in which all information appears */
270692d97c3Snir.tzachar@gmail.com static WINDOW *main_window;
271692d97c3Snir.tzachar@gmail.com /* the largest size of the menu window */
272692d97c3Snir.tzachar@gmail.com static int mwin_max_lines;
273692d97c3Snir.tzachar@gmail.com static int mwin_max_cols;
274692d97c3Snir.tzachar@gmail.com /* the window in which we show option buttons */
275692d97c3Snir.tzachar@gmail.com static MENU *curses_menu;
276692d97c3Snir.tzachar@gmail.com static ITEM *curses_menu_items[MAX_MENU_ITEMS];
277692d97c3Snir.tzachar@gmail.com static struct mitem k_menu_items[MAX_MENU_ITEMS];
278692d97c3Snir.tzachar@gmail.com static int items_num;
279692d97c3Snir.tzachar@gmail.com static int global_exit;
280692d97c3Snir.tzachar@gmail.com /* the currently selected button */
281692d97c3Snir.tzachar@gmail.com const char *current_instructions = menu_instructions;
282692d97c3Snir.tzachar@gmail.com 
283692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu);
284692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu);
285692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu);
286692d97c3Snir.tzachar@gmail.com static void conf_load(void);
287692d97c3Snir.tzachar@gmail.com static void conf_save(void);
288692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu);
289692d97c3Snir.tzachar@gmail.com static int do_exit(void);
290692d97c3Snir.tzachar@gmail.com static void setup_windows(void);
291a72f3e2bSNir Tzachar static void search_conf(void);
292692d97c3Snir.tzachar@gmail.com 
293692d97c3Snir.tzachar@gmail.com typedef void (*function_key_handler_t)(int *key, struct menu *menu);
294692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item);
295692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item);
296692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item);
297692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item);
298692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item);
299692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item);
300692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item);
301692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item);
302a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item);
303692d97c3Snir.tzachar@gmail.com 
304692d97c3Snir.tzachar@gmail.com struct function_keys {
305692d97c3Snir.tzachar@gmail.com 	const char *key_str;
306692d97c3Snir.tzachar@gmail.com 	const char *func;
307692d97c3Snir.tzachar@gmail.com 	function_key key;
308692d97c3Snir.tzachar@gmail.com 	function_key_handler_t handler;
309692d97c3Snir.tzachar@gmail.com };
310692d97c3Snir.tzachar@gmail.com 
311a72f3e2bSNir Tzachar static const int function_keys_num = 9;
312692d97c3Snir.tzachar@gmail.com struct function_keys function_keys[] = {
313692d97c3Snir.tzachar@gmail.com 	{
314692d97c3Snir.tzachar@gmail.com 		.key_str = "F1",
315692d97c3Snir.tzachar@gmail.com 		.func = "Help",
316692d97c3Snir.tzachar@gmail.com 		.key = F_HELP,
317692d97c3Snir.tzachar@gmail.com 		.handler = handle_f1,
318692d97c3Snir.tzachar@gmail.com 	},
319692d97c3Snir.tzachar@gmail.com 	{
320692d97c3Snir.tzachar@gmail.com 		.key_str = "F2",
321a72f3e2bSNir Tzachar 		.func = "Sym Info",
322692d97c3Snir.tzachar@gmail.com 		.key = F_SYMBOL,
323692d97c3Snir.tzachar@gmail.com 		.handler = handle_f2,
324692d97c3Snir.tzachar@gmail.com 	},
325692d97c3Snir.tzachar@gmail.com 	{
326692d97c3Snir.tzachar@gmail.com 		.key_str = "F3",
327a72f3e2bSNir Tzachar 		.func = "Insts",
328692d97c3Snir.tzachar@gmail.com 		.key = F_INSTS,
329692d97c3Snir.tzachar@gmail.com 		.handler = handle_f3,
330692d97c3Snir.tzachar@gmail.com 	},
331692d97c3Snir.tzachar@gmail.com 	{
332692d97c3Snir.tzachar@gmail.com 		.key_str = "F4",
333692d97c3Snir.tzachar@gmail.com 		.func = "Config",
334692d97c3Snir.tzachar@gmail.com 		.key = F_CONF,
335692d97c3Snir.tzachar@gmail.com 		.handler = handle_f4,
336692d97c3Snir.tzachar@gmail.com 	},
337692d97c3Snir.tzachar@gmail.com 	{
338692d97c3Snir.tzachar@gmail.com 		.key_str = "F5",
339692d97c3Snir.tzachar@gmail.com 		.func = "Back",
340692d97c3Snir.tzachar@gmail.com 		.key = F_BACK,
341692d97c3Snir.tzachar@gmail.com 		.handler = handle_f5,
342692d97c3Snir.tzachar@gmail.com 	},
343692d97c3Snir.tzachar@gmail.com 	{
344692d97c3Snir.tzachar@gmail.com 		.key_str = "F6",
345692d97c3Snir.tzachar@gmail.com 		.func = "Save",
346692d97c3Snir.tzachar@gmail.com 		.key = F_SAVE,
347692d97c3Snir.tzachar@gmail.com 		.handler = handle_f6,
348692d97c3Snir.tzachar@gmail.com 	},
349692d97c3Snir.tzachar@gmail.com 	{
350692d97c3Snir.tzachar@gmail.com 		.key_str = "F7",
351692d97c3Snir.tzachar@gmail.com 		.func = "Load",
352692d97c3Snir.tzachar@gmail.com 		.key = F_LOAD,
353692d97c3Snir.tzachar@gmail.com 		.handler = handle_f7,
354692d97c3Snir.tzachar@gmail.com 	},
355692d97c3Snir.tzachar@gmail.com 	{
356692d97c3Snir.tzachar@gmail.com 		.key_str = "F8",
357a72f3e2bSNir Tzachar 		.func = "Sym Search",
358a72f3e2bSNir Tzachar 		.key = F_SEARCH,
359a72f3e2bSNir Tzachar 		.handler = handle_f8,
360a72f3e2bSNir Tzachar 	},
361a72f3e2bSNir Tzachar 	{
362a72f3e2bSNir Tzachar 		.key_str = "F9",
363692d97c3Snir.tzachar@gmail.com 		.func = "Exit",
364692d97c3Snir.tzachar@gmail.com 		.key = F_EXIT,
365a72f3e2bSNir Tzachar 		.handler = handle_f9,
366692d97c3Snir.tzachar@gmail.com 	},
367692d97c3Snir.tzachar@gmail.com };
368692d97c3Snir.tzachar@gmail.com 
369692d97c3Snir.tzachar@gmail.com static void print_function_line(void)
370692d97c3Snir.tzachar@gmail.com {
371692d97c3Snir.tzachar@gmail.com 	int i;
372692d97c3Snir.tzachar@gmail.com 	int offset = 1;
373692d97c3Snir.tzachar@gmail.com 	const int skip = 1;
374692d97c3Snir.tzachar@gmail.com 
375692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
37610175ba6SStephen Boyd 		(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
377692d97c3Snir.tzachar@gmail.com 		mvwprintw(main_window, LINES-3, offset,
378692d97c3Snir.tzachar@gmail.com 				"%s",
379692d97c3Snir.tzachar@gmail.com 				function_keys[i].key_str);
38010175ba6SStephen Boyd 		(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
381692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].key_str);
382692d97c3Snir.tzachar@gmail.com 		mvwprintw(main_window, LINES-3,
383692d97c3Snir.tzachar@gmail.com 				offset, "%s",
384692d97c3Snir.tzachar@gmail.com 				function_keys[i].func);
385692d97c3Snir.tzachar@gmail.com 		offset += strlen(function_keys[i].func) + skip;
386692d97c3Snir.tzachar@gmail.com 	}
38710175ba6SStephen Boyd 	(void) wattrset(main_window, attributes[NORMAL]);
388692d97c3Snir.tzachar@gmail.com }
389692d97c3Snir.tzachar@gmail.com 
390692d97c3Snir.tzachar@gmail.com /* help */
391692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item)
392692d97c3Snir.tzachar@gmail.com {
393692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
394692d97c3Snir.tzachar@gmail.com 			_("README"), _(nconf_readme));
395692d97c3Snir.tzachar@gmail.com 	return;
396692d97c3Snir.tzachar@gmail.com }
397692d97c3Snir.tzachar@gmail.com 
398692d97c3Snir.tzachar@gmail.com /* symbole help */
399692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item)
400692d97c3Snir.tzachar@gmail.com {
401692d97c3Snir.tzachar@gmail.com 	show_help(current_item);
402692d97c3Snir.tzachar@gmail.com 	return;
403692d97c3Snir.tzachar@gmail.com }
404692d97c3Snir.tzachar@gmail.com 
405692d97c3Snir.tzachar@gmail.com /* instructions */
406692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item)
407692d97c3Snir.tzachar@gmail.com {
408692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window,
409692d97c3Snir.tzachar@gmail.com 			_("Instructions"),
410692d97c3Snir.tzachar@gmail.com 			_(current_instructions));
411692d97c3Snir.tzachar@gmail.com 	return;
412692d97c3Snir.tzachar@gmail.com }
413692d97c3Snir.tzachar@gmail.com 
414692d97c3Snir.tzachar@gmail.com /* config */
415692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item)
416692d97c3Snir.tzachar@gmail.com {
417692d97c3Snir.tzachar@gmail.com 	int res = btn_dialog(main_window,
418692d97c3Snir.tzachar@gmail.com 			_("Show all symbols?"),
419692d97c3Snir.tzachar@gmail.com 			2,
420692d97c3Snir.tzachar@gmail.com 			"   <Show All>   ",
421692d97c3Snir.tzachar@gmail.com 			"<Don't show all>");
422692d97c3Snir.tzachar@gmail.com 	if (res == 0)
423692d97c3Snir.tzachar@gmail.com 		show_all_items = 1;
424692d97c3Snir.tzachar@gmail.com 	else if (res == 1)
425692d97c3Snir.tzachar@gmail.com 		show_all_items = 0;
426692d97c3Snir.tzachar@gmail.com 
427692d97c3Snir.tzachar@gmail.com 	return;
428692d97c3Snir.tzachar@gmail.com }
429692d97c3Snir.tzachar@gmail.com 
430692d97c3Snir.tzachar@gmail.com /* back */
431692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item)
432692d97c3Snir.tzachar@gmail.com {
433692d97c3Snir.tzachar@gmail.com 	*key = KEY_LEFT;
434692d97c3Snir.tzachar@gmail.com 	return;
435692d97c3Snir.tzachar@gmail.com }
436692d97c3Snir.tzachar@gmail.com 
437692d97c3Snir.tzachar@gmail.com /* save */
438692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item)
439692d97c3Snir.tzachar@gmail.com {
440692d97c3Snir.tzachar@gmail.com 	conf_save();
441692d97c3Snir.tzachar@gmail.com 	return;
442692d97c3Snir.tzachar@gmail.com }
443692d97c3Snir.tzachar@gmail.com 
444692d97c3Snir.tzachar@gmail.com /* load */
445692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item)
446692d97c3Snir.tzachar@gmail.com {
447692d97c3Snir.tzachar@gmail.com 	conf_load();
448692d97c3Snir.tzachar@gmail.com 	return;
449692d97c3Snir.tzachar@gmail.com }
450692d97c3Snir.tzachar@gmail.com 
451a72f3e2bSNir Tzachar /* search */
452692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item)
453692d97c3Snir.tzachar@gmail.com {
454a72f3e2bSNir Tzachar 	search_conf();
455a72f3e2bSNir Tzachar 	return;
456a72f3e2bSNir Tzachar }
457a72f3e2bSNir Tzachar 
458a72f3e2bSNir Tzachar /* exit */
459a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item)
460a72f3e2bSNir Tzachar {
461692d97c3Snir.tzachar@gmail.com 	do_exit();
462692d97c3Snir.tzachar@gmail.com 	return;
463692d97c3Snir.tzachar@gmail.com }
464692d97c3Snir.tzachar@gmail.com 
465692d97c3Snir.tzachar@gmail.com /* return != 0 to indicate the key was handles */
466851190c9SMichal Marek static int process_special_keys(int *key, struct menu *menu)
467692d97c3Snir.tzachar@gmail.com {
468692d97c3Snir.tzachar@gmail.com 	int i;
469692d97c3Snir.tzachar@gmail.com 
470692d97c3Snir.tzachar@gmail.com 	if (*key == KEY_RESIZE) {
471692d97c3Snir.tzachar@gmail.com 		setup_windows();
472692d97c3Snir.tzachar@gmail.com 		return 1;
473692d97c3Snir.tzachar@gmail.com 	}
474692d97c3Snir.tzachar@gmail.com 
475692d97c3Snir.tzachar@gmail.com 	for (i = 0; i < function_keys_num; i++) {
476692d97c3Snir.tzachar@gmail.com 		if (*key == KEY_F(function_keys[i].key) ||
477692d97c3Snir.tzachar@gmail.com 		    *key == '0' + function_keys[i].key){
478692d97c3Snir.tzachar@gmail.com 			function_keys[i].handler(key, menu);
479692d97c3Snir.tzachar@gmail.com 			return 1;
480692d97c3Snir.tzachar@gmail.com 		}
481692d97c3Snir.tzachar@gmail.com 	}
482692d97c3Snir.tzachar@gmail.com 
483692d97c3Snir.tzachar@gmail.com 	return 0;
484692d97c3Snir.tzachar@gmail.com }
485692d97c3Snir.tzachar@gmail.com 
486692d97c3Snir.tzachar@gmail.com static void clean_items(void)
487692d97c3Snir.tzachar@gmail.com {
488692d97c3Snir.tzachar@gmail.com 	int i;
489692d97c3Snir.tzachar@gmail.com 	for (i = 0; curses_menu_items[i]; i++)
490692d97c3Snir.tzachar@gmail.com 		free_item(curses_menu_items[i]);
491692d97c3Snir.tzachar@gmail.com 	bzero(curses_menu_items, sizeof(curses_menu_items));
492692d97c3Snir.tzachar@gmail.com 	bzero(k_menu_items, sizeof(k_menu_items));
493692d97c3Snir.tzachar@gmail.com 	items_num = 0;
494692d97c3Snir.tzachar@gmail.com }
495692d97c3Snir.tzachar@gmail.com 
496a72f3e2bSNir Tzachar typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
497a72f3e2bSNir Tzachar 	FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
498692d97c3Snir.tzachar@gmail.com 
499a72f3e2bSNir Tzachar /* return the index of the matched item, or -1 if no such item exists */
500a72f3e2bSNir Tzachar static int get_mext_match(const char *match_str, match_f flag)
501a72f3e2bSNir Tzachar {
502a72f3e2bSNir Tzachar 	int match_start = item_index(current_item(curses_menu));
503a72f3e2bSNir Tzachar 	int index;
504a72f3e2bSNir Tzachar 
505a72f3e2bSNir Tzachar 	if (flag == FIND_NEXT_MATCH_DOWN)
506a72f3e2bSNir Tzachar 		++match_start;
507a72f3e2bSNir Tzachar 	else if (flag == FIND_NEXT_MATCH_UP)
508a72f3e2bSNir Tzachar 		--match_start;
509a72f3e2bSNir Tzachar 
510a72f3e2bSNir Tzachar 	index = match_start;
511a72f3e2bSNir Tzachar 	index = (index + items_num) % items_num;
512a72f3e2bSNir Tzachar 	while (true) {
513a72f3e2bSNir Tzachar 		char *str = k_menu_items[index].str;
514a72f3e2bSNir Tzachar 		if (strcasestr(str, match_str) != 0)
515a72f3e2bSNir Tzachar 			return index;
516a72f3e2bSNir Tzachar 		if (flag == FIND_NEXT_MATCH_UP ||
517a72f3e2bSNir Tzachar 		    flag == MATCH_TINKER_PATTERN_UP)
518a72f3e2bSNir Tzachar 			--index;
519a72f3e2bSNir Tzachar 		else
520a72f3e2bSNir Tzachar 			++index;
521a72f3e2bSNir Tzachar 		index = (index + items_num) % items_num;
522a72f3e2bSNir Tzachar 		if (index == match_start)
523692d97c3Snir.tzachar@gmail.com 			return -1;
524692d97c3Snir.tzachar@gmail.com 	}
525692d97c3Snir.tzachar@gmail.com }
526692d97c3Snir.tzachar@gmail.com 
527a72f3e2bSNir Tzachar /* Make a new item. */
528851190c9SMichal Marek static void item_make(struct menu *menu, char tag, const char *fmt, ...)
529692d97c3Snir.tzachar@gmail.com {
530692d97c3Snir.tzachar@gmail.com 	va_list ap;
531692d97c3Snir.tzachar@gmail.com 
532692d97c3Snir.tzachar@gmail.com 	if (items_num > MAX_MENU_ITEMS-1)
533692d97c3Snir.tzachar@gmail.com 		return;
534692d97c3Snir.tzachar@gmail.com 
535692d97c3Snir.tzachar@gmail.com 	bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
536692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].tag = tag;
537692d97c3Snir.tzachar@gmail.com 	k_menu_items[items_num].usrptr = menu;
538692d97c3Snir.tzachar@gmail.com 	if (menu != NULL)
539692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible =
540692d97c3Snir.tzachar@gmail.com 			menu_is_visible(menu);
541692d97c3Snir.tzachar@gmail.com 	else
542692d97c3Snir.tzachar@gmail.com 		k_menu_items[items_num].is_visible = 1;
543692d97c3Snir.tzachar@gmail.com 
544692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
545a72f3e2bSNir Tzachar 	vsnprintf(k_menu_items[items_num].str,
546a72f3e2bSNir Tzachar 		  sizeof(k_menu_items[items_num].str),
547a72f3e2bSNir Tzachar 		  fmt, ap);
548692d97c3Snir.tzachar@gmail.com 	va_end(ap);
549a72f3e2bSNir Tzachar 
550a72f3e2bSNir Tzachar 	if (!k_menu_items[items_num].is_visible)
551a72f3e2bSNir Tzachar 		memcpy(k_menu_items[items_num].str, "XXX", 3);
552692d97c3Snir.tzachar@gmail.com 
553692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = new_item(
554692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str,
555692d97c3Snir.tzachar@gmail.com 			k_menu_items[items_num].str);
556692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[items_num],
557692d97c3Snir.tzachar@gmail.com 			&k_menu_items[items_num]);
558692d97c3Snir.tzachar@gmail.com 	/*
559692d97c3Snir.tzachar@gmail.com 	if (!k_menu_items[items_num].is_visible)
560692d97c3Snir.tzachar@gmail.com 		item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
561692d97c3Snir.tzachar@gmail.com 	*/
562692d97c3Snir.tzachar@gmail.com 
563692d97c3Snir.tzachar@gmail.com 	items_num++;
564692d97c3Snir.tzachar@gmail.com 	curses_menu_items[items_num] = NULL;
565692d97c3Snir.tzachar@gmail.com }
566692d97c3Snir.tzachar@gmail.com 
567692d97c3Snir.tzachar@gmail.com /* very hackish. adds a string to the last item added */
568851190c9SMichal Marek static void item_add_str(const char *fmt, ...)
569692d97c3Snir.tzachar@gmail.com {
570692d97c3Snir.tzachar@gmail.com 	va_list ap;
571692d97c3Snir.tzachar@gmail.com 	int index = items_num-1;
572692d97c3Snir.tzachar@gmail.com 	char new_str[256];
573692d97c3Snir.tzachar@gmail.com 	char tmp_str[256];
574692d97c3Snir.tzachar@gmail.com 
575692d97c3Snir.tzachar@gmail.com 	if (index < 0)
576692d97c3Snir.tzachar@gmail.com 		return;
577692d97c3Snir.tzachar@gmail.com 
578692d97c3Snir.tzachar@gmail.com 	va_start(ap, fmt);
579692d97c3Snir.tzachar@gmail.com 	vsnprintf(new_str, sizeof(new_str), fmt, ap);
580692d97c3Snir.tzachar@gmail.com 	va_end(ap);
581692d97c3Snir.tzachar@gmail.com 	snprintf(tmp_str, sizeof(tmp_str), "%s%s",
582692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str, new_str);
583692d97c3Snir.tzachar@gmail.com 	strncpy(k_menu_items[index].str,
584692d97c3Snir.tzachar@gmail.com 		tmp_str,
585692d97c3Snir.tzachar@gmail.com 		sizeof(k_menu_items[index].str));
586692d97c3Snir.tzachar@gmail.com 
587692d97c3Snir.tzachar@gmail.com 	free_item(curses_menu_items[index]);
588692d97c3Snir.tzachar@gmail.com 	curses_menu_items[index] = new_item(
589692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str,
590692d97c3Snir.tzachar@gmail.com 			k_menu_items[index].str);
591692d97c3Snir.tzachar@gmail.com 	set_item_userptr(curses_menu_items[index],
592692d97c3Snir.tzachar@gmail.com 			&k_menu_items[index]);
593692d97c3Snir.tzachar@gmail.com }
594692d97c3Snir.tzachar@gmail.com 
595692d97c3Snir.tzachar@gmail.com /* get the tag of the currently selected item */
596851190c9SMichal Marek static char item_tag(void)
597692d97c3Snir.tzachar@gmail.com {
598692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
599692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
600692d97c3Snir.tzachar@gmail.com 
601692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
602692d97c3Snir.tzachar@gmail.com 	if (cur == NULL)
603692d97c3Snir.tzachar@gmail.com 		return 0;
604692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
605692d97c3Snir.tzachar@gmail.com 	return mcur->tag;
606692d97c3Snir.tzachar@gmail.com }
607692d97c3Snir.tzachar@gmail.com 
608851190c9SMichal Marek static int curses_item_index(void)
609692d97c3Snir.tzachar@gmail.com {
610692d97c3Snir.tzachar@gmail.com 	return  item_index(current_item(curses_menu));
611692d97c3Snir.tzachar@gmail.com }
612692d97c3Snir.tzachar@gmail.com 
613851190c9SMichal Marek static void *item_data(void)
614692d97c3Snir.tzachar@gmail.com {
615692d97c3Snir.tzachar@gmail.com 	ITEM *cur;
616692d97c3Snir.tzachar@gmail.com 	struct mitem *mcur;
617692d97c3Snir.tzachar@gmail.com 
618692d97c3Snir.tzachar@gmail.com 	cur = current_item(curses_menu);
619866af407SAndrej Gelenberg 	if (!cur)
620866af407SAndrej Gelenberg 		return NULL;
621692d97c3Snir.tzachar@gmail.com 	mcur = (struct mitem *) item_userptr(cur);
622692d97c3Snir.tzachar@gmail.com 	return mcur->usrptr;
623692d97c3Snir.tzachar@gmail.com 
624692d97c3Snir.tzachar@gmail.com }
625692d97c3Snir.tzachar@gmail.com 
626851190c9SMichal Marek static int item_is_tag(char tag)
627692d97c3Snir.tzachar@gmail.com {
628692d97c3Snir.tzachar@gmail.com 	return item_tag() == tag;
629692d97c3Snir.tzachar@gmail.com }
630692d97c3Snir.tzachar@gmail.com 
631692d97c3Snir.tzachar@gmail.com static char filename[PATH_MAX+1];
632692d97c3Snir.tzachar@gmail.com static char menu_backtitle[PATH_MAX+128];
633851190c9SMichal Marek static const char *set_config_filename(const char *config_filename)
634692d97c3Snir.tzachar@gmail.com {
635692d97c3Snir.tzachar@gmail.com 	int size;
636692d97c3Snir.tzachar@gmail.com 
637692d97c3Snir.tzachar@gmail.com 	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
6380954828fSArnaud Lacombe 			"%s - %s", config_filename, rootmenu.prompt->text);
639692d97c3Snir.tzachar@gmail.com 	if (size >= sizeof(menu_backtitle))
640692d97c3Snir.tzachar@gmail.com 		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
641692d97c3Snir.tzachar@gmail.com 
642692d97c3Snir.tzachar@gmail.com 	size = snprintf(filename, sizeof(filename), "%s", config_filename);
643692d97c3Snir.tzachar@gmail.com 	if (size >= sizeof(filename))
644692d97c3Snir.tzachar@gmail.com 		filename[sizeof(filename)-1] = '\0';
645692d97c3Snir.tzachar@gmail.com 	return menu_backtitle;
646692d97c3Snir.tzachar@gmail.com }
647692d97c3Snir.tzachar@gmail.com 
648692d97c3Snir.tzachar@gmail.com /* return = 0 means we are successful.
649692d97c3Snir.tzachar@gmail.com  * -1 means go on doing what you were doing
650692d97c3Snir.tzachar@gmail.com  */
651692d97c3Snir.tzachar@gmail.com static int do_exit(void)
652692d97c3Snir.tzachar@gmail.com {
653692d97c3Snir.tzachar@gmail.com 	int res;
654692d97c3Snir.tzachar@gmail.com 	if (!conf_get_changed()) {
655692d97c3Snir.tzachar@gmail.com 		global_exit = 1;
656692d97c3Snir.tzachar@gmail.com 		return 0;
657692d97c3Snir.tzachar@gmail.com 	}
658692d97c3Snir.tzachar@gmail.com 	res = btn_dialog(main_window,
659652cf982SArnaud Lacombe 			_("Do you wish to save your new configuration?\n"
660692d97c3Snir.tzachar@gmail.com 				"<ESC> to cancel and resume nconfig."),
661692d97c3Snir.tzachar@gmail.com 			2,
662692d97c3Snir.tzachar@gmail.com 			"   <save>   ",
663692d97c3Snir.tzachar@gmail.com 			"<don't save>");
664692d97c3Snir.tzachar@gmail.com 	if (res == KEY_EXIT) {
665692d97c3Snir.tzachar@gmail.com 		global_exit = 0;
666692d97c3Snir.tzachar@gmail.com 		return -1;
667692d97c3Snir.tzachar@gmail.com 	}
668692d97c3Snir.tzachar@gmail.com 
669692d97c3Snir.tzachar@gmail.com 	/* if we got here, the user really wants to exit */
670692d97c3Snir.tzachar@gmail.com 	switch (res) {
671692d97c3Snir.tzachar@gmail.com 	case 0:
672692d97c3Snir.tzachar@gmail.com 		res = conf_write(filename);
673692d97c3Snir.tzachar@gmail.com 		if (res)
674692d97c3Snir.tzachar@gmail.com 			btn_dialog(
675692d97c3Snir.tzachar@gmail.com 				main_window,
676652cf982SArnaud Lacombe 				_("Error during writing of configuration.\n"
677652cf982SArnaud Lacombe 				  "Your configuration changes were NOT saved."),
678692d97c3Snir.tzachar@gmail.com 				  1,
679692d97c3Snir.tzachar@gmail.com 				  "<OK>");
680692d97c3Snir.tzachar@gmail.com 		break;
681692d97c3Snir.tzachar@gmail.com 	default:
682692d97c3Snir.tzachar@gmail.com 		btn_dialog(
683692d97c3Snir.tzachar@gmail.com 			main_window,
684652cf982SArnaud Lacombe 			_("Your configuration changes were NOT saved."),
685692d97c3Snir.tzachar@gmail.com 			1,
686692d97c3Snir.tzachar@gmail.com 			"<OK>");
687692d97c3Snir.tzachar@gmail.com 		break;
688692d97c3Snir.tzachar@gmail.com 	}
689692d97c3Snir.tzachar@gmail.com 	global_exit = 1;
690692d97c3Snir.tzachar@gmail.com 	return 0;
691692d97c3Snir.tzachar@gmail.com }
692692d97c3Snir.tzachar@gmail.com 
693692d97c3Snir.tzachar@gmail.com 
694692d97c3Snir.tzachar@gmail.com static void search_conf(void)
695692d97c3Snir.tzachar@gmail.com {
696692d97c3Snir.tzachar@gmail.com 	struct symbol **sym_arr;
697692d97c3Snir.tzachar@gmail.com 	struct gstr res;
698692d97c3Snir.tzachar@gmail.com 	char dialog_input_result[100];
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_ "\")"),
706692d97c3Snir.tzachar@gmail.com 			"", dialog_input_result, 99);
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);
724692d97c3Snir.tzachar@gmail.com 	res = get_relations_str(sym_arr);
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 	struct menu *active_menu = NULL;
1071692d97c3Snir.tzachar@gmail.com 	int res;
1072692d97c3Snir.tzachar@gmail.com 	int current_index = 0;
1073692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1074a72f3e2bSNir Tzachar 	struct match_state match_state = {
1075a72f3e2bSNir Tzachar 		.in_search = 0,
1076a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1077a72f3e2bSNir Tzachar 		.pattern = "",
1078a72f3e2bSNir Tzachar 	};
1079692d97c3Snir.tzachar@gmail.com 
1080692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1081692d97c3Snir.tzachar@gmail.com 		reset_menu();
1082692d97c3Snir.tzachar@gmail.com 		current_menu = menu;
1083692d97c3Snir.tzachar@gmail.com 		build_conf(menu);
1084692d97c3Snir.tzachar@gmail.com 		if (!child_count)
1085692d97c3Snir.tzachar@gmail.com 			break;
1086692d97c3Snir.tzachar@gmail.com 
1087692d97c3Snir.tzachar@gmail.com 		show_menu(prompt ? _(prompt) : _("Main Menu"),
1088692d97c3Snir.tzachar@gmail.com 				_(menu_instructions),
1089692d97c3Snir.tzachar@gmail.com 				current_index, &last_top_row);
1090692d97c3Snir.tzachar@gmail.com 		keypad((menu_win(curses_menu)), TRUE);
1091a72f3e2bSNir Tzachar 		while (!global_exit) {
1092a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1093a72f3e2bSNir Tzachar 				mvprintw(0, 0,
1094a72f3e2bSNir Tzachar 					"searching: %s", match_state.pattern);
1095a72f3e2bSNir Tzachar 				clrtoeol();
1096a72f3e2bSNir Tzachar 			}
1097a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1098a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1099a72f3e2bSNir Tzachar 			if (!res)
1100a72f3e2bSNir Tzachar 				break;
1101a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &current_index) == 0) {
1102a72f3e2bSNir Tzachar 				if (current_index != -1)
1103a72f3e2bSNir Tzachar 					center_item(current_index,
1104a72f3e2bSNir Tzachar 						    &last_top_row);
1105a72f3e2bSNir Tzachar 				continue;
1106a72f3e2bSNir Tzachar 			}
1107692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(&res,
1108692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1109692d97c3Snir.tzachar@gmail.com 				break;
1110692d97c3Snir.tzachar@gmail.com 			switch (res) {
1111692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
1112692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1113692d97c3Snir.tzachar@gmail.com 				break;
1114692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
1115692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1116692d97c3Snir.tzachar@gmail.com 				break;
1117692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1118692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1119692d97c3Snir.tzachar@gmail.com 				break;
1120692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1121692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1122692d97c3Snir.tzachar@gmail.com 				break;
1123692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1124692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1125692d97c3Snir.tzachar@gmail.com 				break;
1126692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1127692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1128692d97c3Snir.tzachar@gmail.com 				break;
1129692d97c3Snir.tzachar@gmail.com 			case 'h':
1130692d97c3Snir.tzachar@gmail.com 			case '?':
1131692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1132692d97c3Snir.tzachar@gmail.com 				break;
1133692d97c3Snir.tzachar@gmail.com 			}
1134692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 ||
1135692d97c3Snir.tzachar@gmail.com 				res == 32 || res == 'n' || res == 'y' ||
1136692d97c3Snir.tzachar@gmail.com 				res == KEY_LEFT || res == KEY_RIGHT ||
1137a72f3e2bSNir Tzachar 				res == 'm')
1138692d97c3Snir.tzachar@gmail.com 				break;
1139692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1140692d97c3Snir.tzachar@gmail.com 		}
1141692d97c3Snir.tzachar@gmail.com 
1142692d97c3Snir.tzachar@gmail.com 		refresh_all_windows(main_window);
1143692d97c3Snir.tzachar@gmail.com 		/* if ESC or left*/
1144692d97c3Snir.tzachar@gmail.com 		if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1145692d97c3Snir.tzachar@gmail.com 			break;
1146692d97c3Snir.tzachar@gmail.com 
1147692d97c3Snir.tzachar@gmail.com 		/* remember location in the menu */
1148692d97c3Snir.tzachar@gmail.com 		last_top_row = top_row(curses_menu);
1149692d97c3Snir.tzachar@gmail.com 		current_index = curses_item_index();
1150692d97c3Snir.tzachar@gmail.com 
1151692d97c3Snir.tzachar@gmail.com 		if (!item_tag())
1152692d97c3Snir.tzachar@gmail.com 			continue;
1153692d97c3Snir.tzachar@gmail.com 
1154692d97c3Snir.tzachar@gmail.com 		submenu = (struct menu *) item_data();
1155692d97c3Snir.tzachar@gmail.com 		active_menu = (struct menu *)item_data();
1156692d97c3Snir.tzachar@gmail.com 		if (!submenu || !menu_is_visible(submenu))
1157692d97c3Snir.tzachar@gmail.com 			continue;
1158692d97c3Snir.tzachar@gmail.com 		if (submenu)
1159692d97c3Snir.tzachar@gmail.com 			sym = submenu->sym;
1160692d97c3Snir.tzachar@gmail.com 		else
1161692d97c3Snir.tzachar@gmail.com 			sym = NULL;
1162692d97c3Snir.tzachar@gmail.com 
1163692d97c3Snir.tzachar@gmail.com 		switch (res) {
1164692d97c3Snir.tzachar@gmail.com 		case ' ':
1165692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1166692d97c3Snir.tzachar@gmail.com 				sym_toggle_tristate_value(sym);
1167692d97c3Snir.tzachar@gmail.com 			else if (item_is_tag('m'))
1168692d97c3Snir.tzachar@gmail.com 				conf(submenu);
1169692d97c3Snir.tzachar@gmail.com 			break;
1170692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1171692d97c3Snir.tzachar@gmail.com 		case 10: /* ENTER WAS PRESSED */
1172692d97c3Snir.tzachar@gmail.com 			switch (item_tag()) {
1173692d97c3Snir.tzachar@gmail.com 			case 'm':
1174692d97c3Snir.tzachar@gmail.com 				if (single_menu_mode)
1175692d97c3Snir.tzachar@gmail.com 					submenu->data =
1176692d97c3Snir.tzachar@gmail.com 						(void *) (long) !submenu->data;
1177692d97c3Snir.tzachar@gmail.com 				else
1178692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1179692d97c3Snir.tzachar@gmail.com 				break;
1180692d97c3Snir.tzachar@gmail.com 			case 't':
1181692d97c3Snir.tzachar@gmail.com 				if (sym_is_choice(sym) &&
1182692d97c3Snir.tzachar@gmail.com 				    sym_get_tristate_value(sym) == yes)
1183692d97c3Snir.tzachar@gmail.com 					conf_choice(submenu);
1184692d97c3Snir.tzachar@gmail.com 				else if (submenu->prompt &&
1185692d97c3Snir.tzachar@gmail.com 					 submenu->prompt->type == P_MENU)
1186692d97c3Snir.tzachar@gmail.com 					conf(submenu);
1187692d97c3Snir.tzachar@gmail.com 				else if (res == 10)
1188692d97c3Snir.tzachar@gmail.com 					sym_toggle_tristate_value(sym);
1189692d97c3Snir.tzachar@gmail.com 				break;
1190692d97c3Snir.tzachar@gmail.com 			case 's':
1191692d97c3Snir.tzachar@gmail.com 				conf_string(submenu);
1192692d97c3Snir.tzachar@gmail.com 				break;
1193692d97c3Snir.tzachar@gmail.com 			}
1194692d97c3Snir.tzachar@gmail.com 			break;
1195692d97c3Snir.tzachar@gmail.com 		case 'y':
1196692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t')) {
1197692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, yes))
1198692d97c3Snir.tzachar@gmail.com 					break;
1199692d97c3Snir.tzachar@gmail.com 				if (sym_set_tristate_value(sym, mod))
1200692d97c3Snir.tzachar@gmail.com 					btn_dialog(main_window, setmod_text, 0);
1201692d97c3Snir.tzachar@gmail.com 			}
1202692d97c3Snir.tzachar@gmail.com 			break;
1203692d97c3Snir.tzachar@gmail.com 		case 'n':
1204692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1205692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, no);
1206692d97c3Snir.tzachar@gmail.com 			break;
1207692d97c3Snir.tzachar@gmail.com 		case 'm':
1208692d97c3Snir.tzachar@gmail.com 			if (item_is_tag('t'))
1209692d97c3Snir.tzachar@gmail.com 				sym_set_tristate_value(sym, mod);
1210692d97c3Snir.tzachar@gmail.com 			break;
1211692d97c3Snir.tzachar@gmail.com 		}
1212692d97c3Snir.tzachar@gmail.com 	}
1213692d97c3Snir.tzachar@gmail.com }
1214692d97c3Snir.tzachar@gmail.com 
121542368c37SMichal Marek static void conf_message_callback(const char *fmt, va_list ap)
121642368c37SMichal Marek {
121742368c37SMichal Marek 	char buf[1024];
121842368c37SMichal Marek 
121942368c37SMichal Marek 	vsnprintf(buf, sizeof(buf), fmt, ap);
122042368c37SMichal Marek 	btn_dialog(main_window, buf, 1, "<OK>");
122142368c37SMichal Marek }
122242368c37SMichal Marek 
1223692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu)
1224692d97c3Snir.tzachar@gmail.com {
1225692d97c3Snir.tzachar@gmail.com 	struct gstr help = str_new();
1226692d97c3Snir.tzachar@gmail.com 
1227692d97c3Snir.tzachar@gmail.com 	if (menu && menu->sym && menu_has_help(menu)) {
1228692d97c3Snir.tzachar@gmail.com 		if (menu->sym->name) {
1229ffb5957bSArnaud Lacombe 			str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name);
1230692d97c3Snir.tzachar@gmail.com 			str_append(&help, _(menu_get_help(menu)));
1231692d97c3Snir.tzachar@gmail.com 			str_append(&help, "\n");
1232692d97c3Snir.tzachar@gmail.com 			get_symbol_str(&help, menu->sym);
1233aee08ed4SStephen Boyd 		} else {
1234aee08ed4SStephen Boyd 			str_append(&help, _(menu_get_help(menu)));
1235692d97c3Snir.tzachar@gmail.com 		}
1236692d97c3Snir.tzachar@gmail.com 	} else {
1237692d97c3Snir.tzachar@gmail.com 		str_append(&help, nohelp_text);
1238692d97c3Snir.tzachar@gmail.com 	}
1239692d97c3Snir.tzachar@gmail.com 	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1240692d97c3Snir.tzachar@gmail.com 	str_free(&help);
1241692d97c3Snir.tzachar@gmail.com }
1242692d97c3Snir.tzachar@gmail.com 
1243692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu)
1244692d97c3Snir.tzachar@gmail.com {
1245692d97c3Snir.tzachar@gmail.com 	const char *prompt = _(menu_get_prompt(menu));
1246692d97c3Snir.tzachar@gmail.com 	struct menu *child = 0;
1247692d97c3Snir.tzachar@gmail.com 	struct symbol *active;
1248692d97c3Snir.tzachar@gmail.com 	int selected_index = 0;
1249692d97c3Snir.tzachar@gmail.com 	int last_top_row = 0;
1250692d97c3Snir.tzachar@gmail.com 	int res, i = 0;
1251a72f3e2bSNir Tzachar 	struct match_state match_state = {
1252a72f3e2bSNir Tzachar 		.in_search = 0,
1253a72f3e2bSNir Tzachar 		.match_direction = MATCH_TINKER_PATTERN_DOWN,
1254a72f3e2bSNir Tzachar 		.pattern = "",
1255a72f3e2bSNir Tzachar 	};
1256692d97c3Snir.tzachar@gmail.com 
1257692d97c3Snir.tzachar@gmail.com 	active = sym_get_choice_value(menu->sym);
1258692d97c3Snir.tzachar@gmail.com 	/* this is mostly duplicated from the conf() function. */
1259692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1260692d97c3Snir.tzachar@gmail.com 		reset_menu();
1261692d97c3Snir.tzachar@gmail.com 
1262692d97c3Snir.tzachar@gmail.com 		for (i = 0, child = menu->list; child; child = child->next) {
1263692d97c3Snir.tzachar@gmail.com 			if (!show_all_items && !menu_is_visible(child))
1264692d97c3Snir.tzachar@gmail.com 				continue;
1265692d97c3Snir.tzachar@gmail.com 
1266692d97c3Snir.tzachar@gmail.com 			if (child->sym == sym_get_choice_value(menu->sym))
1267692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "<X> %s",
1268692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(child)));
126939177ec3SPeter Korsgaard 			else if (child->sym)
1270692d97c3Snir.tzachar@gmail.com 				item_make(child, ':', "    %s",
1271692d97c3Snir.tzachar@gmail.com 						_(menu_get_prompt(child)));
127239177ec3SPeter Korsgaard 			else
127339177ec3SPeter Korsgaard 				item_make(child, ':', "*** %s ***",
127439177ec3SPeter Korsgaard 						_(menu_get_prompt(child)));
127539177ec3SPeter Korsgaard 
1276692d97c3Snir.tzachar@gmail.com 			if (child->sym == active){
1277692d97c3Snir.tzachar@gmail.com 				last_top_row = top_row(curses_menu);
1278692d97c3Snir.tzachar@gmail.com 				selected_index = i;
1279692d97c3Snir.tzachar@gmail.com 			}
1280692d97c3Snir.tzachar@gmail.com 			i++;
1281692d97c3Snir.tzachar@gmail.com 		}
1282692d97c3Snir.tzachar@gmail.com 		show_menu(prompt ? _(prompt) : _("Choice Menu"),
1283692d97c3Snir.tzachar@gmail.com 				_(radiolist_instructions),
1284692d97c3Snir.tzachar@gmail.com 				selected_index,
1285692d97c3Snir.tzachar@gmail.com 				&last_top_row);
1286a72f3e2bSNir Tzachar 		while (!global_exit) {
1287a72f3e2bSNir Tzachar 			if (match_state.in_search) {
1288a72f3e2bSNir Tzachar 				mvprintw(0, 0, "searching: %s",
1289a72f3e2bSNir Tzachar 					 match_state.pattern);
1290a72f3e2bSNir Tzachar 				clrtoeol();
1291a72f3e2bSNir Tzachar 			}
1292a72f3e2bSNir Tzachar 			refresh_all_windows(main_window);
1293a72f3e2bSNir Tzachar 			res = wgetch(menu_win(curses_menu));
1294a72f3e2bSNir Tzachar 			if (!res)
1295a72f3e2bSNir Tzachar 				break;
1296a72f3e2bSNir Tzachar 			if (do_match(res, &match_state, &selected_index) == 0) {
1297a72f3e2bSNir Tzachar 				if (selected_index != -1)
1298a72f3e2bSNir Tzachar 					center_item(selected_index,
1299a72f3e2bSNir Tzachar 						    &last_top_row);
1300a72f3e2bSNir Tzachar 				continue;
1301a72f3e2bSNir Tzachar 			}
1302692d97c3Snir.tzachar@gmail.com 			if (process_special_keys(
1303692d97c3Snir.tzachar@gmail.com 						&res,
1304692d97c3Snir.tzachar@gmail.com 						(struct menu *) item_data()))
1305692d97c3Snir.tzachar@gmail.com 				break;
1306692d97c3Snir.tzachar@gmail.com 			switch (res) {
1307692d97c3Snir.tzachar@gmail.com 			case KEY_DOWN:
1308692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_DOWN_ITEM);
1309692d97c3Snir.tzachar@gmail.com 				break;
1310692d97c3Snir.tzachar@gmail.com 			case KEY_UP:
1311692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_UP_ITEM);
1312692d97c3Snir.tzachar@gmail.com 				break;
1313692d97c3Snir.tzachar@gmail.com 			case KEY_NPAGE:
1314692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_DPAGE);
1315692d97c3Snir.tzachar@gmail.com 				break;
1316692d97c3Snir.tzachar@gmail.com 			case KEY_PPAGE:
1317692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_SCR_UPAGE);
1318692d97c3Snir.tzachar@gmail.com 				break;
1319692d97c3Snir.tzachar@gmail.com 			case KEY_HOME:
1320692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_FIRST_ITEM);
1321692d97c3Snir.tzachar@gmail.com 				break;
1322692d97c3Snir.tzachar@gmail.com 			case KEY_END:
1323692d97c3Snir.tzachar@gmail.com 				menu_driver(curses_menu, REQ_LAST_ITEM);
1324692d97c3Snir.tzachar@gmail.com 				break;
1325692d97c3Snir.tzachar@gmail.com 			case 'h':
1326692d97c3Snir.tzachar@gmail.com 			case '?':
1327692d97c3Snir.tzachar@gmail.com 				show_help((struct menu *) item_data());
1328692d97c3Snir.tzachar@gmail.com 				break;
1329692d97c3Snir.tzachar@gmail.com 			}
1330692d97c3Snir.tzachar@gmail.com 			if (res == 10 || res == 27 || res == ' ' ||
1331a72f3e2bSNir Tzachar 					res == KEY_LEFT){
1332692d97c3Snir.tzachar@gmail.com 				break;
1333692d97c3Snir.tzachar@gmail.com 			}
1334692d97c3Snir.tzachar@gmail.com 			refresh_all_windows(main_window);
1335692d97c3Snir.tzachar@gmail.com 		}
1336692d97c3Snir.tzachar@gmail.com 		/* if ESC or left */
1337692d97c3Snir.tzachar@gmail.com 		if (res == 27 || res == KEY_LEFT)
1338692d97c3Snir.tzachar@gmail.com 			break;
1339692d97c3Snir.tzachar@gmail.com 
1340692d97c3Snir.tzachar@gmail.com 		child = item_data();
134139177ec3SPeter Korsgaard 		if (!child || !menu_is_visible(child) || !child->sym)
1342692d97c3Snir.tzachar@gmail.com 			continue;
1343692d97c3Snir.tzachar@gmail.com 		switch (res) {
1344692d97c3Snir.tzachar@gmail.com 		case ' ':
1345692d97c3Snir.tzachar@gmail.com 		case  10:
1346692d97c3Snir.tzachar@gmail.com 		case KEY_RIGHT:
1347692d97c3Snir.tzachar@gmail.com 			sym_set_tristate_value(child->sym, yes);
1348692d97c3Snir.tzachar@gmail.com 			return;
1349692d97c3Snir.tzachar@gmail.com 		case 'h':
1350692d97c3Snir.tzachar@gmail.com 		case '?':
1351692d97c3Snir.tzachar@gmail.com 			show_help(child);
1352692d97c3Snir.tzachar@gmail.com 			active = child->sym;
1353692d97c3Snir.tzachar@gmail.com 			break;
1354692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1355692d97c3Snir.tzachar@gmail.com 			return;
1356692d97c3Snir.tzachar@gmail.com 		}
1357692d97c3Snir.tzachar@gmail.com 	}
1358692d97c3Snir.tzachar@gmail.com }
1359692d97c3Snir.tzachar@gmail.com 
1360692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu)
1361692d97c3Snir.tzachar@gmail.com {
1362692d97c3Snir.tzachar@gmail.com 	const char *prompt = menu_get_prompt(menu);
1363692d97c3Snir.tzachar@gmail.com 	char dialog_input_result[256];
1364692d97c3Snir.tzachar@gmail.com 
1365692d97c3Snir.tzachar@gmail.com 	while (1) {
1366692d97c3Snir.tzachar@gmail.com 		int res;
1367692d97c3Snir.tzachar@gmail.com 		const char *heading;
1368692d97c3Snir.tzachar@gmail.com 
1369692d97c3Snir.tzachar@gmail.com 		switch (sym_get_type(menu->sym)) {
1370692d97c3Snir.tzachar@gmail.com 		case S_INT:
1371692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_int);
1372692d97c3Snir.tzachar@gmail.com 			break;
1373692d97c3Snir.tzachar@gmail.com 		case S_HEX:
1374692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_hex);
1375692d97c3Snir.tzachar@gmail.com 			break;
1376692d97c3Snir.tzachar@gmail.com 		case S_STRING:
1377692d97c3Snir.tzachar@gmail.com 			heading = _(inputbox_instructions_string);
1378692d97c3Snir.tzachar@gmail.com 			break;
1379692d97c3Snir.tzachar@gmail.com 		default:
1380692d97c3Snir.tzachar@gmail.com 			heading = _("Internal nconf error!");
1381692d97c3Snir.tzachar@gmail.com 		}
1382692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1383692d97c3Snir.tzachar@gmail.com 				prompt ? _(prompt) : _("Main Menu"),
1384692d97c3Snir.tzachar@gmail.com 				heading,
1385692d97c3Snir.tzachar@gmail.com 				sym_get_string_value(menu->sym),
1386692d97c3Snir.tzachar@gmail.com 				dialog_input_result,
1387692d97c3Snir.tzachar@gmail.com 				sizeof(dialog_input_result));
1388692d97c3Snir.tzachar@gmail.com 		switch (res) {
1389692d97c3Snir.tzachar@gmail.com 		case 0:
1390692d97c3Snir.tzachar@gmail.com 			if (sym_set_string_value(menu->sym,
1391692d97c3Snir.tzachar@gmail.com 						dialog_input_result))
1392692d97c3Snir.tzachar@gmail.com 				return;
1393692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window,
1394692d97c3Snir.tzachar@gmail.com 				_("You have made an invalid entry."), 0);
1395692d97c3Snir.tzachar@gmail.com 			break;
1396692d97c3Snir.tzachar@gmail.com 		case 1:
1397692d97c3Snir.tzachar@gmail.com 			show_help(menu);
1398692d97c3Snir.tzachar@gmail.com 			break;
1399692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1400692d97c3Snir.tzachar@gmail.com 			return;
1401692d97c3Snir.tzachar@gmail.com 		}
1402692d97c3Snir.tzachar@gmail.com 	}
1403692d97c3Snir.tzachar@gmail.com }
1404692d97c3Snir.tzachar@gmail.com 
1405692d97c3Snir.tzachar@gmail.com static void conf_load(void)
1406692d97c3Snir.tzachar@gmail.com {
1407692d97c3Snir.tzachar@gmail.com 	char dialog_input_result[256];
1408692d97c3Snir.tzachar@gmail.com 	while (1) {
1409692d97c3Snir.tzachar@gmail.com 		int res;
1410692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1411692d97c3Snir.tzachar@gmail.com 				NULL, load_config_text,
1412692d97c3Snir.tzachar@gmail.com 				filename,
1413692d97c3Snir.tzachar@gmail.com 				dialog_input_result,
1414692d97c3Snir.tzachar@gmail.com 				sizeof(dialog_input_result));
1415692d97c3Snir.tzachar@gmail.com 		switch (res) {
1416692d97c3Snir.tzachar@gmail.com 		case 0:
1417692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1418692d97c3Snir.tzachar@gmail.com 				return;
1419692d97c3Snir.tzachar@gmail.com 			if (!conf_read(dialog_input_result)) {
1420692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
1421692d97c3Snir.tzachar@gmail.com 				sym_set_change_count(1);
1422692d97c3Snir.tzachar@gmail.com 				return;
1423692d97c3Snir.tzachar@gmail.com 			}
1424692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window, _("File does not exist!"), 0);
1425692d97c3Snir.tzachar@gmail.com 			break;
1426692d97c3Snir.tzachar@gmail.com 		case 1:
1427692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1428692d97c3Snir.tzachar@gmail.com 					_("Load Alternate Configuration"),
1429692d97c3Snir.tzachar@gmail.com 					load_config_help);
1430692d97c3Snir.tzachar@gmail.com 			break;
1431692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1432692d97c3Snir.tzachar@gmail.com 			return;
1433692d97c3Snir.tzachar@gmail.com 		}
1434692d97c3Snir.tzachar@gmail.com 	}
1435692d97c3Snir.tzachar@gmail.com }
1436692d97c3Snir.tzachar@gmail.com 
1437692d97c3Snir.tzachar@gmail.com static void conf_save(void)
1438692d97c3Snir.tzachar@gmail.com {
1439692d97c3Snir.tzachar@gmail.com 	char dialog_input_result[256];
1440692d97c3Snir.tzachar@gmail.com 	while (1) {
1441692d97c3Snir.tzachar@gmail.com 		int res;
1442692d97c3Snir.tzachar@gmail.com 		res = dialog_inputbox(main_window,
1443692d97c3Snir.tzachar@gmail.com 				NULL, save_config_text,
1444692d97c3Snir.tzachar@gmail.com 				filename,
1445692d97c3Snir.tzachar@gmail.com 				dialog_input_result,
1446692d97c3Snir.tzachar@gmail.com 				sizeof(dialog_input_result));
1447692d97c3Snir.tzachar@gmail.com 		switch (res) {
1448692d97c3Snir.tzachar@gmail.com 		case 0:
1449692d97c3Snir.tzachar@gmail.com 			if (!dialog_input_result[0])
1450692d97c3Snir.tzachar@gmail.com 				return;
1451692d97c3Snir.tzachar@gmail.com 			res = conf_write(dialog_input_result);
1452692d97c3Snir.tzachar@gmail.com 			if (!res) {
1453692d97c3Snir.tzachar@gmail.com 				set_config_filename(dialog_input_result);
1454692d97c3Snir.tzachar@gmail.com 				return;
1455692d97c3Snir.tzachar@gmail.com 			}
1456692d97c3Snir.tzachar@gmail.com 			btn_dialog(main_window, _("Can't create file! "
1457692d97c3Snir.tzachar@gmail.com 				"Probably a nonexistent directory."),
1458692d97c3Snir.tzachar@gmail.com 				1, "<OK>");
1459692d97c3Snir.tzachar@gmail.com 			break;
1460692d97c3Snir.tzachar@gmail.com 		case 1:
1461692d97c3Snir.tzachar@gmail.com 			show_scroll_win(main_window,
1462692d97c3Snir.tzachar@gmail.com 				_("Save Alternate Configuration"),
1463692d97c3Snir.tzachar@gmail.com 				save_config_help);
1464692d97c3Snir.tzachar@gmail.com 			break;
1465692d97c3Snir.tzachar@gmail.com 		case KEY_EXIT:
1466692d97c3Snir.tzachar@gmail.com 			return;
1467692d97c3Snir.tzachar@gmail.com 		}
1468692d97c3Snir.tzachar@gmail.com 	}
1469692d97c3Snir.tzachar@gmail.com }
1470692d97c3Snir.tzachar@gmail.com 
1471692d97c3Snir.tzachar@gmail.com void setup_windows(void)
1472692d97c3Snir.tzachar@gmail.com {
1473692d97c3Snir.tzachar@gmail.com 	if (main_window != NULL)
1474692d97c3Snir.tzachar@gmail.com 		delwin(main_window);
1475692d97c3Snir.tzachar@gmail.com 
1476692d97c3Snir.tzachar@gmail.com 	/* set up the menu and menu window */
1477692d97c3Snir.tzachar@gmail.com 	main_window = newwin(LINES-2, COLS-2, 2, 1);
1478692d97c3Snir.tzachar@gmail.com 	keypad(main_window, TRUE);
1479a72f3e2bSNir Tzachar 	mwin_max_lines = LINES-7;
1480692d97c3Snir.tzachar@gmail.com 	mwin_max_cols = COLS-6;
1481692d97c3Snir.tzachar@gmail.com 
1482692d97c3Snir.tzachar@gmail.com 	/* panels order is from bottom to top */
1483692d97c3Snir.tzachar@gmail.com 	new_panel(main_window);
1484692d97c3Snir.tzachar@gmail.com }
1485692d97c3Snir.tzachar@gmail.com 
1486692d97c3Snir.tzachar@gmail.com int main(int ac, char **av)
1487692d97c3Snir.tzachar@gmail.com {
1488692d97c3Snir.tzachar@gmail.com 	char *mode;
1489692d97c3Snir.tzachar@gmail.com 
1490692d97c3Snir.tzachar@gmail.com 	setlocale(LC_ALL, "");
1491692d97c3Snir.tzachar@gmail.com 	bindtextdomain(PACKAGE, LOCALEDIR);
1492692d97c3Snir.tzachar@gmail.com 	textdomain(PACKAGE);
1493692d97c3Snir.tzachar@gmail.com 
1494692d97c3Snir.tzachar@gmail.com 	conf_parse(av[1]);
1495692d97c3Snir.tzachar@gmail.com 	conf_read(NULL);
1496692d97c3Snir.tzachar@gmail.com 
1497692d97c3Snir.tzachar@gmail.com 	mode = getenv("NCONFIG_MODE");
1498692d97c3Snir.tzachar@gmail.com 	if (mode) {
1499692d97c3Snir.tzachar@gmail.com 		if (!strcasecmp(mode, "single_menu"))
1500692d97c3Snir.tzachar@gmail.com 			single_menu_mode = 1;
1501692d97c3Snir.tzachar@gmail.com 	}
1502692d97c3Snir.tzachar@gmail.com 
1503692d97c3Snir.tzachar@gmail.com 	/* Initialize curses */
1504692d97c3Snir.tzachar@gmail.com 	initscr();
1505692d97c3Snir.tzachar@gmail.com 	/* set color theme */
1506692d97c3Snir.tzachar@gmail.com 	set_colors();
1507692d97c3Snir.tzachar@gmail.com 
1508692d97c3Snir.tzachar@gmail.com 	cbreak();
1509692d97c3Snir.tzachar@gmail.com 	noecho();
1510692d97c3Snir.tzachar@gmail.com 	keypad(stdscr, TRUE);
1511692d97c3Snir.tzachar@gmail.com 	curs_set(0);
1512692d97c3Snir.tzachar@gmail.com 
1513692d97c3Snir.tzachar@gmail.com 	if (COLS < 75 || LINES < 20) {
1514692d97c3Snir.tzachar@gmail.com 		endwin();
1515692d97c3Snir.tzachar@gmail.com 		printf("Your terminal should have at "
1516692d97c3Snir.tzachar@gmail.com 			"least 20 lines and 75 columns\n");
1517692d97c3Snir.tzachar@gmail.com 		return 1;
1518692d97c3Snir.tzachar@gmail.com 	}
1519692d97c3Snir.tzachar@gmail.com 
1520692d97c3Snir.tzachar@gmail.com 	notimeout(stdscr, FALSE);
1521692d97c3Snir.tzachar@gmail.com 	ESCDELAY = 1;
1522692d97c3Snir.tzachar@gmail.com 
1523692d97c3Snir.tzachar@gmail.com 	/* set btns menu */
1524692d97c3Snir.tzachar@gmail.com 	curses_menu = new_menu(curses_menu_items);
1525692d97c3Snir.tzachar@gmail.com 	menu_opts_off(curses_menu, O_SHOWDESC);
1526a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_SHOWMATCH);
1527692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_ONEVALUE);
1528692d97c3Snir.tzachar@gmail.com 	menu_opts_on(curses_menu, O_NONCYCLIC);
1529a72f3e2bSNir Tzachar 	menu_opts_on(curses_menu, O_IGNORECASE);
1530692d97c3Snir.tzachar@gmail.com 	set_menu_mark(curses_menu, " ");
1531692d97c3Snir.tzachar@gmail.com 	set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1532692d97c3Snir.tzachar@gmail.com 	set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1533692d97c3Snir.tzachar@gmail.com 	set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1534692d97c3Snir.tzachar@gmail.com 
1535692d97c3Snir.tzachar@gmail.com 	set_config_filename(conf_get_configname());
1536692d97c3Snir.tzachar@gmail.com 	setup_windows();
1537692d97c3Snir.tzachar@gmail.com 
1538692d97c3Snir.tzachar@gmail.com 	/* check for KEY_FUNC(1) */
1539692d97c3Snir.tzachar@gmail.com 	if (has_key(KEY_F(1)) == FALSE) {
1540692d97c3Snir.tzachar@gmail.com 		show_scroll_win(main_window,
1541692d97c3Snir.tzachar@gmail.com 				_("Instructions"),
1542692d97c3Snir.tzachar@gmail.com 				_(menu_no_f_instructions));
1543692d97c3Snir.tzachar@gmail.com 	}
1544692d97c3Snir.tzachar@gmail.com 
154542368c37SMichal Marek 	conf_set_message_callback(conf_message_callback);
1546692d97c3Snir.tzachar@gmail.com 	/* do the work */
1547692d97c3Snir.tzachar@gmail.com 	while (!global_exit) {
1548692d97c3Snir.tzachar@gmail.com 		conf(&rootmenu);
1549692d97c3Snir.tzachar@gmail.com 		if (!global_exit && do_exit() == 0)
1550692d97c3Snir.tzachar@gmail.com 			break;
1551692d97c3Snir.tzachar@gmail.com 	}
1552692d97c3Snir.tzachar@gmail.com 	/* ok, we are done */
1553692d97c3Snir.tzachar@gmail.com 	unpost_menu(curses_menu);
1554692d97c3Snir.tzachar@gmail.com 	free_menu(curses_menu);
1555692d97c3Snir.tzachar@gmail.com 	delwin(main_window);
1556692d97c3Snir.tzachar@gmail.com 	clear();
1557692d97c3Snir.tzachar@gmail.com 	refresh();
1558692d97c3Snir.tzachar@gmail.com 	endwin();
1559692d97c3Snir.tzachar@gmail.com 	return 0;
1560692d97c3Snir.tzachar@gmail.com }
1561692d97c3Snir.tzachar@gmail.com 
1562