yann@2454
|
1 |
/*
|
yann@2454
|
2 |
* Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
|
yann@2454
|
3 |
* Released under the terms of the GNU GPL v2.0.
|
yann@2454
|
4 |
*
|
yann@2454
|
5 |
* Derived from menuconfig.
|
yann@2454
|
6 |
*
|
yann@2454
|
7 |
*/
|
yann@2454
|
8 |
#define _GNU_SOURCE
|
yann@2454
|
9 |
#include <string.h>
|
yann@2454
|
10 |
#define LKC_DIRECT_LINK
|
yann@2454
|
11 |
#include "lkc.h"
|
yann@2454
|
12 |
#include "nconf.h"
|
yann@2454
|
13 |
#include <ctype.h>
|
yann@2454
|
14 |
|
yann@2454
|
15 |
static const char nconf_readme[] = N_(
|
yann@2454
|
16 |
"Overview\n"
|
yann@2454
|
17 |
"--------\n"
|
yann@2454
|
18 |
"This interface let you select features and parameters for the build.\n"
|
yann@2454
|
19 |
"Features can either be built-in, modularized, or ignored. Parameters\n"
|
yann@2454
|
20 |
"must be entered in as decimal or hexadecimal numbers or text.\n"
|
yann@2454
|
21 |
"\n"
|
yann@2454
|
22 |
"Menu items beginning with following braces represent features that\n"
|
yann@2454
|
23 |
" [ ] can be built in or removed\n"
|
yann@2454
|
24 |
" < > can be built in, modularized or removed\n"
|
yann@2454
|
25 |
" { } can be built in or modularized (selected by other feature)\n"
|
yann@2454
|
26 |
" - - are selected by other feature,\n"
|
yann@2454
|
27 |
" XXX cannot be selected. Use Symbol Info to find out why,\n"
|
yann@2454
|
28 |
"while *, M or whitespace inside braces means to build in, build as\n"
|
yann@2454
|
29 |
"a module or to exclude the feature respectively.\n"
|
yann@2454
|
30 |
"\n"
|
yann@2454
|
31 |
"To change any of these features, highlight it with the cursor\n"
|
yann@2454
|
32 |
"keys and press <Y> to build it in, <M> to make it a module or\n"
|
yann@2454
|
33 |
"<N> to removed it. You may also press the <Space Bar> to cycle\n"
|
yann@2454
|
34 |
"through the available options (ie. Y->N->M->Y).\n"
|
yann@2454
|
35 |
"\n"
|
yann@2454
|
36 |
"Some additional keyboard hints:\n"
|
yann@2454
|
37 |
"\n"
|
yann@2454
|
38 |
"Menus\n"
|
yann@2454
|
39 |
"----------\n"
|
yann@2454
|
40 |
"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
|
yann@2454
|
41 |
" you wish to change use <Enter> or <Space>. Goto submenu by \n"
|
yann@2454
|
42 |
" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
|
yann@2454
|
43 |
" Submenus are designated by \"--->\".\n"
|
yann@2454
|
44 |
"\n"
|
yann@2454
|
45 |
" Searching: pressing '/' triggers interactive search mode.\n"
|
yann@2454
|
46 |
" nconfig performs a case insensitive search for the string\n"
|
yann@2454
|
47 |
" in the menu prompts (no regex support).\n"
|
yann@2454
|
48 |
" Pressing the up/down keys highlights the previous/next\n"
|
yann@2454
|
49 |
" matching item. Backspace removes one character from the\n"
|
yann@2454
|
50 |
" match string. Pressing either '/' again or ESC exits\n"
|
yann@2454
|
51 |
" search mode. All other keys behave normally.\n"
|
yann@2454
|
52 |
"\n"
|
yann@2454
|
53 |
" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
|
yann@2454
|
54 |
" unseen options into view.\n"
|
yann@2454
|
55 |
"\n"
|
yann@2454
|
56 |
"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
|
yann@2454
|
57 |
"\n"
|
yann@2454
|
58 |
"o To get help with an item, press <F1>\n"
|
yann@2454
|
59 |
" Shortcut: Press <h> or <?>.\n"
|
yann@2454
|
60 |
"\n"
|
yann@2454
|
61 |
"\n"
|
yann@2454
|
62 |
"Radiolists (Choice lists)\n"
|
yann@2454
|
63 |
"-----------\n"
|
yann@2454
|
64 |
"o Use the cursor keys to select the option you wish to set and press\n"
|
yann@2454
|
65 |
" <S> or the <SPACE BAR>.\n"
|
yann@2454
|
66 |
"\n"
|
yann@2454
|
67 |
" Shortcut: Press the first letter of the option you wish to set then\n"
|
yann@2454
|
68 |
" press <S> or <SPACE BAR>.\n"
|
yann@2454
|
69 |
"\n"
|
yann@2454
|
70 |
"o To see available help for the item, press <F1>\n"
|
yann@2454
|
71 |
" Shortcut: Press <H> or <?>.\n"
|
yann@2454
|
72 |
"\n"
|
yann@2454
|
73 |
"\n"
|
yann@2454
|
74 |
"Data Entry\n"
|
yann@2454
|
75 |
"-----------\n"
|
yann@2454
|
76 |
"o Enter the requested information and press <ENTER>\n"
|
yann@2454
|
77 |
" If you are entering hexadecimal values, it is not necessary to\n"
|
yann@2454
|
78 |
" add the '0x' prefix to the entry.\n"
|
yann@2454
|
79 |
"\n"
|
yann@2454
|
80 |
"o For help, press <F1>.\n"
|
yann@2454
|
81 |
"\n"
|
yann@2454
|
82 |
"\n"
|
yann@2454
|
83 |
"Text Box (Help Window)\n"
|
yann@2454
|
84 |
"--------\n"
|
yann@2454
|
85 |
"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
|
yann@2454
|
86 |
" keys h,j,k,l function here as do <SPACE BAR> for those\n"
|
yann@2454
|
87 |
" who are familiar with less and lynx.\n"
|
yann@2454
|
88 |
"\n"
|
yann@2454
|
89 |
"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
|
yann@2454
|
90 |
"\n"
|
yann@2454
|
91 |
"\n"
|
yann@2454
|
92 |
"Alternate Configuration Files\n"
|
yann@2454
|
93 |
"-----------------------------\n"
|
yann@2454
|
94 |
"nconfig supports the use of alternate configuration files for\n"
|
yann@2454
|
95 |
"those who, for various reasons, find it necessary to switch\n"
|
yann@2454
|
96 |
"between different configurations.\n"
|
yann@2454
|
97 |
"\n"
|
yann@2454
|
98 |
"At the end of the main menu you will find two options. One is\n"
|
yann@2454
|
99 |
"for saving the current configuration to a file of your choosing.\n"
|
yann@2454
|
100 |
"The other option is for loading a previously saved alternate\n"
|
yann@2454
|
101 |
"configuration.\n"
|
yann@2454
|
102 |
"\n"
|
yann@2454
|
103 |
"Even if you don't use alternate configuration files, but you\n"
|
yann@2454
|
104 |
"find during a nconfig session that you have completely messed\n"
|
yann@2454
|
105 |
"up your settings, you may use the \"Load Alternate...\" option to\n"
|
yann@2454
|
106 |
"restore your previously saved settings from \".config\" without\n"
|
yann@2454
|
107 |
"restarting nconfig.\n"
|
yann@2454
|
108 |
"\n"
|
yann@2454
|
109 |
"Other information\n"
|
yann@2454
|
110 |
"-----------------\n"
|
yann@2454
|
111 |
"If you use nconfig in an XTERM window make sure you have your\n"
|
yann@2454
|
112 |
"$TERM variable set to point to a xterm definition which supports color.\n"
|
yann@2454
|
113 |
"Otherwise, nconfig will look rather bad. nconfig will not\n"
|
yann@2454
|
114 |
"display correctly in a RXVT window because rxvt displays only one\n"
|
yann@2454
|
115 |
"intensity of color, bright.\n"
|
yann@2454
|
116 |
"\n"
|
yann@2454
|
117 |
"nconfig will display larger menus on screens or xterms which are\n"
|
yann@2454
|
118 |
"set to display more than the standard 25 row by 80 column geometry.\n"
|
yann@2454
|
119 |
"In order for this to work, the \"stty size\" command must be able to\n"
|
yann@2454
|
120 |
"display the screen's current row and column geometry. I STRONGLY\n"
|
yann@2454
|
121 |
"RECOMMEND that you make sure you do NOT have the shell variables\n"
|
yann@2454
|
122 |
"LINES and COLUMNS exported into your environment. Some distributions\n"
|
yann@2454
|
123 |
"export those variables via /etc/profile. Some ncurses programs can\n"
|
yann@2454
|
124 |
"become confused when those variables (LINES & COLUMNS) don't reflect\n"
|
yann@2454
|
125 |
"the true screen size.\n"
|
yann@2454
|
126 |
"\n"
|
yann@2454
|
127 |
"Optional personality available\n"
|
yann@2454
|
128 |
"------------------------------\n"
|
yann@2454
|
129 |
"If you prefer to have all of the options listed in a single menu, rather\n"
|
yann@2454
|
130 |
"than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n"
|
yann@2454
|
131 |
"environment variable set to single_menu. Example:\n"
|
yann@2454
|
132 |
"\n"
|
yann@2454
|
133 |
"make NCONFIG_MODE=single_menu nconfig\n"
|
yann@2454
|
134 |
"\n"
|
yann@2454
|
135 |
"<Enter> will then unroll the appropriate category, or enfold it if it\n"
|
yann@2454
|
136 |
"is already unrolled.\n"
|
yann@2454
|
137 |
"\n"
|
yann@2454
|
138 |
"Note that this mode can eventually be a little more CPU expensive\n"
|
yann@2454
|
139 |
"(especially with a larger number of unrolled categories) than the\n"
|
yann@2454
|
140 |
"default mode.\n"
|
yann@2454
|
141 |
"\n"),
|
yann@2454
|
142 |
menu_no_f_instructions[] = N_(
|
yann@2454
|
143 |
" You do not have function keys support. Please follow the\n"
|
yann@2454
|
144 |
" following instructions:\n"
|
yann@2454
|
145 |
" Arrow keys navigate the menu.\n"
|
yann@2454
|
146 |
" <Enter> or <right-arrow> selects submenus --->.\n"
|
yann@2454
|
147 |
" Capital Letters are hotkeys.\n"
|
yann@2454
|
148 |
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
|
yann@2454
|
149 |
" Pressing SpaceBar toggles between the above options.\n"
|
yann@2454
|
150 |
" Press <Esc> or <left-arrow> to go back one menu,\n"
|
yann@2454
|
151 |
" <?> or <h> for Help, </> for Search.\n"
|
yann@2454
|
152 |
" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
|
yann@2454
|
153 |
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
|
yann@2454
|
154 |
" <Esc> always leaves the current window.\n"),
|
yann@2454
|
155 |
menu_instructions[] = N_(
|
yann@2454
|
156 |
" Arrow keys navigate the menu.\n"
|
yann@2454
|
157 |
" <Enter> or <right-arrow> selects submenus --->.\n"
|
yann@2454
|
158 |
" Capital Letters are hotkeys.\n"
|
yann@2454
|
159 |
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
|
yann@2454
|
160 |
" Pressing SpaceBar toggles between the above options\n"
|
yann@2454
|
161 |
" Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
|
yann@2454
|
162 |
" <?>, <F1> or <h> for Help, </> for Search.\n"
|
yann@2454
|
163 |
" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
|
yann@2454
|
164 |
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
|
yann@2454
|
165 |
" <Esc> always leaves the current window\n"),
|
yann@2454
|
166 |
radiolist_instructions[] = N_(
|
yann@2454
|
167 |
" Use the arrow keys to navigate this window or\n"
|
yann@2454
|
168 |
" press the hotkey of the item you wish to select\n"
|
yann@2454
|
169 |
" followed by the <SPACE BAR>.\n"
|
yann@2454
|
170 |
" Press <?>, <F1> or <h> for additional information about this option.\n"),
|
yann@2454
|
171 |
inputbox_instructions_int[] = N_(
|
yann@2454
|
172 |
"Please enter a decimal value.\n"
|
yann@2454
|
173 |
"Fractions will not be accepted.\n"
|
yann@2454
|
174 |
"Press <RETURN> to accept, <ESC> to cancel."),
|
yann@2454
|
175 |
inputbox_instructions_hex[] = N_(
|
yann@2454
|
176 |
"Please enter a hexadecimal value.\n"
|
yann@2454
|
177 |
"Press <RETURN> to accept, <ESC> to cancel."),
|
yann@2454
|
178 |
inputbox_instructions_string[] = N_(
|
yann@2454
|
179 |
"Please enter a string value.\n"
|
yann@2454
|
180 |
"Press <RETURN> to accept, <ESC> to cancel."),
|
yann@2454
|
181 |
setmod_text[] = N_(
|
yann@2454
|
182 |
"This feature depends on another which\n"
|
yann@2454
|
183 |
"has been configured as a module.\n"
|
yann@2454
|
184 |
"As a result, this feature will be built as a module."),
|
yann@2454
|
185 |
nohelp_text[] = N_(
|
yann@2454
|
186 |
"There is no help available for this option.\n"),
|
yann@2454
|
187 |
load_config_text[] = N_(
|
yann@2454
|
188 |
"Enter the name of the configuration file you wish to load.\n"
|
yann@2454
|
189 |
"Accept the name shown to restore the configuration you\n"
|
yann@2454
|
190 |
"last retrieved. Leave blank to abort."),
|
yann@2454
|
191 |
load_config_help[] = N_(
|
yann@2454
|
192 |
"\n"
|
yann@2454
|
193 |
"For various reasons, one may wish to keep several different\n"
|
yann@2454
|
194 |
"configurations available on a single machine.\n"
|
yann@2454
|
195 |
"\n"
|
yann@2454
|
196 |
"If you have saved a previous configuration in a file other than the\n"
|
yann@2454
|
197 |
"default one, entering its name here will allow you to modify that\n"
|
yann@2454
|
198 |
"configuration.\n"
|
yann@2454
|
199 |
"\n"
|
yann@2454
|
200 |
"If you are uncertain, then you have probably never used alternate\n"
|
yann@2454
|
201 |
"configuration files. You should therefor leave this blank to abort.\n"),
|
yann@2454
|
202 |
save_config_text[] = N_(
|
yann@2454
|
203 |
"Enter a filename to which this configuration should be saved\n"
|
yann@2454
|
204 |
"as an alternate. Leave blank to abort."),
|
yann@2454
|
205 |
save_config_help[] = N_(
|
yann@2454
|
206 |
"\n"
|
yann@2454
|
207 |
"For various reasons, one may wish to keep different configurations\n"
|
yann@2454
|
208 |
"available on a single machine.\n"
|
yann@2454
|
209 |
"\n"
|
yann@2454
|
210 |
"Entering a file name here will allow you to later retrieve, modify\n"
|
yann@2454
|
211 |
"and use the current configuration as an alternate to whatever\n"
|
yann@2454
|
212 |
"configuration options you have selected at that time.\n"
|
yann@2454
|
213 |
"\n"
|
yann@2454
|
214 |
"If you are uncertain what all this means then you should probably\n"
|
yann@2454
|
215 |
"leave this blank.\n"),
|
yann@2454
|
216 |
search_help[] = N_(
|
yann@2454
|
217 |
"\n"
|
yann@2454
|
218 |
"Search for symbols and display their relations. Regular expressions\n"
|
yann@2454
|
219 |
"are allowed.\n"
|
yann@2454
|
220 |
"Example: search for \"^FOO\"\n"
|
yann@2454
|
221 |
"Result:\n"
|
yann@2454
|
222 |
"-----------------------------------------------------------------\n"
|
yann@2454
|
223 |
"Symbol: FOO [ = m]\n"
|
yann@2454
|
224 |
"Prompt: Foo bus is used to drive the bar HW\n"
|
yann@2454
|
225 |
"Defined at drivers/pci/Kconfig:47\n"
|
yann@2454
|
226 |
"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
|
yann@2454
|
227 |
"Location:\n"
|
yann@2454
|
228 |
" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
|
yann@2454
|
229 |
" -> PCI support (PCI [ = y])\n"
|
yann@2454
|
230 |
" -> PCI access mode (<choice> [ = y])\n"
|
yann@2454
|
231 |
"Selects: LIBCRC32\n"
|
yann@2454
|
232 |
"Selected by: BAR\n"
|
yann@2454
|
233 |
"-----------------------------------------------------------------\n"
|
yann@2454
|
234 |
"o The line 'Prompt:' shows the text used in the menu structure for\n"
|
yann@2454
|
235 |
" this symbol\n"
|
yann@2454
|
236 |
"o The 'Defined at' line tell at what file / line number the symbol\n"
|
yann@2454
|
237 |
" is defined\n"
|
yann@2454
|
238 |
"o The 'Depends on:' line tell what symbols needs to be defined for\n"
|
yann@2454
|
239 |
" this symbol to be visible in the menu (selectable)\n"
|
yann@2454
|
240 |
"o The 'Location:' lines tell where in the menu structure this symbol\n"
|
yann@2454
|
241 |
" is located\n"
|
yann@2454
|
242 |
" A location followed by a [ = y] indicate that this is a selectable\n"
|
yann@2454
|
243 |
" menu item - and current value is displayed inside brackets.\n"
|
yann@2454
|
244 |
"o The 'Selects:' line tell what symbol will be automatically\n"
|
yann@2454
|
245 |
" selected if this symbol is selected (y or m)\n"
|
yann@2454
|
246 |
"o The 'Selected by' line tell what symbol has selected this symbol\n"
|
yann@2454
|
247 |
"\n"
|
yann@2454
|
248 |
"Only relevant lines are shown.\n"
|
yann@2454
|
249 |
"\n\n"
|
yann@2454
|
250 |
"Search examples:\n"
|
yann@2454
|
251 |
"Examples: USB => find all symbols containing USB\n"
|
yann@2454
|
252 |
" ^USB => find all symbols starting with USB\n"
|
yann@2454
|
253 |
" USB$ => find all symbols ending with USB\n"
|
yann@2454
|
254 |
"\n");
|
yann@2454
|
255 |
|
yann@2454
|
256 |
struct mitem {
|
yann@2454
|
257 |
char str[256];
|
yann@2454
|
258 |
char tag;
|
yann@2454
|
259 |
void *usrptr;
|
yann@2454
|
260 |
int is_visible;
|
yann@2454
|
261 |
};
|
yann@2454
|
262 |
|
yann@2454
|
263 |
#define MAX_MENU_ITEMS 4096
|
yann@2454
|
264 |
static int show_all_items;
|
yann@2454
|
265 |
static int indent;
|
yann@2454
|
266 |
static struct menu *current_menu;
|
yann@2454
|
267 |
static int child_count;
|
yann@2454
|
268 |
static int single_menu_mode;
|
yann@2454
|
269 |
/* the window in which all information appears */
|
yann@2454
|
270 |
static WINDOW *main_window;
|
yann@2454
|
271 |
/* the largest size of the menu window */
|
yann@2454
|
272 |
static int mwin_max_lines;
|
yann@2454
|
273 |
static int mwin_max_cols;
|
yann@2454
|
274 |
/* the window in which we show option buttons */
|
yann@2454
|
275 |
static MENU *curses_menu;
|
yann@2454
|
276 |
static ITEM *curses_menu_items[MAX_MENU_ITEMS];
|
yann@2454
|
277 |
static struct mitem k_menu_items[MAX_MENU_ITEMS];
|
yann@2454
|
278 |
static int items_num;
|
yann@2454
|
279 |
static int global_exit;
|
yann@2454
|
280 |
/* the currently selected button */
|
yann@2454
|
281 |
const char *current_instructions = menu_instructions;
|
yann@2454
|
282 |
|
yann@2454
|
283 |
static void conf(struct menu *menu);
|
yann@2454
|
284 |
static void conf_choice(struct menu *menu);
|
yann@2454
|
285 |
static void conf_string(struct menu *menu);
|
yann@2454
|
286 |
static void conf_load(void);
|
yann@2454
|
287 |
static void conf_save(void);
|
yann@2454
|
288 |
static void show_help(struct menu *menu);
|
yann@2454
|
289 |
static int do_exit(void);
|
yann@2454
|
290 |
static void setup_windows(void);
|
yann@2454
|
291 |
static void search_conf(void);
|
yann@2454
|
292 |
|
yann@2454
|
293 |
typedef void (*function_key_handler_t)(int *key, struct menu *menu);
|
yann@2454
|
294 |
static void handle_f1(int *key, struct menu *current_item);
|
yann@2454
|
295 |
static void handle_f2(int *key, struct menu *current_item);
|
yann@2454
|
296 |
static void handle_f3(int *key, struct menu *current_item);
|
yann@2454
|
297 |
static void handle_f4(int *key, struct menu *current_item);
|
yann@2454
|
298 |
static void handle_f5(int *key, struct menu *current_item);
|
yann@2454
|
299 |
static void handle_f6(int *key, struct menu *current_item);
|
yann@2454
|
300 |
static void handle_f7(int *key, struct menu *current_item);
|
yann@2454
|
301 |
static void handle_f8(int *key, struct menu *current_item);
|
yann@2454
|
302 |
static void handle_f9(int *key, struct menu *current_item);
|
yann@2454
|
303 |
|
yann@2454
|
304 |
struct function_keys {
|
yann@2454
|
305 |
const char *key_str;
|
yann@2454
|
306 |
const char *func;
|
yann@2454
|
307 |
function_key key;
|
yann@2454
|
308 |
function_key_handler_t handler;
|
yann@2454
|
309 |
};
|
yann@2454
|
310 |
|
yann@2454
|
311 |
static const int function_keys_num = 9;
|
yann@2454
|
312 |
struct function_keys function_keys[] = {
|
yann@2454
|
313 |
{
|
yann@2454
|
314 |
.key_str = "F1",
|
yann@2454
|
315 |
.func = "Help",
|
yann@2454
|
316 |
.key = F_HELP,
|
yann@2454
|
317 |
.handler = handle_f1,
|
yann@2454
|
318 |
},
|
yann@2454
|
319 |
{
|
yann@2454
|
320 |
.key_str = "F2",
|
yann@2454
|
321 |
.func = "Sym Info",
|
yann@2454
|
322 |
.key = F_SYMBOL,
|
yann@2454
|
323 |
.handler = handle_f2,
|
yann@2454
|
324 |
},
|
yann@2454
|
325 |
{
|
yann@2454
|
326 |
.key_str = "F3",
|
yann@2454
|
327 |
.func = "Insts",
|
yann@2454
|
328 |
.key = F_INSTS,
|
yann@2454
|
329 |
.handler = handle_f3,
|
yann@2454
|
330 |
},
|
yann@2454
|
331 |
{
|
yann@2454
|
332 |
.key_str = "F4",
|
yann@2454
|
333 |
.func = "Config",
|
yann@2454
|
334 |
.key = F_CONF,
|
yann@2454
|
335 |
.handler = handle_f4,
|
yann@2454
|
336 |
},
|
yann@2454
|
337 |
{
|
yann@2454
|
338 |
.key_str = "F5",
|
yann@2454
|
339 |
.func = "Back",
|
yann@2454
|
340 |
.key = F_BACK,
|
yann@2454
|
341 |
.handler = handle_f5,
|
yann@2454
|
342 |
},
|
yann@2454
|
343 |
{
|
yann@2454
|
344 |
.key_str = "F6",
|
yann@2454
|
345 |
.func = "Save",
|
yann@2454
|
346 |
.key = F_SAVE,
|
yann@2454
|
347 |
.handler = handle_f6,
|
yann@2454
|
348 |
},
|
yann@2454
|
349 |
{
|
yann@2454
|
350 |
.key_str = "F7",
|
yann@2454
|
351 |
.func = "Load",
|
yann@2454
|
352 |
.key = F_LOAD,
|
yann@2454
|
353 |
.handler = handle_f7,
|
yann@2454
|
354 |
},
|
yann@2454
|
355 |
{
|
yann@2454
|
356 |
.key_str = "F8",
|
yann@2454
|
357 |
.func = "Sym Search",
|
yann@2454
|
358 |
.key = F_SEARCH,
|
yann@2454
|
359 |
.handler = handle_f8,
|
yann@2454
|
360 |
},
|
yann@2454
|
361 |
{
|
yann@2454
|
362 |
.key_str = "F9",
|
yann@2454
|
363 |
.func = "Exit",
|
yann@2454
|
364 |
.key = F_EXIT,
|
yann@2454
|
365 |
.handler = handle_f9,
|
yann@2454
|
366 |
},
|
yann@2454
|
367 |
};
|
yann@2454
|
368 |
|
yann@2454
|
369 |
static void print_function_line(void)
|
yann@2454
|
370 |
{
|
yann@2454
|
371 |
int i;
|
yann@2454
|
372 |
int offset = 1;
|
yann@2454
|
373 |
const int skip = 1;
|
yann@2454
|
374 |
|
yann@2454
|
375 |
for (i = 0; i < function_keys_num; i++) {
|
yann@2454
|
376 |
(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
|
yann@2454
|
377 |
mvwprintw(main_window, LINES-3, offset,
|
yann@2454
|
378 |
"%s",
|
yann@2454
|
379 |
function_keys[i].key_str);
|
yann@2454
|
380 |
(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
|
yann@2454
|
381 |
offset += strlen(function_keys[i].key_str);
|
yann@2454
|
382 |
mvwprintw(main_window, LINES-3,
|
yann@2454
|
383 |
offset, "%s",
|
yann@2454
|
384 |
function_keys[i].func);
|
yann@2454
|
385 |
offset += strlen(function_keys[i].func) + skip;
|
yann@2454
|
386 |
}
|
yann@2454
|
387 |
(void) wattrset(main_window, attributes[NORMAL]);
|
yann@2454
|
388 |
}
|
yann@2454
|
389 |
|
yann@2454
|
390 |
/* help */
|
yann@2454
|
391 |
static void handle_f1(int *key, struct menu *current_item)
|
yann@2454
|
392 |
{
|
yann@2454
|
393 |
show_scroll_win(main_window,
|
yann@2454
|
394 |
_("README"), _(nconf_readme));
|
yann@2454
|
395 |
return;
|
yann@2454
|
396 |
}
|
yann@2454
|
397 |
|
yann@2454
|
398 |
/* symbole help */
|
yann@2454
|
399 |
static void handle_f2(int *key, struct menu *current_item)
|
yann@2454
|
400 |
{
|
yann@2454
|
401 |
show_help(current_item);
|
yann@2454
|
402 |
return;
|
yann@2454
|
403 |
}
|
yann@2454
|
404 |
|
yann@2454
|
405 |
/* instructions */
|
yann@2454
|
406 |
static void handle_f3(int *key, struct menu *current_item)
|
yann@2454
|
407 |
{
|
yann@2454
|
408 |
show_scroll_win(main_window,
|
yann@2454
|
409 |
_("Instructions"),
|
yann@2454
|
410 |
_(current_instructions));
|
yann@2454
|
411 |
return;
|
yann@2454
|
412 |
}
|
yann@2454
|
413 |
|
yann@2454
|
414 |
/* config */
|
yann@2454
|
415 |
static void handle_f4(int *key, struct menu *current_item)
|
yann@2454
|
416 |
{
|
yann@2454
|
417 |
int res = btn_dialog(main_window,
|
yann@2454
|
418 |
_("Show all symbols?"),
|
yann@2454
|
419 |
2,
|
yann@2454
|
420 |
" <Show All> ",
|
yann@2454
|
421 |
"<Don't show all>");
|
yann@2454
|
422 |
if (res == 0)
|
yann@2454
|
423 |
show_all_items = 1;
|
yann@2454
|
424 |
else if (res == 1)
|
yann@2454
|
425 |
show_all_items = 0;
|
yann@2454
|
426 |
|
yann@2454
|
427 |
return;
|
yann@2454
|
428 |
}
|
yann@2454
|
429 |
|
yann@2454
|
430 |
/* back */
|
yann@2454
|
431 |
static void handle_f5(int *key, struct menu *current_item)
|
yann@2454
|
432 |
{
|
yann@2454
|
433 |
*key = KEY_LEFT;
|
yann@2454
|
434 |
return;
|
yann@2454
|
435 |
}
|
yann@2454
|
436 |
|
yann@2454
|
437 |
/* save */
|
yann@2454
|
438 |
static void handle_f6(int *key, struct menu *current_item)
|
yann@2454
|
439 |
{
|
yann@2454
|
440 |
conf_save();
|
yann@2454
|
441 |
return;
|
yann@2454
|
442 |
}
|
yann@2454
|
443 |
|
yann@2454
|
444 |
/* load */
|
yann@2454
|
445 |
static void handle_f7(int *key, struct menu *current_item)
|
yann@2454
|
446 |
{
|
yann@2454
|
447 |
conf_load();
|
yann@2454
|
448 |
return;
|
yann@2454
|
449 |
}
|
yann@2454
|
450 |
|
yann@2454
|
451 |
/* search */
|
yann@2454
|
452 |
static void handle_f8(int *key, struct menu *current_item)
|
yann@2454
|
453 |
{
|
yann@2454
|
454 |
search_conf();
|
yann@2454
|
455 |
return;
|
yann@2454
|
456 |
}
|
yann@2454
|
457 |
|
yann@2454
|
458 |
/* exit */
|
yann@2454
|
459 |
static void handle_f9(int *key, struct menu *current_item)
|
yann@2454
|
460 |
{
|
yann@2454
|
461 |
do_exit();
|
yann@2454
|
462 |
return;
|
yann@2454
|
463 |
}
|
yann@2454
|
464 |
|
yann@2454
|
465 |
/* return != 0 to indicate the key was handles */
|
yann@2454
|
466 |
static int process_special_keys(int *key, struct menu *menu)
|
yann@2454
|
467 |
{
|
yann@2454
|
468 |
int i;
|
yann@2454
|
469 |
|
yann@2454
|
470 |
if (*key == KEY_RESIZE) {
|
yann@2454
|
471 |
setup_windows();
|
yann@2454
|
472 |
return 1;
|
yann@2454
|
473 |
}
|
yann@2454
|
474 |
|
yann@2454
|
475 |
for (i = 0; i < function_keys_num; i++) {
|
yann@2454
|
476 |
if (*key == KEY_F(function_keys[i].key) ||
|
yann@2454
|
477 |
*key == '0' + function_keys[i].key){
|
yann@2454
|
478 |
function_keys[i].handler(key, menu);
|
yann@2454
|
479 |
return 1;
|
yann@2454
|
480 |
}
|
yann@2454
|
481 |
}
|
yann@2454
|
482 |
|
yann@2454
|
483 |
return 0;
|
yann@2454
|
484 |
}
|
yann@2454
|
485 |
|
yann@2454
|
486 |
static void clean_items(void)
|
yann@2454
|
487 |
{
|
yann@2454
|
488 |
int i;
|
yann@2454
|
489 |
for (i = 0; curses_menu_items[i]; i++)
|
yann@2454
|
490 |
free_item(curses_menu_items[i]);
|
yann@2454
|
491 |
bzero(curses_menu_items, sizeof(curses_menu_items));
|
yann@2454
|
492 |
bzero(k_menu_items, sizeof(k_menu_items));
|
yann@2454
|
493 |
items_num = 0;
|
yann@2454
|
494 |
}
|
yann@2454
|
495 |
|
yann@2454
|
496 |
typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
|
yann@2454
|
497 |
FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
|
yann@2454
|
498 |
|
yann@2454
|
499 |
/* return the index of the matched item, or -1 if no such item exists */
|
yann@2454
|
500 |
static int get_mext_match(const char *match_str, match_f flag)
|
yann@2454
|
501 |
{
|
yann@2454
|
502 |
int match_start = item_index(current_item(curses_menu));
|
yann@2454
|
503 |
int index;
|
yann@2454
|
504 |
|
yann@2454
|
505 |
if (flag == FIND_NEXT_MATCH_DOWN)
|
yann@2454
|
506 |
++match_start;
|
yann@2454
|
507 |
else if (flag == FIND_NEXT_MATCH_UP)
|
yann@2454
|
508 |
--match_start;
|
yann@2454
|
509 |
|
yann@2454
|
510 |
index = match_start;
|
yann@2454
|
511 |
index = (index + items_num) % items_num;
|
yann@2454
|
512 |
while (true) {
|
yann@2454
|
513 |
char *str = k_menu_items[index].str;
|
yann@2454
|
514 |
if (strcasestr(str, match_str) != 0)
|
yann@2454
|
515 |
return index;
|
yann@2454
|
516 |
if (flag == FIND_NEXT_MATCH_UP ||
|
yann@2454
|
517 |
flag == MATCH_TINKER_PATTERN_UP)
|
yann@2454
|
518 |
--index;
|
yann@2454
|
519 |
else
|
yann@2454
|
520 |
++index;
|
yann@2454
|
521 |
index = (index + items_num) % items_num;
|
yann@2454
|
522 |
if (index == match_start)
|
yann@2454
|
523 |
return -1;
|
yann@2454
|
524 |
}
|
yann@2454
|
525 |
}
|
yann@2454
|
526 |
|
yann@2454
|
527 |
/* Make a new item. */
|
yann@2454
|
528 |
static void item_make(struct menu *menu, char tag, const char *fmt, ...)
|
yann@2454
|
529 |
{
|
yann@2454
|
530 |
va_list ap;
|
yann@2454
|
531 |
|
yann@2454
|
532 |
if (items_num > MAX_MENU_ITEMS-1)
|
yann@2454
|
533 |
return;
|
yann@2454
|
534 |
|
yann@2454
|
535 |
bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
|
yann@2454
|
536 |
k_menu_items[items_num].tag = tag;
|
yann@2454
|
537 |
k_menu_items[items_num].usrptr = menu;
|
yann@2454
|
538 |
if (menu != NULL)
|
yann@2454
|
539 |
k_menu_items[items_num].is_visible =
|
yann@2454
|
540 |
menu_is_visible(menu);
|
yann@2454
|
541 |
else
|
yann@2454
|
542 |
k_menu_items[items_num].is_visible = 1;
|
yann@2454
|
543 |
|
yann@2454
|
544 |
va_start(ap, fmt);
|
yann@2454
|
545 |
vsnprintf(k_menu_items[items_num].str,
|
yann@2454
|
546 |
sizeof(k_menu_items[items_num].str),
|
yann@2454
|
547 |
fmt, ap);
|
yann@2454
|
548 |
va_end(ap);
|
yann@2454
|
549 |
|
yann@2454
|
550 |
if (!k_menu_items[items_num].is_visible)
|
yann@2454
|
551 |
memcpy(k_menu_items[items_num].str, "XXX", 3);
|
yann@2454
|
552 |
|
yann@2454
|
553 |
curses_menu_items[items_num] = new_item(
|
yann@2454
|
554 |
k_menu_items[items_num].str,
|
yann@2454
|
555 |
k_menu_items[items_num].str);
|
yann@2454
|
556 |
set_item_userptr(curses_menu_items[items_num],
|
yann@2454
|
557 |
&k_menu_items[items_num]);
|
yann@2454
|
558 |
/*
|
yann@2454
|
559 |
if (!k_menu_items[items_num].is_visible)
|
yann@2454
|
560 |
item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
|
yann@2454
|
561 |
*/
|
yann@2454
|
562 |
|
yann@2454
|
563 |
items_num++;
|
yann@2454
|
564 |
curses_menu_items[items_num] = NULL;
|
yann@2454
|
565 |
}
|
yann@2454
|
566 |
|
yann@2454
|
567 |
/* very hackish. adds a string to the last item added */
|
yann@2454
|
568 |
static void item_add_str(const char *fmt, ...)
|
yann@2454
|
569 |
{
|
yann@2454
|
570 |
va_list ap;
|
yann@2454
|
571 |
int index = items_num-1;
|
yann@2454
|
572 |
char new_str[256];
|
yann@2454
|
573 |
char tmp_str[256];
|
yann@2454
|
574 |
|
yann@2454
|
575 |
if (index < 0)
|
yann@2454
|
576 |
return;
|
yann@2454
|
577 |
|
yann@2454
|
578 |
va_start(ap, fmt);
|
yann@2454
|
579 |
vsnprintf(new_str, sizeof(new_str), fmt, ap);
|
yann@2454
|
580 |
va_end(ap);
|
yann@2454
|
581 |
snprintf(tmp_str, sizeof(tmp_str), "%s%s",
|
yann@2454
|
582 |
k_menu_items[index].str, new_str);
|
yann@2454
|
583 |
strncpy(k_menu_items[index].str,
|
yann@2454
|
584 |
tmp_str,
|
yann@2454
|
585 |
sizeof(k_menu_items[index].str));
|
yann@2454
|
586 |
|
yann@2454
|
587 |
free_item(curses_menu_items[index]);
|
yann@2454
|
588 |
curses_menu_items[index] = new_item(
|
yann@2454
|
589 |
k_menu_items[index].str,
|
yann@2454
|
590 |
k_menu_items[index].str);
|
yann@2454
|
591 |
set_item_userptr(curses_menu_items[index],
|
yann@2454
|
592 |
&k_menu_items[index]);
|
yann@2454
|
593 |
}
|
yann@2454
|
594 |
|
yann@2454
|
595 |
/* get the tag of the currently selected item */
|
yann@2454
|
596 |
static char item_tag(void)
|
yann@2454
|
597 |
{
|
yann@2454
|
598 |
ITEM *cur;
|
yann@2454
|
599 |
struct mitem *mcur;
|
yann@2454
|
600 |
|
yann@2454
|
601 |
cur = current_item(curses_menu);
|
yann@2454
|
602 |
if (cur == NULL)
|
yann@2454
|
603 |
return 0;
|
yann@2454
|
604 |
mcur = (struct mitem *) item_userptr(cur);
|
yann@2454
|
605 |
return mcur->tag;
|
yann@2454
|
606 |
}
|
yann@2454
|
607 |
|
yann@2454
|
608 |
static int curses_item_index(void)
|
yann@2454
|
609 |
{
|
yann@2454
|
610 |
return item_index(current_item(curses_menu));
|
yann@2454
|
611 |
}
|
yann@2454
|
612 |
|
yann@2454
|
613 |
static void *item_data(void)
|
yann@2454
|
614 |
{
|
yann@2454
|
615 |
ITEM *cur;
|
yann@2454
|
616 |
struct mitem *mcur;
|
yann@2454
|
617 |
|
yann@2454
|
618 |
cur = current_item(curses_menu);
|
yann@2454
|
619 |
if (!cur)
|
yann@2454
|
620 |
return NULL;
|
yann@2454
|
621 |
mcur = (struct mitem *) item_userptr(cur);
|
yann@2454
|
622 |
return mcur->usrptr;
|
yann@2454
|
623 |
|
yann@2454
|
624 |
}
|
yann@2454
|
625 |
|
yann@2454
|
626 |
static int item_is_tag(char tag)
|
yann@2454
|
627 |
{
|
yann@2454
|
628 |
return item_tag() == tag;
|
yann@2454
|
629 |
}
|
yann@2454
|
630 |
|
yann@2454
|
631 |
static char filename[PATH_MAX+1];
|
yann@2454
|
632 |
static char menu_backtitle[PATH_MAX+128];
|
yann@2454
|
633 |
static const char *set_config_filename(const char *config_filename)
|
yann@2454
|
634 |
{
|
yann@2454
|
635 |
int size;
|
yann@2454
|
636 |
|
yann@2454
|
637 |
size = snprintf(menu_backtitle, sizeof(menu_backtitle),
|
yann@2454
|
638 |
"%s - %s", config_filename, rootmenu.prompt->text);
|
yann@2454
|
639 |
if (size >= sizeof(menu_backtitle))
|
yann@2454
|
640 |
menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
|
yann@2454
|
641 |
|
yann@2454
|
642 |
size = snprintf(filename, sizeof(filename), "%s", config_filename);
|
yann@2454
|
643 |
if (size >= sizeof(filename))
|
yann@2454
|
644 |
filename[sizeof(filename)-1] = '\0';
|
yann@2454
|
645 |
return menu_backtitle;
|
yann@2454
|
646 |
}
|
yann@2454
|
647 |
|
yann@2454
|
648 |
/* return = 0 means we are successful.
|
yann@2454
|
649 |
* -1 means go on doing what you were doing
|
yann@2454
|
650 |
*/
|
yann@2454
|
651 |
static int do_exit(void)
|
yann@2454
|
652 |
{
|
yann@2454
|
653 |
int res;
|
yann@2454
|
654 |
if (!conf_get_changed()) {
|
yann@2454
|
655 |
global_exit = 1;
|
yann@2454
|
656 |
return 0;
|
yann@2454
|
657 |
}
|
yann@2454
|
658 |
res = btn_dialog(main_window,
|
yann@2454
|
659 |
_("Do you wish to save your new configuration?\n"
|
yann@2454
|
660 |
"<ESC> to cancel and resume nconfig."),
|
yann@2454
|
661 |
2,
|
yann@2454
|
662 |
" <save> ",
|
yann@2454
|
663 |
"<don't save>");
|
yann@2454
|
664 |
if (res == KEY_EXIT) {
|
yann@2454
|
665 |
global_exit = 0;
|
yann@2454
|
666 |
return -1;
|
yann@2454
|
667 |
}
|
yann@2454
|
668 |
|
yann@2454
|
669 |
/* if we got here, the user really wants to exit */
|
yann@2454
|
670 |
switch (res) {
|
yann@2454
|
671 |
case 0:
|
yann@2454
|
672 |
res = conf_write(filename);
|
yann@2454
|
673 |
if (res)
|
yann@2454
|
674 |
btn_dialog(
|
yann@2454
|
675 |
main_window,
|
yann@2454
|
676 |
_("Error during writing of configuration.\n"
|
yann@2454
|
677 |
"Your configuration changes were NOT saved."),
|
yann@2454
|
678 |
1,
|
yann@2454
|
679 |
"<OK>");
|
yann@2454
|
680 |
break;
|
yann@2454
|
681 |
default:
|
yann@2454
|
682 |
btn_dialog(
|
yann@2454
|
683 |
main_window,
|
yann@2454
|
684 |
_("Your configuration changes were NOT saved."),
|
yann@2454
|
685 |
1,
|
yann@2454
|
686 |
"<OK>");
|
yann@2454
|
687 |
break;
|
yann@2454
|
688 |
}
|
yann@2454
|
689 |
global_exit = 1;
|
yann@2454
|
690 |
return 0;
|
yann@2454
|
691 |
}
|
yann@2454
|
692 |
|
yann@2454
|
693 |
|
yann@2454
|
694 |
static void search_conf(void)
|
yann@2454
|
695 |
{
|
yann@2454
|
696 |
struct symbol **sym_arr;
|
yann@2454
|
697 |
struct gstr res;
|
yann@2454
|
698 |
char dialog_input_result[100];
|
yann@2454
|
699 |
char *dialog_input;
|
yann@2454
|
700 |
int dres;
|
yann@2454
|
701 |
again:
|
yann@2454
|
702 |
dres = dialog_inputbox(main_window,
|
yann@2454
|
703 |
_("Search Configuration Parameter"),
|
yann@2454
|
704 |
_("Enter " CONFIG_ " (sub)string to search for "
|
yann@2454
|
705 |
"(with or without \"" CONFIG_ "\")"),
|
yann@2454
|
706 |
"", dialog_input_result, 99);
|
yann@2454
|
707 |
switch (dres) {
|
yann@2454
|
708 |
case 0:
|
yann@2454
|
709 |
break;
|
yann@2454
|
710 |
case 1:
|
yann@2454
|
711 |
show_scroll_win(main_window,
|
yann@2454
|
712 |
_("Search Configuration"), search_help);
|
yann@2454
|
713 |
goto again;
|
yann@2454
|
714 |
default:
|
yann@2454
|
715 |
return;
|
yann@2454
|
716 |
}
|
yann@2454
|
717 |
|
yann@2454
|
718 |
/* strip the prefix if necessary */
|
yann@2454
|
719 |
dialog_input = dialog_input_result;
|
yann@2454
|
720 |
if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
|
yann@2454
|
721 |
dialog_input += strlen(CONFIG_);
|
yann@2454
|
722 |
|
yann@2454
|
723 |
sym_arr = sym_re_search(dialog_input);
|
yann@2454
|
724 |
res = get_relations_str(sym_arr);
|
yann@2454
|
725 |
free(sym_arr);
|
yann@2454
|
726 |
show_scroll_win(main_window,
|
yann@2454
|
727 |
_("Search Results"), str_get(&res));
|
yann@2454
|
728 |
str_free(&res);
|
yann@2454
|
729 |
}
|
yann@2454
|
730 |
|
yann@2454
|
731 |
|
yann@2454
|
732 |
static void build_conf(struct menu *menu)
|
yann@2454
|
733 |
{
|
yann@2454
|
734 |
struct symbol *sym;
|
yann@2454
|
735 |
struct property *prop;
|
yann@2454
|
736 |
struct menu *child;
|
yann@2454
|
737 |
int type, tmp, doint = 2;
|
yann@2454
|
738 |
tristate val;
|
yann@2454
|
739 |
char ch;
|
yann@2454
|
740 |
|
yann@2454
|
741 |
if (!menu || (!show_all_items && !menu_is_visible(menu)))
|
yann@2454
|
742 |
return;
|
yann@2454
|
743 |
|
yann@2454
|
744 |
sym = menu->sym;
|
yann@2454
|
745 |
prop = menu->prompt;
|
yann@2454
|
746 |
if (!sym) {
|
yann@2454
|
747 |
if (prop && menu != current_menu) {
|
yann@2454
|
748 |
const char *prompt = menu_get_prompt(menu);
|
yann@2454
|
749 |
enum prop_type ptype;
|
yann@2454
|
750 |
ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
|
yann@2454
|
751 |
switch (ptype) {
|
yann@2454
|
752 |
case P_MENU:
|
yann@2454
|
753 |
child_count++;
|
yann@2454
|
754 |
prompt = _(prompt);
|
yann@2454
|
755 |
if (single_menu_mode) {
|
yann@2454
|
756 |
item_make(menu, 'm',
|
yann@2454
|
757 |
"%s%*c%s",
|
yann@2454
|
758 |
menu->data ? "-->" : "++>",
|
yann@2454
|
759 |
indent + 1, ' ', prompt);
|
yann@2454
|
760 |
} else
|
yann@2454
|
761 |
item_make(menu, 'm',
|
yann@2454
|
762 |
" %*c%s --->",
|
yann@2454
|
763 |
indent + 1,
|
yann@2454
|
764 |
' ', prompt);
|
yann@2454
|
765 |
|
yann@2454
|
766 |
if (single_menu_mode && menu->data)
|
yann@2454
|
767 |
goto conf_childs;
|
yann@2454
|
768 |
return;
|
yann@2454
|
769 |
case P_COMMENT:
|
yann@2454
|
770 |
if (prompt) {
|
yann@2454
|
771 |
child_count++;
|
yann@2454
|
772 |
item_make(menu, ':',
|
yann@2454
|
773 |
" %*c*** %s ***",
|
yann@2454
|
774 |
indent + 1, ' ',
|
yann@2454
|
775 |
_(prompt));
|
yann@2454
|
776 |
}
|
yann@2454
|
777 |
break;
|
yann@2454
|
778 |
default:
|
yann@2454
|
779 |
if (prompt) {
|
yann@2454
|
780 |
child_count++;
|
yann@2454
|
781 |
item_make(menu, ':', "---%*c%s",
|
yann@2454
|
782 |
indent + 1, ' ',
|
yann@2454
|
783 |
_(prompt));
|
yann@2454
|
784 |
}
|
yann@2454
|
785 |
}
|
yann@2454
|
786 |
} else
|
yann@2454
|
787 |
doint = 0;
|
yann@2454
|
788 |
goto conf_childs;
|
yann@2454
|
789 |
}
|
yann@2454
|
790 |
|
yann@2454
|
791 |
type = sym_get_type(sym);
|
yann@2454
|
792 |
if (sym_is_choice(sym)) {
|
yann@2454
|
793 |
struct symbol *def_sym = sym_get_choice_value(sym);
|
yann@2454
|
794 |
struct menu *def_menu = NULL;
|
yann@2454
|
795 |
|
yann@2454
|
796 |
child_count++;
|
yann@2454
|
797 |
for (child = menu->list; child; child = child->next) {
|
yann@2454
|
798 |
if (menu_is_visible(child) && child->sym == def_sym)
|
yann@2454
|
799 |
def_menu = child;
|
yann@2454
|
800 |
}
|
yann@2454
|
801 |
|
yann@2454
|
802 |
val = sym_get_tristate_value(sym);
|
yann@2454
|
803 |
if (sym_is_changable(sym)) {
|
yann@2454
|
804 |
switch (type) {
|
yann@2454
|
805 |
case S_BOOLEAN:
|
yann@2454
|
806 |
item_make(menu, 't', "[%c]",
|
yann@2454
|
807 |
val == no ? ' ' : '*');
|
yann@2454
|
808 |
break;
|
yann@2454
|
809 |
case S_TRISTATE:
|
yann@2454
|
810 |
switch (val) {
|
yann@2454
|
811 |
case yes:
|
yann@2454
|
812 |
ch = '*';
|
yann@2454
|
813 |
break;
|
yann@2454
|
814 |
case mod:
|
yann@2454
|
815 |
ch = 'M';
|
yann@2454
|
816 |
break;
|
yann@2454
|
817 |
default:
|
yann@2454
|
818 |
ch = ' ';
|
yann@2454
|
819 |
break;
|
yann@2454
|
820 |
}
|
yann@2454
|
821 |
item_make(menu, 't', "<%c>", ch);
|
yann@2454
|
822 |
break;
|
yann@2454
|
823 |
}
|
yann@2454
|
824 |
} else {
|
yann@2454
|
825 |
item_make(menu, def_menu ? 't' : ':', " ");
|
yann@2454
|
826 |
}
|
yann@2454
|
827 |
|
yann@2454
|
828 |
item_add_str("%*c%s", indent + 1,
|
yann@2454
|
829 |
' ', _(menu_get_prompt(menu)));
|
yann@2454
|
830 |
if (val == yes) {
|
yann@2454
|
831 |
if (def_menu) {
|
yann@2454
|
832 |
item_add_str(" (%s)",
|
yann@2454
|
833 |
_(menu_get_prompt(def_menu)));
|
yann@2454
|
834 |
item_add_str(" --->");
|
yann@2454
|
835 |
if (def_menu->list) {
|
yann@2454
|
836 |
indent += 2;
|
yann@2454
|
837 |
build_conf(def_menu);
|
yann@2454
|
838 |
indent -= 2;
|
yann@2454
|
839 |
}
|
yann@2454
|
840 |
}
|
yann@2454
|
841 |
return;
|
yann@2454
|
842 |
}
|
yann@2454
|
843 |
} else {
|
yann@2454
|
844 |
if (menu == current_menu) {
|
yann@2454
|
845 |
item_make(menu, ':',
|
yann@2454
|
846 |
"---%*c%s", indent + 1,
|
yann@2454
|
847 |
' ', _(menu_get_prompt(menu)));
|
yann@2454
|
848 |
goto conf_childs;
|
yann@2454
|
849 |
}
|
yann@2454
|
850 |
child_count++;
|
yann@2454
|
851 |
val = sym_get_tristate_value(sym);
|
yann@2454
|
852 |
if (sym_is_choice_value(sym) && val == yes) {
|
yann@2454
|
853 |
item_make(menu, ':', " ");
|
yann@2454
|
854 |
} else {
|
yann@2454
|
855 |
switch (type) {
|
yann@2454
|
856 |
case S_BOOLEAN:
|
yann@2454
|
857 |
if (sym_is_changable(sym))
|
yann@2454
|
858 |
item_make(menu, 't', "[%c]",
|
yann@2454
|
859 |
val == no ? ' ' : '*');
|
yann@2454
|
860 |
else
|
yann@2454
|
861 |
item_make(menu, 't', "-%c-",
|
yann@2454
|
862 |
val == no ? ' ' : '*');
|
yann@2454
|
863 |
break;
|
yann@2454
|
864 |
case S_TRISTATE:
|
yann@2454
|
865 |
switch (val) {
|
yann@2454
|
866 |
case yes:
|
yann@2454
|
867 |
ch = '*';
|
yann@2454
|
868 |
break;
|
yann@2454
|
869 |
case mod:
|
yann@2454
|
870 |
ch = 'M';
|
yann@2454
|
871 |
break;
|
yann@2454
|
872 |
default:
|
yann@2454
|
873 |
ch = ' ';
|
yann@2454
|
874 |
break;
|
yann@2454
|
875 |
}
|
yann@2454
|
876 |
if (sym_is_changable(sym)) {
|
yann@2454
|
877 |
if (sym->rev_dep.tri == mod)
|
yann@2454
|
878 |
item_make(menu,
|
yann@2454
|
879 |
't', "{%c}", ch);
|
yann@2454
|
880 |
else
|
yann@2454
|
881 |
item_make(menu,
|
yann@2454
|
882 |
't', "<%c>", ch);
|
yann@2454
|
883 |
} else
|
yann@2454
|
884 |
item_make(menu, 't', "-%c-", ch);
|
yann@2454
|
885 |
break;
|
yann@2454
|
886 |
default:
|
yann@2454
|
887 |
tmp = 2 + strlen(sym_get_string_value(sym));
|
yann@2454
|
888 |
item_make(menu, 's', " (%s)",
|
yann@2454
|
889 |
sym_get_string_value(sym));
|
yann@2454
|
890 |
tmp = indent - tmp + 4;
|
yann@2454
|
891 |
if (tmp < 0)
|
yann@2454
|
892 |
tmp = 0;
|
yann@2454
|
893 |
item_add_str("%*c%s%s", tmp, ' ',
|
yann@2454
|
894 |
_(menu_get_prompt(menu)),
|
yann@2454
|
895 |
(sym_has_value(sym) ||
|
yann@2454
|
896 |
!sym_is_changable(sym)) ? "" :
|
yann@2454
|
897 |
_(" (NEW)"));
|
yann@2454
|
898 |
goto conf_childs;
|
yann@2454
|
899 |
}
|
yann@2454
|
900 |
}
|
yann@2454
|
901 |
item_add_str("%*c%s%s", indent + 1, ' ',
|
yann@2454
|
902 |
_(menu_get_prompt(menu)),
|
yann@2454
|
903 |
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
yann@2454
|
904 |
"" : _(" (NEW)"));
|
yann@2454
|
905 |
if (menu->prompt && menu->prompt->type == P_MENU) {
|
yann@2454
|
906 |
item_add_str(" --->");
|
yann@2454
|
907 |
return;
|
yann@2454
|
908 |
}
|
yann@2454
|
909 |
}
|
yann@2454
|
910 |
|
yann@2454
|
911 |
conf_childs:
|
yann@2454
|
912 |
indent += doint;
|
yann@2454
|
913 |
for (child = menu->list; child; child = child->next)
|
yann@2454
|
914 |
build_conf(child);
|
yann@2454
|
915 |
indent -= doint;
|
yann@2454
|
916 |
}
|
yann@2454
|
917 |
|
yann@2454
|
918 |
static void reset_menu(void)
|
yann@2454
|
919 |
{
|
yann@2454
|
920 |
unpost_menu(curses_menu);
|
yann@2454
|
921 |
clean_items();
|
yann@2454
|
922 |
}
|
yann@2454
|
923 |
|
yann@2454
|
924 |
/* adjust the menu to show this item.
|
yann@2454
|
925 |
* prefer not to scroll the menu if possible*/
|
yann@2454
|
926 |
static void center_item(int selected_index, int *last_top_row)
|
yann@2454
|
927 |
{
|
yann@2454
|
928 |
int toprow;
|
yann@2454
|
929 |
|
yann@2454
|
930 |
set_top_row(curses_menu, *last_top_row);
|
yann@2454
|
931 |
toprow = top_row(curses_menu);
|
yann@2454
|
932 |
if (selected_index < toprow ||
|
yann@2454
|
933 |
selected_index >= toprow+mwin_max_lines) {
|
yann@2454
|
934 |
toprow = max(selected_index-mwin_max_lines/2, 0);
|
yann@2454
|
935 |
if (toprow >= item_count(curses_menu)-mwin_max_lines)
|
yann@2454
|
936 |
toprow = item_count(curses_menu)-mwin_max_lines;
|
yann@2454
|
937 |
set_top_row(curses_menu, toprow);
|
yann@2454
|
938 |
}
|
yann@2454
|
939 |
set_current_item(curses_menu,
|
yann@2454
|
940 |
curses_menu_items[selected_index]);
|
yann@2454
|
941 |
*last_top_row = toprow;
|
yann@2454
|
942 |
post_menu(curses_menu);
|
yann@2454
|
943 |
refresh_all_windows(main_window);
|
yann@2454
|
944 |
}
|
yann@2454
|
945 |
|
yann@2454
|
946 |
/* this function assumes reset_menu has been called before */
|
yann@2454
|
947 |
static void show_menu(const char *prompt, const char *instructions,
|
yann@2454
|
948 |
int selected_index, int *last_top_row)
|
yann@2454
|
949 |
{
|
yann@2454
|
950 |
int maxx, maxy;
|
yann@2454
|
951 |
WINDOW *menu_window;
|
yann@2454
|
952 |
|
yann@2454
|
953 |
current_instructions = instructions;
|
yann@2454
|
954 |
|
yann@2454
|
955 |
clear();
|
yann@2454
|
956 |
(void) wattrset(main_window, attributes[NORMAL]);
|
yann@2454
|
957 |
print_in_middle(stdscr, 1, 0, COLS,
|
yann@2454
|
958 |
menu_backtitle,
|
yann@2454
|
959 |
attributes[MAIN_HEADING]);
|
yann@2454
|
960 |
|
yann@2454
|
961 |
(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
|
yann@2454
|
962 |
box(main_window, 0, 0);
|
yann@2454
|
963 |
(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
|
yann@2454
|
964 |
mvwprintw(main_window, 0, 3, " %s ", prompt);
|
yann@2454
|
965 |
(void) wattrset(main_window, attributes[NORMAL]);
|
yann@2454
|
966 |
|
yann@2454
|
967 |
set_menu_items(curses_menu, curses_menu_items);
|
yann@2454
|
968 |
|
yann@2454
|
969 |
/* position the menu at the middle of the screen */
|
yann@2454
|
970 |
scale_menu(curses_menu, &maxy, &maxx);
|
yann@2454
|
971 |
maxx = min(maxx, mwin_max_cols-2);
|
yann@2454
|
972 |
maxy = mwin_max_lines;
|
yann@2454
|
973 |
menu_window = derwin(main_window,
|
yann@2454
|
974 |
maxy,
|
yann@2454
|
975 |
maxx,
|
yann@2454
|
976 |
2,
|
yann@2454
|
977 |
(mwin_max_cols-maxx)/2);
|
yann@2454
|
978 |
keypad(menu_window, TRUE);
|
yann@2454
|
979 |
set_menu_win(curses_menu, menu_window);
|
yann@2454
|
980 |
set_menu_sub(curses_menu, menu_window);
|
yann@2454
|
981 |
|
yann@2454
|
982 |
/* must reassert this after changing items, otherwise returns to a
|
yann@2454
|
983 |
* default of 16
|
yann@2454
|
984 |
*/
|
yann@2454
|
985 |
set_menu_format(curses_menu, maxy, 1);
|
yann@2454
|
986 |
center_item(selected_index, last_top_row);
|
yann@2454
|
987 |
set_menu_format(curses_menu, maxy, 1);
|
yann@2454
|
988 |
|
yann@2454
|
989 |
print_function_line();
|
yann@2454
|
990 |
|
yann@2454
|
991 |
/* Post the menu */
|
yann@2454
|
992 |
post_menu(curses_menu);
|
yann@2454
|
993 |
refresh_all_windows(main_window);
|
yann@2454
|
994 |
}
|
yann@2454
|
995 |
|
yann@2454
|
996 |
static void adj_match_dir(match_f *match_direction)
|
yann@2454
|
997 |
{
|
yann@2454
|
998 |
if (*match_direction == FIND_NEXT_MATCH_DOWN)
|
yann@2454
|
999 |
*match_direction =
|
yann@2454
|
1000 |
MATCH_TINKER_PATTERN_DOWN;
|
yann@2454
|
1001 |
else if (*match_direction == FIND_NEXT_MATCH_UP)
|
yann@2454
|
1002 |
*match_direction =
|
yann@2454
|
1003 |
MATCH_TINKER_PATTERN_UP;
|
yann@2454
|
1004 |
/* else, do no change.. */
|
yann@2454
|
1005 |
}
|
yann@2454
|
1006 |
|
yann@2454
|
1007 |
struct match_state
|
yann@2454
|
1008 |
{
|
yann@2454
|
1009 |
int in_search;
|
yann@2454
|
1010 |
match_f match_direction;
|
yann@2454
|
1011 |
char pattern[256];
|
yann@2454
|
1012 |
};
|
yann@2454
|
1013 |
|
yann@2454
|
1014 |
/* Return 0 means I have handled the key. In such a case, ans should hold the
|
yann@2454
|
1015 |
* item to center, or -1 otherwise.
|
yann@2454
|
1016 |
* Else return -1 .
|
yann@2454
|
1017 |
*/
|
yann@2454
|
1018 |
static int do_match(int key, struct match_state *state, int *ans)
|
yann@2454
|
1019 |
{
|
yann@2454
|
1020 |
char c = (char) key;
|
yann@2454
|
1021 |
int terminate_search = 0;
|
yann@2454
|
1022 |
*ans = -1;
|
yann@2454
|
1023 |
if (key == '/' || (state->in_search && key == 27)) {
|
yann@2454
|
1024 |
move(0, 0);
|
yann@2454
|
1025 |
refresh();
|
yann@2454
|
1026 |
clrtoeol();
|
yann@2454
|
1027 |
state->in_search = 1-state->in_search;
|
yann@2454
|
1028 |
bzero(state->pattern, sizeof(state->pattern));
|
yann@2454
|
1029 |
state->match_direction = MATCH_TINKER_PATTERN_DOWN;
|
yann@2454
|
1030 |
return 0;
|
yann@2454
|
1031 |
} else if (!state->in_search)
|
yann@2454
|
1032 |
return 1;
|
yann@2454
|
1033 |
|
yann@2454
|
1034 |
if (isalnum(c) || isgraph(c) || c == ' ') {
|
yann@2454
|
1035 |
state->pattern[strlen(state->pattern)] = c;
|
yann@2454
|
1036 |
state->pattern[strlen(state->pattern)] = '\0';
|
yann@2454
|
1037 |
adj_match_dir(&state->match_direction);
|
yann@2454
|
1038 |
*ans = get_mext_match(state->pattern,
|
yann@2454
|
1039 |
state->match_direction);
|
yann@2454
|
1040 |
} else if (key == KEY_DOWN) {
|
yann@2454
|
1041 |
state->match_direction = FIND_NEXT_MATCH_DOWN;
|
yann@2454
|
1042 |
*ans = get_mext_match(state->pattern,
|
yann@2454
|
1043 |
state->match_direction);
|
yann@2454
|
1044 |
} else if (key == KEY_UP) {
|
yann@2454
|
1045 |
state->match_direction = FIND_NEXT_MATCH_UP;
|
yann@2454
|
1046 |
*ans = get_mext_match(state->pattern,
|
yann@2454
|
1047 |
state->match_direction);
|
yann@2454
|
1048 |
} else if (key == KEY_BACKSPACE || key == 127) {
|
yann@2454
|
1049 |
state->pattern[strlen(state->pattern)-1] = '\0';
|
yann@2454
|
1050 |
adj_match_dir(&state->match_direction);
|
yann@2454
|
1051 |
} else
|
yann@2454
|
1052 |
terminate_search = 1;
|
yann@2454
|
1053 |
|
yann@2454
|
1054 |
if (terminate_search) {
|
yann@2454
|
1055 |
state->in_search = 0;
|
yann@2454
|
1056 |
bzero(state->pattern, sizeof(state->pattern));
|
yann@2454
|
1057 |
move(0, 0);
|
yann@2454
|
1058 |
refresh();
|
yann@2454
|
1059 |
clrtoeol();
|
yann@2454
|
1060 |
return -1;
|
yann@2454
|
1061 |
}
|
yann@2454
|
1062 |
return 0;
|
yann@2454
|
1063 |
}
|
yann@2454
|
1064 |
|
yann@2454
|
1065 |
static void conf(struct menu *menu)
|
yann@2454
|
1066 |
{
|
yann@2454
|
1067 |
struct menu *submenu = 0;
|
yann@2454
|
1068 |
const char *prompt = menu_get_prompt(menu);
|
yann@2454
|
1069 |
struct symbol *sym;
|
yann@2454
|
1070 |
struct menu *active_menu = NULL;
|
yann@2454
|
1071 |
int res;
|
yann@2454
|
1072 |
int current_index = 0;
|
yann@2454
|
1073 |
int last_top_row = 0;
|
yann@2454
|
1074 |
struct match_state match_state = {
|
yann@2454
|
1075 |
.in_search = 0,
|
yann@2454
|
1076 |
.match_direction = MATCH_TINKER_PATTERN_DOWN,
|
yann@2454
|
1077 |
.pattern = "",
|
yann@2454
|
1078 |
};
|
yann@2454
|
1079 |
|
yann@2454
|
1080 |
while (!global_exit) {
|
yann@2454
|
1081 |
reset_menu();
|
yann@2454
|
1082 |
current_menu = menu;
|
yann@2454
|
1083 |
build_conf(menu);
|
yann@2454
|
1084 |
if (!child_count)
|
yann@2454
|
1085 |
break;
|
yann@2454
|
1086 |
|
yann@2454
|
1087 |
show_menu(prompt ? _(prompt) : _("Main Menu"),
|
yann@2454
|
1088 |
_(menu_instructions),
|
yann@2454
|
1089 |
current_index, &last_top_row);
|
yann@2454
|
1090 |
keypad((menu_win(curses_menu)), TRUE);
|
yann@2454
|
1091 |
while (!global_exit) {
|
yann@2454
|
1092 |
if (match_state.in_search) {
|
yann@2454
|
1093 |
mvprintw(0, 0,
|
yann@2454
|
1094 |
"searching: %s", match_state.pattern);
|
yann@2454
|
1095 |
clrtoeol();
|
yann@2454
|
1096 |
}
|
yann@2454
|
1097 |
refresh_all_windows(main_window);
|
yann@2454
|
1098 |
res = wgetch(menu_win(curses_menu));
|
yann@2454
|
1099 |
if (!res)
|
yann@2454
|
1100 |
break;
|
yann@2454
|
1101 |
if (do_match(res, &match_state, ¤t_index) == 0) {
|
yann@2454
|
1102 |
if (current_index != -1)
|
yann@2454
|
1103 |
center_item(current_index,
|
yann@2454
|
1104 |
&last_top_row);
|
yann@2454
|
1105 |
continue;
|
yann@2454
|
1106 |
}
|
yann@2454
|
1107 |
if (process_special_keys(&res,
|
yann@2454
|
1108 |
(struct menu *) item_data()))
|
yann@2454
|
1109 |
break;
|
yann@2454
|
1110 |
switch (res) {
|
yann@2454
|
1111 |
case KEY_DOWN:
|
yann@2454
|
1112 |
menu_driver(curses_menu, REQ_DOWN_ITEM);
|
yann@2454
|
1113 |
break;
|
yann@2454
|
1114 |
case KEY_UP:
|
yann@2454
|
1115 |
menu_driver(curses_menu, REQ_UP_ITEM);
|
yann@2454
|
1116 |
break;
|
yann@2454
|
1117 |
case KEY_NPAGE:
|
yann@2454
|
1118 |
menu_driver(curses_menu, REQ_SCR_DPAGE);
|
yann@2454
|
1119 |
break;
|
yann@2454
|
1120 |
case KEY_PPAGE:
|
yann@2454
|
1121 |
menu_driver(curses_menu, REQ_SCR_UPAGE);
|
yann@2454
|
1122 |
break;
|
yann@2454
|
1123 |
case KEY_HOME:
|
yann@2454
|
1124 |
menu_driver(curses_menu, REQ_FIRST_ITEM);
|
yann@2454
|
1125 |
break;
|
yann@2454
|
1126 |
case KEY_END:
|
yann@2454
|
1127 |
menu_driver(curses_menu, REQ_LAST_ITEM);
|
yann@2454
|
1128 |
break;
|
yann@2454
|
1129 |
case 'h':
|
yann@2454
|
1130 |
case '?':
|
yann@2454
|
1131 |
show_help((struct menu *) item_data());
|
yann@2454
|
1132 |
break;
|
yann@2454
|
1133 |
}
|
yann@2454
|
1134 |
if (res == 10 || res == 27 ||
|
yann@2454
|
1135 |
res == 32 || res == 'n' || res == 'y' ||
|
yann@2454
|
1136 |
res == KEY_LEFT || res == KEY_RIGHT ||
|
yann@2454
|
1137 |
res == 'm')
|
yann@2454
|
1138 |
break;
|
yann@2454
|
1139 |
refresh_all_windows(main_window);
|
yann@2454
|
1140 |
}
|
yann@2454
|
1141 |
|
yann@2454
|
1142 |
refresh_all_windows(main_window);
|
yann@2454
|
1143 |
/* if ESC or left*/
|
yann@2454
|
1144 |
if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
|
yann@2454
|
1145 |
break;
|
yann@2454
|
1146 |
|
yann@2454
|
1147 |
/* remember location in the menu */
|
yann@2454
|
1148 |
last_top_row = top_row(curses_menu);
|
yann@2454
|
1149 |
current_index = curses_item_index();
|
yann@2454
|
1150 |
|
yann@2454
|
1151 |
if (!item_tag())
|
yann@2454
|
1152 |
continue;
|
yann@2454
|
1153 |
|
yann@2454
|
1154 |
submenu = (struct menu *) item_data();
|
yann@2454
|
1155 |
active_menu = (struct menu *)item_data();
|
yann@2454
|
1156 |
if (!submenu || !menu_is_visible(submenu))
|
yann@2454
|
1157 |
continue;
|
yann@2454
|
1158 |
if (submenu)
|
yann@2454
|
1159 |
sym = submenu->sym;
|
yann@2454
|
1160 |
else
|
yann@2454
|
1161 |
sym = NULL;
|
yann@2454
|
1162 |
|
yann@2454
|
1163 |
switch (res) {
|
yann@2454
|
1164 |
case ' ':
|
yann@2454
|
1165 |
if (item_is_tag('t'))
|
yann@2454
|
1166 |
sym_toggle_tristate_value(sym);
|
yann@2454
|
1167 |
else if (item_is_tag('m'))
|
yann@2454
|
1168 |
conf(submenu);
|
yann@2454
|
1169 |
break;
|
yann@2454
|
1170 |
case KEY_RIGHT:
|
yann@2454
|
1171 |
case 10: /* ENTER WAS PRESSED */
|
yann@2454
|
1172 |
switch (item_tag()) {
|
yann@2454
|
1173 |
case 'm':
|
yann@2454
|
1174 |
if (single_menu_mode)
|
yann@2454
|
1175 |
submenu->data =
|
yann@2454
|
1176 |
(void *) (long) !submenu->data;
|
yann@2454
|
1177 |
else
|
yann@2454
|
1178 |
conf(submenu);
|
yann@2454
|
1179 |
break;
|
yann@2454
|
1180 |
case 't':
|
yann@2454
|
1181 |
if (sym_is_choice(sym) &&
|
yann@2454
|
1182 |
sym_get_tristate_value(sym) == yes)
|
yann@2454
|
1183 |
conf_choice(submenu);
|
yann@2454
|
1184 |
else if (submenu->prompt &&
|
yann@2454
|
1185 |
submenu->prompt->type == P_MENU)
|
yann@2454
|
1186 |
conf(submenu);
|
yann@2454
|
1187 |
else if (res == 10)
|
yann@2454
|
1188 |
sym_toggle_tristate_value(sym);
|
yann@2454
|
1189 |
break;
|
yann@2454
|
1190 |
case 's':
|
yann@2454
|
1191 |
conf_string(submenu);
|
yann@2454
|
1192 |
break;
|
yann@2454
|
1193 |
}
|
yann@2454
|
1194 |
break;
|
yann@2454
|
1195 |
case 'y':
|
yann@2454
|
1196 |
if (item_is_tag('t')) {
|
yann@2454
|
1197 |
if (sym_set_tristate_value(sym, yes))
|
yann@2454
|
1198 |
break;
|
yann@2454
|
1199 |
if (sym_set_tristate_value(sym, mod))
|
yann@2454
|
1200 |
btn_dialog(main_window, setmod_text, 0);
|
yann@2454
|
1201 |
}
|
yann@2454
|
1202 |
break;
|
yann@2454
|
1203 |
case 'n':
|
yann@2454
|
1204 |
if (item_is_tag('t'))
|
yann@2454
|
1205 |
sym_set_tristate_value(sym, no);
|
yann@2454
|
1206 |
break;
|
yann@2454
|
1207 |
case 'm':
|
yann@2454
|
1208 |
if (item_is_tag('t'))
|
yann@2454
|
1209 |
sym_set_tristate_value(sym, mod);
|
yann@2454
|
1210 |
break;
|
yann@2454
|
1211 |
}
|
yann@2454
|
1212 |
}
|
yann@2454
|
1213 |
}
|
yann@2454
|
1214 |
|
yann@2454
|
1215 |
static void conf_message_callback(const char *fmt, va_list ap)
|
yann@2454
|
1216 |
{
|
yann@2454
|
1217 |
char buf[1024];
|
yann@2454
|
1218 |
|
yann@2454
|
1219 |
vsnprintf(buf, sizeof(buf), fmt, ap);
|
yann@2454
|
1220 |
btn_dialog(main_window, buf, 1, "<OK>");
|
yann@2454
|
1221 |
}
|
yann@2454
|
1222 |
|
yann@2454
|
1223 |
static void show_help(struct menu *menu)
|
yann@2454
|
1224 |
{
|
yann@2454
|
1225 |
struct gstr help = str_new();
|
yann@2454
|
1226 |
|
yann@2454
|
1227 |
if (menu && menu->sym && menu_has_help(menu)) {
|
yann@2454
|
1228 |
if (menu->sym->name) {
|
yann@2454
|
1229 |
str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name);
|
yann@2454
|
1230 |
str_append(&help, _(menu_get_help(menu)));
|
yann@2454
|
1231 |
str_append(&help, "\n");
|
yann@2454
|
1232 |
get_symbol_str(&help, menu->sym);
|
yann@2454
|
1233 |
} else {
|
yann@2454
|
1234 |
str_append(&help, _(menu_get_help(menu)));
|
yann@2454
|
1235 |
}
|
yann@2454
|
1236 |
} else {
|
yann@2454
|
1237 |
str_append(&help, nohelp_text);
|
yann@2454
|
1238 |
}
|
yann@2454
|
1239 |
show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
|
yann@2454
|
1240 |
str_free(&help);
|
yann@2454
|
1241 |
}
|
yann@2454
|
1242 |
|
yann@2454
|
1243 |
static void conf_choice(struct menu *menu)
|
yann@2454
|
1244 |
{
|
yann@2454
|
1245 |
const char *prompt = _(menu_get_prompt(menu));
|
yann@2454
|
1246 |
struct menu *child = 0;
|
yann@2454
|
1247 |
struct symbol *active;
|
yann@2454
|
1248 |
int selected_index = 0;
|
yann@2454
|
1249 |
int last_top_row = 0;
|
yann@2454
|
1250 |
int res, i = 0;
|
yann@2454
|
1251 |
struct match_state match_state = {
|
yann@2454
|
1252 |
.in_search = 0,
|
yann@2454
|
1253 |
.match_direction = MATCH_TINKER_PATTERN_DOWN,
|
yann@2454
|
1254 |
.pattern = "",
|
yann@2454
|
1255 |
};
|
yann@2454
|
1256 |
|
yann@2454
|
1257 |
active = sym_get_choice_value(menu->sym);
|
yann@2454
|
1258 |
/* this is mostly duplicated from the conf() function. */
|
yann@2454
|
1259 |
while (!global_exit) {
|
yann@2454
|
1260 |
reset_menu();
|
yann@2454
|
1261 |
|
yann@2454
|
1262 |
for (i = 0, child = menu->list; child; child = child->next) {
|
yann@2454
|
1263 |
if (!show_all_items && !menu_is_visible(child))
|
yann@2454
|
1264 |
continue;
|
yann@2454
|
1265 |
|
yann@2454
|
1266 |
if (child->sym == sym_get_choice_value(menu->sym))
|
yann@2454
|
1267 |
item_make(child, ':', "<X> %s",
|
yann@2454
|
1268 |
_(menu_get_prompt(child)));
|
yann@2454
|
1269 |
else if (child->sym)
|
yann@2454
|
1270 |
item_make(child, ':', " %s",
|
yann@2454
|
1271 |
_(menu_get_prompt(child)));
|
yann@2454
|
1272 |
else
|
yann@2454
|
1273 |
item_make(child, ':', "*** %s ***",
|
yann@2454
|
1274 |
_(menu_get_prompt(child)));
|
yann@2454
|
1275 |
|
yann@2454
|
1276 |
if (child->sym == active){
|
yann@2454
|
1277 |
last_top_row = top_row(curses_menu);
|
yann@2454
|
1278 |
selected_index = i;
|
yann@2454
|
1279 |
}
|
yann@2454
|
1280 |
i++;
|
yann@2454
|
1281 |
}
|
yann@2454
|
1282 |
show_menu(prompt ? _(prompt) : _("Choice Menu"),
|
yann@2454
|
1283 |
_(radiolist_instructions),
|
yann@2454
|
1284 |
selected_index,
|
yann@2454
|
1285 |
&last_top_row);
|
yann@2454
|
1286 |
while (!global_exit) {
|
yann@2454
|
1287 |
if (match_state.in_search) {
|
yann@2454
|
1288 |
mvprintw(0, 0, "searching: %s",
|
yann@2454
|
1289 |
match_state.pattern);
|
yann@2454
|
1290 |
clrtoeol();
|
yann@2454
|
1291 |
}
|
yann@2454
|
1292 |
refresh_all_windows(main_window);
|
yann@2454
|
1293 |
res = wgetch(menu_win(curses_menu));
|
yann@2454
|
1294 |
if (!res)
|
yann@2454
|
1295 |
break;
|
yann@2454
|
1296 |
if (do_match(res, &match_state, &selected_index) == 0) {
|
yann@2454
|
1297 |
if (selected_index != -1)
|
yann@2454
|
1298 |
center_item(selected_index,
|
yann@2454
|
1299 |
&last_top_row);
|
yann@2454
|
1300 |
continue;
|
yann@2454
|
1301 |
}
|
yann@2454
|
1302 |
if (process_special_keys(
|
yann@2454
|
1303 |
&res,
|
yann@2454
|
1304 |
(struct menu *) item_data()))
|
yann@2454
|
1305 |
break;
|
yann@2454
|
1306 |
switch (res) {
|
yann@2454
|
1307 |
case KEY_DOWN:
|
yann@2454
|
1308 |
menu_driver(curses_menu, REQ_DOWN_ITEM);
|
yann@2454
|
1309 |
break;
|
yann@2454
|
1310 |
case KEY_UP:
|
yann@2454
|
1311 |
menu_driver(curses_menu, REQ_UP_ITEM);
|
yann@2454
|
1312 |
break;
|
yann@2454
|
1313 |
case KEY_NPAGE:
|
yann@2454
|
1314 |
menu_driver(curses_menu, REQ_SCR_DPAGE);
|
yann@2454
|
1315 |
break;
|
yann@2454
|
1316 |
case KEY_PPAGE:
|
yann@2454
|
1317 |
menu_driver(curses_menu, REQ_SCR_UPAGE);
|
yann@2454
|
1318 |
break;
|
yann@2454
|
1319 |
case KEY_HOME:
|
yann@2454
|
1320 |
menu_driver(curses_menu, REQ_FIRST_ITEM);
|
yann@2454
|
1321 |
break;
|
yann@2454
|
1322 |
case KEY_END:
|
yann@2454
|
1323 |
menu_driver(curses_menu, REQ_LAST_ITEM);
|
yann@2454
|
1324 |
break;
|
yann@2454
|
1325 |
case 'h':
|
yann@2454
|
1326 |
case '?':
|
yann@2454
|
1327 |
show_help((struct menu *) item_data());
|
yann@2454
|
1328 |
break;
|
yann@2454
|
1329 |
}
|
yann@2454
|
1330 |
if (res == 10 || res == 27 || res == ' ' ||
|
yann@2454
|
1331 |
res == KEY_LEFT){
|
yann@2454
|
1332 |
break;
|
yann@2454
|
1333 |
}
|
yann@2454
|
1334 |
refresh_all_windows(main_window);
|
yann@2454
|
1335 |
}
|
yann@2454
|
1336 |
/* if ESC or left */
|
yann@2454
|
1337 |
if (res == 27 || res == KEY_LEFT)
|
yann@2454
|
1338 |
break;
|
yann@2454
|
1339 |
|
yann@2454
|
1340 |
child = item_data();
|
yann@2454
|
1341 |
if (!child || !menu_is_visible(child) || !child->sym)
|
yann@2454
|
1342 |
continue;
|
yann@2454
|
1343 |
switch (res) {
|
yann@2454
|
1344 |
case ' ':
|
yann@2454
|
1345 |
case 10:
|
yann@2454
|
1346 |
case KEY_RIGHT:
|
yann@2454
|
1347 |
sym_set_tristate_value(child->sym, yes);
|
yann@2454
|
1348 |
return;
|
yann@2454
|
1349 |
case 'h':
|
yann@2454
|
1350 |
case '?':
|
yann@2454
|
1351 |
show_help(child);
|
yann@2454
|
1352 |
active = child->sym;
|
yann@2454
|
1353 |
break;
|
yann@2454
|
1354 |
case KEY_EXIT:
|
yann@2454
|
1355 |
return;
|
yann@2454
|
1356 |
}
|
yann@2454
|
1357 |
}
|
yann@2454
|
1358 |
}
|
yann@2454
|
1359 |
|
yann@2454
|
1360 |
static void conf_string(struct menu *menu)
|
yann@2454
|
1361 |
{
|
yann@2454
|
1362 |
const char *prompt = menu_get_prompt(menu);
|
yann@2454
|
1363 |
char dialog_input_result[256];
|
yann@2454
|
1364 |
|
yann@2454
|
1365 |
while (1) {
|
yann@2454
|
1366 |
int res;
|
yann@2454
|
1367 |
const char *heading;
|
yann@2454
|
1368 |
|
yann@2454
|
1369 |
switch (sym_get_type(menu->sym)) {
|
yann@2454
|
1370 |
case S_INT:
|
yann@2454
|
1371 |
heading = _(inputbox_instructions_int);
|
yann@2454
|
1372 |
break;
|
yann@2454
|
1373 |
case S_HEX:
|
yann@2454
|
1374 |
heading = _(inputbox_instructions_hex);
|
yann@2454
|
1375 |
break;
|
yann@2454
|
1376 |
case S_STRING:
|
yann@2454
|
1377 |
heading = _(inputbox_instructions_string);
|
yann@2454
|
1378 |
break;
|
yann@2454
|
1379 |
default:
|
yann@2454
|
1380 |
heading = _("Internal nconf error!");
|
yann@2454
|
1381 |
}
|
yann@2454
|
1382 |
res = dialog_inputbox(main_window,
|
yann@2454
|
1383 |
prompt ? _(prompt) : _("Main Menu"),
|
yann@2454
|
1384 |
heading,
|
yann@2454
|
1385 |
sym_get_string_value(menu->sym),
|
yann@2454
|
1386 |
dialog_input_result,
|
yann@2454
|
1387 |
sizeof(dialog_input_result));
|
yann@2454
|
1388 |
switch (res) {
|
yann@2454
|
1389 |
case 0:
|
yann@2454
|
1390 |
if (sym_set_string_value(menu->sym,
|
yann@2454
|
1391 |
dialog_input_result))
|
yann@2454
|
1392 |
return;
|
yann@2454
|
1393 |
btn_dialog(main_window,
|
yann@2454
|
1394 |
_("You have made an invalid entry."), 0);
|
yann@2454
|
1395 |
break;
|
yann@2454
|
1396 |
case 1:
|
yann@2454
|
1397 |
show_help(menu);
|
yann@2454
|
1398 |
break;
|
yann@2454
|
1399 |
case KEY_EXIT:
|
yann@2454
|
1400 |
return;
|
yann@2454
|
1401 |
}
|
yann@2454
|
1402 |
}
|
yann@2454
|
1403 |
}
|
yann@2454
|
1404 |
|
yann@2454
|
1405 |
static void conf_load(void)
|
yann@2454
|
1406 |
{
|
yann@2454
|
1407 |
char dialog_input_result[256];
|
yann@2454
|
1408 |
while (1) {
|
yann@2454
|
1409 |
int res;
|
yann@2454
|
1410 |
res = dialog_inputbox(main_window,
|
yann@2454
|
1411 |
NULL, load_config_text,
|
yann@2454
|
1412 |
filename,
|
yann@2454
|
1413 |
dialog_input_result,
|
yann@2454
|
1414 |
sizeof(dialog_input_result));
|
yann@2454
|
1415 |
switch (res) {
|
yann@2454
|
1416 |
case 0:
|
yann@2454
|
1417 |
if (!dialog_input_result[0])
|
yann@2454
|
1418 |
return;
|
yann@2454
|
1419 |
if (!conf_read(dialog_input_result)) {
|
yann@2454
|
1420 |
set_config_filename(dialog_input_result);
|
yann@2454
|
1421 |
sym_set_change_count(1);
|
yann@2454
|
1422 |
return;
|
yann@2454
|
1423 |
}
|
yann@2454
|
1424 |
btn_dialog(main_window, _("File does not exist!"), 0);
|
yann@2454
|
1425 |
break;
|
yann@2454
|
1426 |
case 1:
|
yann@2454
|
1427 |
show_scroll_win(main_window,
|
yann@2454
|
1428 |
_("Load Alternate Configuration"),
|
yann@2454
|
1429 |
load_config_help);
|
yann@2454
|
1430 |
break;
|
yann@2454
|
1431 |
case KEY_EXIT:
|
yann@2454
|
1432 |
return;
|
yann@2454
|
1433 |
}
|
yann@2454
|
1434 |
}
|
yann@2454
|
1435 |
}
|
yann@2454
|
1436 |
|
yann@2454
|
1437 |
static void conf_save(void)
|
yann@2454
|
1438 |
{
|
yann@2454
|
1439 |
char dialog_input_result[256];
|
yann@2454
|
1440 |
while (1) {
|
yann@2454
|
1441 |
int res;
|
yann@2454
|
1442 |
res = dialog_inputbox(main_window,
|
yann@2454
|
1443 |
NULL, save_config_text,
|
yann@2454
|
1444 |
filename,
|
yann@2454
|
1445 |
dialog_input_result,
|
yann@2454
|
1446 |
sizeof(dialog_input_result));
|
yann@2454
|
1447 |
switch (res) {
|
yann@2454
|
1448 |
case 0:
|
yann@2454
|
1449 |
if (!dialog_input_result[0])
|
yann@2454
|
1450 |
return;
|
yann@2454
|
1451 |
res = conf_write(dialog_input_result);
|
yann@2454
|
1452 |
if (!res) {
|
yann@2454
|
1453 |
set_config_filename(dialog_input_result);
|
yann@2454
|
1454 |
return;
|
yann@2454
|
1455 |
}
|
yann@2454
|
1456 |
btn_dialog(main_window, _("Can't create file! "
|
yann@2454
|
1457 |
"Probably a nonexistent directory."),
|
yann@2454
|
1458 |
1, "<OK>");
|
yann@2454
|
1459 |
break;
|
yann@2454
|
1460 |
case 1:
|
yann@2454
|
1461 |
show_scroll_win(main_window,
|
yann@2454
|
1462 |
_("Save Alternate Configuration"),
|
yann@2454
|
1463 |
save_config_help);
|
yann@2454
|
1464 |
break;
|
yann@2454
|
1465 |
case KEY_EXIT:
|
yann@2454
|
1466 |
return;
|
yann@2454
|
1467 |
}
|
yann@2454
|
1468 |
}
|
yann@2454
|
1469 |
}
|
yann@2454
|
1470 |
|
yann@2454
|
1471 |
void setup_windows(void)
|
yann@2454
|
1472 |
{
|
yann@2454
|
1473 |
if (main_window != NULL)
|
yann@2454
|
1474 |
delwin(main_window);
|
yann@2454
|
1475 |
|
yann@2454
|
1476 |
/* set up the menu and menu window */
|
yann@2454
|
1477 |
main_window = newwin(LINES-2, COLS-2, 2, 1);
|
yann@2454
|
1478 |
keypad(main_window, TRUE);
|
yann@2454
|
1479 |
mwin_max_lines = LINES-7;
|
yann@2454
|
1480 |
mwin_max_cols = COLS-6;
|
yann@2454
|
1481 |
|
yann@2454
|
1482 |
/* panels order is from bottom to top */
|
yann@2454
|
1483 |
new_panel(main_window);
|
yann@2454
|
1484 |
}
|
yann@2454
|
1485 |
|
yann@2454
|
1486 |
int main(int ac, char **av)
|
yann@2454
|
1487 |
{
|
yann@2454
|
1488 |
char *mode;
|
yann@2454
|
1489 |
|
yann@2454
|
1490 |
setlocale(LC_ALL, "");
|
yann@2454
|
1491 |
bindtextdomain(PACKAGE, LOCALEDIR);
|
yann@2454
|
1492 |
textdomain(PACKAGE);
|
yann@2454
|
1493 |
|
yann@2454
|
1494 |
conf_parse(av[1]);
|
yann@2454
|
1495 |
conf_read(NULL);
|
yann@2454
|
1496 |
|
yann@2454
|
1497 |
mode = getenv("NCONFIG_MODE");
|
yann@2454
|
1498 |
if (mode) {
|
yann@2454
|
1499 |
if (!strcasecmp(mode, "single_menu"))
|
yann@2454
|
1500 |
single_menu_mode = 1;
|
yann@2454
|
1501 |
}
|
yann@2454
|
1502 |
|
yann@2454
|
1503 |
/* Initialize curses */
|
yann@2454
|
1504 |
initscr();
|
yann@2454
|
1505 |
/* set color theme */
|
yann@2454
|
1506 |
set_colors();
|
yann@2454
|
1507 |
|
yann@2454
|
1508 |
cbreak();
|
yann@2454
|
1509 |
noecho();
|
yann@2454
|
1510 |
keypad(stdscr, TRUE);
|
yann@2454
|
1511 |
curs_set(0);
|
yann@2454
|
1512 |
|
yann@2454
|
1513 |
if (COLS < 75 || LINES < 20) {
|
yann@2454
|
1514 |
endwin();
|
yann@2454
|
1515 |
printf("Your terminal should have at "
|
yann@2454
|
1516 |
"least 20 lines and 75 columns\n");
|
yann@2454
|
1517 |
return 1;
|
yann@2454
|
1518 |
}
|
yann@2454
|
1519 |
|
yann@2454
|
1520 |
notimeout(stdscr, FALSE);
|
yann@2454
|
1521 |
ESCDELAY = 1;
|
yann@2454
|
1522 |
|
yann@2454
|
1523 |
/* set btns menu */
|
yann@2454
|
1524 |
curses_menu = new_menu(curses_menu_items);
|
yann@2454
|
1525 |
menu_opts_off(curses_menu, O_SHOWDESC);
|
yann@2454
|
1526 |
menu_opts_on(curses_menu, O_SHOWMATCH);
|
yann@2454
|
1527 |
menu_opts_on(curses_menu, O_ONEVALUE);
|
yann@2454
|
1528 |
menu_opts_on(curses_menu, O_NONCYCLIC);
|
yann@2454
|
1529 |
menu_opts_on(curses_menu, O_IGNORECASE);
|
yann@2454
|
1530 |
set_menu_mark(curses_menu, " ");
|
yann@2454
|
1531 |
set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
|
yann@2454
|
1532 |
set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
|
yann@2454
|
1533 |
set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
|
yann@2454
|
1534 |
|
yann@2454
|
1535 |
set_config_filename(conf_get_configname());
|
yann@2454
|
1536 |
setup_windows();
|
yann@2454
|
1537 |
|
yann@2454
|
1538 |
/* check for KEY_FUNC(1) */
|
yann@2454
|
1539 |
if (has_key(KEY_F(1)) == FALSE) {
|
yann@2454
|
1540 |
show_scroll_win(main_window,
|
yann@2454
|
1541 |
_("Instructions"),
|
yann@2454
|
1542 |
_(menu_no_f_instructions));
|
yann@2454
|
1543 |
}
|
yann@2454
|
1544 |
|
yann@2454
|
1545 |
conf_set_message_callback(conf_message_callback);
|
yann@2454
|
1546 |
/* do the work */
|
yann@2454
|
1547 |
while (!global_exit) {
|
yann@2454
|
1548 |
conf(&rootmenu);
|
yann@2454
|
1549 |
if (!global_exit && do_exit() == 0)
|
yann@2454
|
1550 |
break;
|
yann@2454
|
1551 |
}
|
yann@2454
|
1552 |
/* ok, we are done */
|
yann@2454
|
1553 |
unpost_menu(curses_menu);
|
yann@2454
|
1554 |
free_menu(curses_menu);
|
yann@2454
|
1555 |
delwin(main_window);
|
yann@2454
|
1556 |
clear();
|
yann@2454
|
1557 |
refresh();
|
yann@2454
|
1558 |
endwin();
|
yann@2454
|
1559 |
return 0;
|
yann@2454
|
1560 |
}
|
yann@2454
|
1561 |
|