1.1 --- a/.hgignore Mon May 09 20:15:39 2011 +0200
1.2 +++ b/.hgignore Thu May 12 19:45:30 2011 +0200
1.3 @@ -10,7 +10,7 @@
1.4 scripts/saveSample.sh
1.5 scripts/showTuple.sh
1.6 kconfig/conf
1.7 -kconfig/mconf
1.8 +kconfig/?conf
1.9 kconfig/**.o
1.10 kconfig/**.dep
1.11 config.gen/
2.1 --- a/kconfig/kconfig.mk Mon May 09 20:15:39 2011 +0200
2.2 +++ b/kconfig/kconfig.mk Thu May 12 19:45:30 2011 +0200
2.3 @@ -11,7 +11,7 @@
2.4 #-----------------------------------------------------------
2.5 # The configurators rules
2.6
2.7 -configurators = menuconfig oldconfig
2.8 +configurators = menuconfig nconfig oldconfig
2.9 PHONY += $(configurators)
2.10
2.11 $(configurators): config_files
2.12 @@ -20,6 +20,10 @@
2.13 @$(ECHO) " CONF $(KCONFIG_TOP)"
2.14 $(SILENT)$< $(KCONFIG_TOP)
2.15
2.16 +nconfig: $(obj)/nconf
2.17 + @$(ECHO) " CONF $(KCONFIG_TOP)"
2.18 + $(SILENT)$< $(KCONFIG_TOP)
2.19 +
2.20 oldconfig: $(obj)/conf .config
2.21 @$(ECHO) " CONF $(KCONFIG_TOP)"
2.22 $(SILENT)$< --silent$@ $(KCONFIG_TOP)
2.23 @@ -103,13 +107,24 @@
2.24 mconf_DEP = $(patsubst %.c,%.dep,$(mconf_SRC))
2.25 $(mconf_OBJ) $(mconf_DEP): CFLAGS += $(NCURSES_CFLAGS) $(INTL_CFLAGS)
2.26 $(obj)/mconf: LDFLAGS += $(NCURSES_LDFLAGS)
2.27 +
2.28 +# What's needed to build 'nconf'
2.29 +nconf_SRC = kconfig/nconf.c kconfig/nconf.gui.c
2.30 +nconf_OBJ = $(patsubst %.c,%.o,$(nconf_SRC))
2.31 +nconf_DEP = $(patsubst %.c,%.dep,$(nconf_SRC))
2.32 +$(nconf_OBJ) $(nconf_DEP): CFLAGS += $(INTL_CFLAGS)
2.33 +$(obj)/nconf: LDFLAGS += -lmenu -lpanel -lncurses
2.34 +
2.35 +# Under Cygwin, we need to auto-import some libs (which ones, exactly?)
2.36 +# for mconf and nconf to lin properly.
2.37 ifeq ($(shell uname -o 2>/dev/null || echo unknown),Cygwin)
2.38 $(obj)/mconf: LDFLAGS += -Wl,--enable-auto-import
2.39 +$(obj)/nconf: LDFLAGS += -Wl,--enable-auto-import
2.40 endif
2.41
2.42 # These are generated files:
2.43 -ALL_OBJS = $(sort $(COMMON_OBJ) $(LX_OBJ) $(conf_OBJ) $(mconf_OBJ))
2.44 -ALL_DEPS = $(sort $(COMMON_DEP) $(LX_DEP) $(conf_DEP) $(mconf_DEP))
2.45 +ALL_OBJS = $(sort $(COMMON_OBJ) $(LX_OBJ) $(conf_OBJ) $(mconf_OBJ) $(nconf_OBJ))
2.46 +ALL_DEPS = $(sort $(COMMON_DEP) $(LX_DEP) $(conf_DEP) $(mconf_DEP) $(nconf_DEP))
2.47
2.48 # Cheesy auto-dependencies
2.49 # Only parse the following if a configurator was called, to avoid building
2.50 @@ -133,6 +148,9 @@
2.51 $(LX_OBJ) $(LX_DEP): |dochecklxdialog
2.52 $(mconf_OBJ) $(mconf_DEP): |dochecklxdialog
2.53 endif
2.54 +ifneq ($(strip $(filter nconfig,$(MAKECMDGOALS))),)
2.55 +DEPS += $(nconf_DEP)
2.56 +endif
2.57
2.58 -include $(DEPS)
2.59
2.60 @@ -170,6 +188,10 @@
2.61 @$(ECHO) ' LD $@'
2.62 $(SILENT)$(HOST_LD) -o $@ $^ $(LDFLAGS) $(EXTRA_LDFLAGS)
2.63
2.64 +$(obj)/nconf: $(COMMON_OBJ) $(nconf_OBJ)
2.65 + @$(ECHO) ' LD $@'
2.66 + $(SILENT)$(HOST_LD) -o $@ $^ $(LDFLAGS) $(EXTRA_LDFLAGS)
2.67 +
2.68 $(obj)/conf: $(COMMON_OBJ) $(conf_OBJ)
2.69 @$(ECHO) ' LD $@'
2.70 $(SILENT)$(HOST_LD) -o $@ $^ $(LDFLAGS) $(EXTRA_LDFLAGS)
2.71 @@ -179,5 +201,5 @@
2.72
2.73 clean::
2.74 @$(ECHO) " CLEAN kconfig"
2.75 - $(SILENT)rm -f kconfig/{,m}conf{,.exe} $(ALL_OBJS) $(ALL_DEPS)
2.76 + $(SILENT)rm -f kconfig/{,m,n}conf{,.exe} $(ALL_OBJS) $(ALL_DEPS)
2.77 $(SILENT)rmdir --ignore-fail-on-non-empty kconfig{/lxdialog,} 2>/dev/null || true
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/kconfig/nconf.c Thu May 12 19:45:30 2011 +0200
3.3 @@ -0,0 +1,1561 @@
3.4 +/*
3.5 + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3.6 + * Released under the terms of the GNU GPL v2.0.
3.7 + *
3.8 + * Derived from menuconfig.
3.9 + *
3.10 + */
3.11 +#define _GNU_SOURCE
3.12 +#include <string.h>
3.13 +#define LKC_DIRECT_LINK
3.14 +#include "lkc.h"
3.15 +#include "nconf.h"
3.16 +#include <ctype.h>
3.17 +
3.18 +static const char nconf_readme[] = N_(
3.19 +"Overview\n"
3.20 +"--------\n"
3.21 +"This interface let you select features and parameters for the build.\n"
3.22 +"Features can either be built-in, modularized, or ignored. Parameters\n"
3.23 +"must be entered in as decimal or hexadecimal numbers or text.\n"
3.24 +"\n"
3.25 +"Menu items beginning with following braces represent features that\n"
3.26 +" [ ] can be built in or removed\n"
3.27 +" < > can be built in, modularized or removed\n"
3.28 +" { } can be built in or modularized (selected by other feature)\n"
3.29 +" - - are selected by other feature,\n"
3.30 +" XXX cannot be selected. Use Symbol Info to find out why,\n"
3.31 +"while *, M or whitespace inside braces means to build in, build as\n"
3.32 +"a module or to exclude the feature respectively.\n"
3.33 +"\n"
3.34 +"To change any of these features, highlight it with the cursor\n"
3.35 +"keys and press <Y> to build it in, <M> to make it a module or\n"
3.36 +"<N> to removed it. You may also press the <Space Bar> to cycle\n"
3.37 +"through the available options (ie. Y->N->M->Y).\n"
3.38 +"\n"
3.39 +"Some additional keyboard hints:\n"
3.40 +"\n"
3.41 +"Menus\n"
3.42 +"----------\n"
3.43 +"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
3.44 +" you wish to change use <Enter> or <Space>. Goto submenu by \n"
3.45 +" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
3.46 +" Submenus are designated by \"--->\".\n"
3.47 +"\n"
3.48 +" Searching: pressing '/' triggers interactive search mode.\n"
3.49 +" nconfig performs a case insensitive search for the string\n"
3.50 +" in the menu prompts (no regex support).\n"
3.51 +" Pressing the up/down keys highlights the previous/next\n"
3.52 +" matching item. Backspace removes one character from the\n"
3.53 +" match string. Pressing either '/' again or ESC exits\n"
3.54 +" search mode. All other keys behave normally.\n"
3.55 +"\n"
3.56 +" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
3.57 +" unseen options into view.\n"
3.58 +"\n"
3.59 +"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
3.60 +"\n"
3.61 +"o To get help with an item, press <F1>\n"
3.62 +" Shortcut: Press <h> or <?>.\n"
3.63 +"\n"
3.64 +"\n"
3.65 +"Radiolists (Choice lists)\n"
3.66 +"-----------\n"
3.67 +"o Use the cursor keys to select the option you wish to set and press\n"
3.68 +" <S> or the <SPACE BAR>.\n"
3.69 +"\n"
3.70 +" Shortcut: Press the first letter of the option you wish to set then\n"
3.71 +" press <S> or <SPACE BAR>.\n"
3.72 +"\n"
3.73 +"o To see available help for the item, press <F1>\n"
3.74 +" Shortcut: Press <H> or <?>.\n"
3.75 +"\n"
3.76 +"\n"
3.77 +"Data Entry\n"
3.78 +"-----------\n"
3.79 +"o Enter the requested information and press <ENTER>\n"
3.80 +" If you are entering hexadecimal values, it is not necessary to\n"
3.81 +" add the '0x' prefix to the entry.\n"
3.82 +"\n"
3.83 +"o For help, press <F1>.\n"
3.84 +"\n"
3.85 +"\n"
3.86 +"Text Box (Help Window)\n"
3.87 +"--------\n"
3.88 +"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
3.89 +" keys h,j,k,l function here as do <SPACE BAR> for those\n"
3.90 +" who are familiar with less and lynx.\n"
3.91 +"\n"
3.92 +"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
3.93 +"\n"
3.94 +"\n"
3.95 +"Alternate Configuration Files\n"
3.96 +"-----------------------------\n"
3.97 +"nconfig supports the use of alternate configuration files for\n"
3.98 +"those who, for various reasons, find it necessary to switch\n"
3.99 +"between different configurations.\n"
3.100 +"\n"
3.101 +"At the end of the main menu you will find two options. One is\n"
3.102 +"for saving the current configuration to a file of your choosing.\n"
3.103 +"The other option is for loading a previously saved alternate\n"
3.104 +"configuration.\n"
3.105 +"\n"
3.106 +"Even if you don't use alternate configuration files, but you\n"
3.107 +"find during a nconfig session that you have completely messed\n"
3.108 +"up your settings, you may use the \"Load Alternate...\" option to\n"
3.109 +"restore your previously saved settings from \".config\" without\n"
3.110 +"restarting nconfig.\n"
3.111 +"\n"
3.112 +"Other information\n"
3.113 +"-----------------\n"
3.114 +"If you use nconfig in an XTERM window make sure you have your\n"
3.115 +"$TERM variable set to point to a xterm definition which supports color.\n"
3.116 +"Otherwise, nconfig will look rather bad. nconfig will not\n"
3.117 +"display correctly in a RXVT window because rxvt displays only one\n"
3.118 +"intensity of color, bright.\n"
3.119 +"\n"
3.120 +"nconfig will display larger menus on screens or xterms which are\n"
3.121 +"set to display more than the standard 25 row by 80 column geometry.\n"
3.122 +"In order for this to work, the \"stty size\" command must be able to\n"
3.123 +"display the screen's current row and column geometry. I STRONGLY\n"
3.124 +"RECOMMEND that you make sure you do NOT have the shell variables\n"
3.125 +"LINES and COLUMNS exported into your environment. Some distributions\n"
3.126 +"export those variables via /etc/profile. Some ncurses programs can\n"
3.127 +"become confused when those variables (LINES & COLUMNS) don't reflect\n"
3.128 +"the true screen size.\n"
3.129 +"\n"
3.130 +"Optional personality available\n"
3.131 +"------------------------------\n"
3.132 +"If you prefer to have all of the options listed in a single menu, rather\n"
3.133 +"than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n"
3.134 +"environment variable set to single_menu. Example:\n"
3.135 +"\n"
3.136 +"make NCONFIG_MODE=single_menu nconfig\n"
3.137 +"\n"
3.138 +"<Enter> will then unroll the appropriate category, or enfold it if it\n"
3.139 +"is already unrolled.\n"
3.140 +"\n"
3.141 +"Note that this mode can eventually be a little more CPU expensive\n"
3.142 +"(especially with a larger number of unrolled categories) than the\n"
3.143 +"default mode.\n"
3.144 +"\n"),
3.145 +menu_no_f_instructions[] = N_(
3.146 +" You do not have function keys support. Please follow the\n"
3.147 +" following instructions:\n"
3.148 +" Arrow keys navigate the menu.\n"
3.149 +" <Enter> or <right-arrow> selects submenus --->.\n"
3.150 +" Capital Letters are hotkeys.\n"
3.151 +" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
3.152 +" Pressing SpaceBar toggles between the above options.\n"
3.153 +" Press <Esc> or <left-arrow> to go back one menu,\n"
3.154 +" <?> or <h> for Help, </> for Search.\n"
3.155 +" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
3.156 +" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
3.157 +" <Esc> always leaves the current window.\n"),
3.158 +menu_instructions[] = N_(
3.159 +" Arrow keys navigate the menu.\n"
3.160 +" <Enter> or <right-arrow> selects submenus --->.\n"
3.161 +" Capital Letters are hotkeys.\n"
3.162 +" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
3.163 +" Pressing SpaceBar toggles between the above options\n"
3.164 +" Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
3.165 +" <?>, <F1> or <h> for Help, </> for Search.\n"
3.166 +" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
3.167 +" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
3.168 +" <Esc> always leaves the current window\n"),
3.169 +radiolist_instructions[] = N_(
3.170 +" Use the arrow keys to navigate this window or\n"
3.171 +" press the hotkey of the item you wish to select\n"
3.172 +" followed by the <SPACE BAR>.\n"
3.173 +" Press <?>, <F1> or <h> for additional information about this option.\n"),
3.174 +inputbox_instructions_int[] = N_(
3.175 +"Please enter a decimal value.\n"
3.176 +"Fractions will not be accepted.\n"
3.177 +"Press <RETURN> to accept, <ESC> to cancel."),
3.178 +inputbox_instructions_hex[] = N_(
3.179 +"Please enter a hexadecimal value.\n"
3.180 +"Press <RETURN> to accept, <ESC> to cancel."),
3.181 +inputbox_instructions_string[] = N_(
3.182 +"Please enter a string value.\n"
3.183 +"Press <RETURN> to accept, <ESC> to cancel."),
3.184 +setmod_text[] = N_(
3.185 +"This feature depends on another which\n"
3.186 +"has been configured as a module.\n"
3.187 +"As a result, this feature will be built as a module."),
3.188 +nohelp_text[] = N_(
3.189 +"There is no help available for this option.\n"),
3.190 +load_config_text[] = N_(
3.191 +"Enter the name of the configuration file you wish to load.\n"
3.192 +"Accept the name shown to restore the configuration you\n"
3.193 +"last retrieved. Leave blank to abort."),
3.194 +load_config_help[] = N_(
3.195 +"\n"
3.196 +"For various reasons, one may wish to keep several different\n"
3.197 +"configurations available on a single machine.\n"
3.198 +"\n"
3.199 +"If you have saved a previous configuration in a file other than the\n"
3.200 +"default one, entering its name here will allow you to modify that\n"
3.201 +"configuration.\n"
3.202 +"\n"
3.203 +"If you are uncertain, then you have probably never used alternate\n"
3.204 +"configuration files. You should therefor leave this blank to abort.\n"),
3.205 +save_config_text[] = N_(
3.206 +"Enter a filename to which this configuration should be saved\n"
3.207 +"as an alternate. Leave blank to abort."),
3.208 +save_config_help[] = N_(
3.209 +"\n"
3.210 +"For various reasons, one may wish to keep different configurations\n"
3.211 +"available on a single machine.\n"
3.212 +"\n"
3.213 +"Entering a file name here will allow you to later retrieve, modify\n"
3.214 +"and use the current configuration as an alternate to whatever\n"
3.215 +"configuration options you have selected at that time.\n"
3.216 +"\n"
3.217 +"If you are uncertain what all this means then you should probably\n"
3.218 +"leave this blank.\n"),
3.219 +search_help[] = N_(
3.220 +"\n"
3.221 +"Search for symbols and display their relations. Regular expressions\n"
3.222 +"are allowed.\n"
3.223 +"Example: search for \"^FOO\"\n"
3.224 +"Result:\n"
3.225 +"-----------------------------------------------------------------\n"
3.226 +"Symbol: FOO [ = m]\n"
3.227 +"Prompt: Foo bus is used to drive the bar HW\n"
3.228 +"Defined at drivers/pci/Kconfig:47\n"
3.229 +"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
3.230 +"Location:\n"
3.231 +" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
3.232 +" -> PCI support (PCI [ = y])\n"
3.233 +" -> PCI access mode (<choice> [ = y])\n"
3.234 +"Selects: LIBCRC32\n"
3.235 +"Selected by: BAR\n"
3.236 +"-----------------------------------------------------------------\n"
3.237 +"o The line 'Prompt:' shows the text used in the menu structure for\n"
3.238 +" this symbol\n"
3.239 +"o The 'Defined at' line tell at what file / line number the symbol\n"
3.240 +" is defined\n"
3.241 +"o The 'Depends on:' line tell what symbols needs to be defined for\n"
3.242 +" this symbol to be visible in the menu (selectable)\n"
3.243 +"o The 'Location:' lines tell where in the menu structure this symbol\n"
3.244 +" is located\n"
3.245 +" A location followed by a [ = y] indicate that this is a selectable\n"
3.246 +" menu item - and current value is displayed inside brackets.\n"
3.247 +"o The 'Selects:' line tell what symbol will be automatically\n"
3.248 +" selected if this symbol is selected (y or m)\n"
3.249 +"o The 'Selected by' line tell what symbol has selected this symbol\n"
3.250 +"\n"
3.251 +"Only relevant lines are shown.\n"
3.252 +"\n\n"
3.253 +"Search examples:\n"
3.254 +"Examples: USB => find all symbols containing USB\n"
3.255 +" ^USB => find all symbols starting with USB\n"
3.256 +" USB$ => find all symbols ending with USB\n"
3.257 +"\n");
3.258 +
3.259 +struct mitem {
3.260 + char str[256];
3.261 + char tag;
3.262 + void *usrptr;
3.263 + int is_visible;
3.264 +};
3.265 +
3.266 +#define MAX_MENU_ITEMS 4096
3.267 +static int show_all_items;
3.268 +static int indent;
3.269 +static struct menu *current_menu;
3.270 +static int child_count;
3.271 +static int single_menu_mode;
3.272 +/* the window in which all information appears */
3.273 +static WINDOW *main_window;
3.274 +/* the largest size of the menu window */
3.275 +static int mwin_max_lines;
3.276 +static int mwin_max_cols;
3.277 +/* the window in which we show option buttons */
3.278 +static MENU *curses_menu;
3.279 +static ITEM *curses_menu_items[MAX_MENU_ITEMS];
3.280 +static struct mitem k_menu_items[MAX_MENU_ITEMS];
3.281 +static int items_num;
3.282 +static int global_exit;
3.283 +/* the currently selected button */
3.284 +const char *current_instructions = menu_instructions;
3.285 +
3.286 +static void conf(struct menu *menu);
3.287 +static void conf_choice(struct menu *menu);
3.288 +static void conf_string(struct menu *menu);
3.289 +static void conf_load(void);
3.290 +static void conf_save(void);
3.291 +static void show_help(struct menu *menu);
3.292 +static int do_exit(void);
3.293 +static void setup_windows(void);
3.294 +static void search_conf(void);
3.295 +
3.296 +typedef void (*function_key_handler_t)(int *key, struct menu *menu);
3.297 +static void handle_f1(int *key, struct menu *current_item);
3.298 +static void handle_f2(int *key, struct menu *current_item);
3.299 +static void handle_f3(int *key, struct menu *current_item);
3.300 +static void handle_f4(int *key, struct menu *current_item);
3.301 +static void handle_f5(int *key, struct menu *current_item);
3.302 +static void handle_f6(int *key, struct menu *current_item);
3.303 +static void handle_f7(int *key, struct menu *current_item);
3.304 +static void handle_f8(int *key, struct menu *current_item);
3.305 +static void handle_f9(int *key, struct menu *current_item);
3.306 +
3.307 +struct function_keys {
3.308 + const char *key_str;
3.309 + const char *func;
3.310 + function_key key;
3.311 + function_key_handler_t handler;
3.312 +};
3.313 +
3.314 +static const int function_keys_num = 9;
3.315 +struct function_keys function_keys[] = {
3.316 + {
3.317 + .key_str = "F1",
3.318 + .func = "Help",
3.319 + .key = F_HELP,
3.320 + .handler = handle_f1,
3.321 + },
3.322 + {
3.323 + .key_str = "F2",
3.324 + .func = "Sym Info",
3.325 + .key = F_SYMBOL,
3.326 + .handler = handle_f2,
3.327 + },
3.328 + {
3.329 + .key_str = "F3",
3.330 + .func = "Insts",
3.331 + .key = F_INSTS,
3.332 + .handler = handle_f3,
3.333 + },
3.334 + {
3.335 + .key_str = "F4",
3.336 + .func = "Config",
3.337 + .key = F_CONF,
3.338 + .handler = handle_f4,
3.339 + },
3.340 + {
3.341 + .key_str = "F5",
3.342 + .func = "Back",
3.343 + .key = F_BACK,
3.344 + .handler = handle_f5,
3.345 + },
3.346 + {
3.347 + .key_str = "F6",
3.348 + .func = "Save",
3.349 + .key = F_SAVE,
3.350 + .handler = handle_f6,
3.351 + },
3.352 + {
3.353 + .key_str = "F7",
3.354 + .func = "Load",
3.355 + .key = F_LOAD,
3.356 + .handler = handle_f7,
3.357 + },
3.358 + {
3.359 + .key_str = "F8",
3.360 + .func = "Sym Search",
3.361 + .key = F_SEARCH,
3.362 + .handler = handle_f8,
3.363 + },
3.364 + {
3.365 + .key_str = "F9",
3.366 + .func = "Exit",
3.367 + .key = F_EXIT,
3.368 + .handler = handle_f9,
3.369 + },
3.370 +};
3.371 +
3.372 +static void print_function_line(void)
3.373 +{
3.374 + int i;
3.375 + int offset = 1;
3.376 + const int skip = 1;
3.377 +
3.378 + for (i = 0; i < function_keys_num; i++) {
3.379 + (void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
3.380 + mvwprintw(main_window, LINES-3, offset,
3.381 + "%s",
3.382 + function_keys[i].key_str);
3.383 + (void) wattrset(main_window, attributes[FUNCTION_TEXT]);
3.384 + offset += strlen(function_keys[i].key_str);
3.385 + mvwprintw(main_window, LINES-3,
3.386 + offset, "%s",
3.387 + function_keys[i].func);
3.388 + offset += strlen(function_keys[i].func) + skip;
3.389 + }
3.390 + (void) wattrset(main_window, attributes[NORMAL]);
3.391 +}
3.392 +
3.393 +/* help */
3.394 +static void handle_f1(int *key, struct menu *current_item)
3.395 +{
3.396 + show_scroll_win(main_window,
3.397 + _("README"), _(nconf_readme));
3.398 + return;
3.399 +}
3.400 +
3.401 +/* symbole help */
3.402 +static void handle_f2(int *key, struct menu *current_item)
3.403 +{
3.404 + show_help(current_item);
3.405 + return;
3.406 +}
3.407 +
3.408 +/* instructions */
3.409 +static void handle_f3(int *key, struct menu *current_item)
3.410 +{
3.411 + show_scroll_win(main_window,
3.412 + _("Instructions"),
3.413 + _(current_instructions));
3.414 + return;
3.415 +}
3.416 +
3.417 +/* config */
3.418 +static void handle_f4(int *key, struct menu *current_item)
3.419 +{
3.420 + int res = btn_dialog(main_window,
3.421 + _("Show all symbols?"),
3.422 + 2,
3.423 + " <Show All> ",
3.424 + "<Don't show all>");
3.425 + if (res == 0)
3.426 + show_all_items = 1;
3.427 + else if (res == 1)
3.428 + show_all_items = 0;
3.429 +
3.430 + return;
3.431 +}
3.432 +
3.433 +/* back */
3.434 +static void handle_f5(int *key, struct menu *current_item)
3.435 +{
3.436 + *key = KEY_LEFT;
3.437 + return;
3.438 +}
3.439 +
3.440 +/* save */
3.441 +static void handle_f6(int *key, struct menu *current_item)
3.442 +{
3.443 + conf_save();
3.444 + return;
3.445 +}
3.446 +
3.447 +/* load */
3.448 +static void handle_f7(int *key, struct menu *current_item)
3.449 +{
3.450 + conf_load();
3.451 + return;
3.452 +}
3.453 +
3.454 +/* search */
3.455 +static void handle_f8(int *key, struct menu *current_item)
3.456 +{
3.457 + search_conf();
3.458 + return;
3.459 +}
3.460 +
3.461 +/* exit */
3.462 +static void handle_f9(int *key, struct menu *current_item)
3.463 +{
3.464 + do_exit();
3.465 + return;
3.466 +}
3.467 +
3.468 +/* return != 0 to indicate the key was handles */
3.469 +static int process_special_keys(int *key, struct menu *menu)
3.470 +{
3.471 + int i;
3.472 +
3.473 + if (*key == KEY_RESIZE) {
3.474 + setup_windows();
3.475 + return 1;
3.476 + }
3.477 +
3.478 + for (i = 0; i < function_keys_num; i++) {
3.479 + if (*key == KEY_F(function_keys[i].key) ||
3.480 + *key == '0' + function_keys[i].key){
3.481 + function_keys[i].handler(key, menu);
3.482 + return 1;
3.483 + }
3.484 + }
3.485 +
3.486 + return 0;
3.487 +}
3.488 +
3.489 +static void clean_items(void)
3.490 +{
3.491 + int i;
3.492 + for (i = 0; curses_menu_items[i]; i++)
3.493 + free_item(curses_menu_items[i]);
3.494 + bzero(curses_menu_items, sizeof(curses_menu_items));
3.495 + bzero(k_menu_items, sizeof(k_menu_items));
3.496 + items_num = 0;
3.497 +}
3.498 +
3.499 +typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
3.500 + FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
3.501 +
3.502 +/* return the index of the matched item, or -1 if no such item exists */
3.503 +static int get_mext_match(const char *match_str, match_f flag)
3.504 +{
3.505 + int match_start = item_index(current_item(curses_menu));
3.506 + int index;
3.507 +
3.508 + if (flag == FIND_NEXT_MATCH_DOWN)
3.509 + ++match_start;
3.510 + else if (flag == FIND_NEXT_MATCH_UP)
3.511 + --match_start;
3.512 +
3.513 + index = match_start;
3.514 + index = (index + items_num) % items_num;
3.515 + while (true) {
3.516 + char *str = k_menu_items[index].str;
3.517 + if (strcasestr(str, match_str) != 0)
3.518 + return index;
3.519 + if (flag == FIND_NEXT_MATCH_UP ||
3.520 + flag == MATCH_TINKER_PATTERN_UP)
3.521 + --index;
3.522 + else
3.523 + ++index;
3.524 + index = (index + items_num) % items_num;
3.525 + if (index == match_start)
3.526 + return -1;
3.527 + }
3.528 +}
3.529 +
3.530 +/* Make a new item. */
3.531 +static void item_make(struct menu *menu, char tag, const char *fmt, ...)
3.532 +{
3.533 + va_list ap;
3.534 +
3.535 + if (items_num > MAX_MENU_ITEMS-1)
3.536 + return;
3.537 +
3.538 + bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
3.539 + k_menu_items[items_num].tag = tag;
3.540 + k_menu_items[items_num].usrptr = menu;
3.541 + if (menu != NULL)
3.542 + k_menu_items[items_num].is_visible =
3.543 + menu_is_visible(menu);
3.544 + else
3.545 + k_menu_items[items_num].is_visible = 1;
3.546 +
3.547 + va_start(ap, fmt);
3.548 + vsnprintf(k_menu_items[items_num].str,
3.549 + sizeof(k_menu_items[items_num].str),
3.550 + fmt, ap);
3.551 + va_end(ap);
3.552 +
3.553 + if (!k_menu_items[items_num].is_visible)
3.554 + memcpy(k_menu_items[items_num].str, "XXX", 3);
3.555 +
3.556 + curses_menu_items[items_num] = new_item(
3.557 + k_menu_items[items_num].str,
3.558 + k_menu_items[items_num].str);
3.559 + set_item_userptr(curses_menu_items[items_num],
3.560 + &k_menu_items[items_num]);
3.561 + /*
3.562 + if (!k_menu_items[items_num].is_visible)
3.563 + item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
3.564 + */
3.565 +
3.566 + items_num++;
3.567 + curses_menu_items[items_num] = NULL;
3.568 +}
3.569 +
3.570 +/* very hackish. adds a string to the last item added */
3.571 +static void item_add_str(const char *fmt, ...)
3.572 +{
3.573 + va_list ap;
3.574 + int index = items_num-1;
3.575 + char new_str[256];
3.576 + char tmp_str[256];
3.577 +
3.578 + if (index < 0)
3.579 + return;
3.580 +
3.581 + va_start(ap, fmt);
3.582 + vsnprintf(new_str, sizeof(new_str), fmt, ap);
3.583 + va_end(ap);
3.584 + snprintf(tmp_str, sizeof(tmp_str), "%s%s",
3.585 + k_menu_items[index].str, new_str);
3.586 + strncpy(k_menu_items[index].str,
3.587 + tmp_str,
3.588 + sizeof(k_menu_items[index].str));
3.589 +
3.590 + free_item(curses_menu_items[index]);
3.591 + curses_menu_items[index] = new_item(
3.592 + k_menu_items[index].str,
3.593 + k_menu_items[index].str);
3.594 + set_item_userptr(curses_menu_items[index],
3.595 + &k_menu_items[index]);
3.596 +}
3.597 +
3.598 +/* get the tag of the currently selected item */
3.599 +static char item_tag(void)
3.600 +{
3.601 + ITEM *cur;
3.602 + struct mitem *mcur;
3.603 +
3.604 + cur = current_item(curses_menu);
3.605 + if (cur == NULL)
3.606 + return 0;
3.607 + mcur = (struct mitem *) item_userptr(cur);
3.608 + return mcur->tag;
3.609 +}
3.610 +
3.611 +static int curses_item_index(void)
3.612 +{
3.613 + return item_index(current_item(curses_menu));
3.614 +}
3.615 +
3.616 +static void *item_data(void)
3.617 +{
3.618 + ITEM *cur;
3.619 + struct mitem *mcur;
3.620 +
3.621 + cur = current_item(curses_menu);
3.622 + if (!cur)
3.623 + return NULL;
3.624 + mcur = (struct mitem *) item_userptr(cur);
3.625 + return mcur->usrptr;
3.626 +
3.627 +}
3.628 +
3.629 +static int item_is_tag(char tag)
3.630 +{
3.631 + return item_tag() == tag;
3.632 +}
3.633 +
3.634 +static char filename[PATH_MAX+1];
3.635 +static char menu_backtitle[PATH_MAX+128];
3.636 +static const char *set_config_filename(const char *config_filename)
3.637 +{
3.638 + int size;
3.639 +
3.640 + size = snprintf(menu_backtitle, sizeof(menu_backtitle),
3.641 + "%s - %s", config_filename, rootmenu.prompt->text);
3.642 + if (size >= sizeof(menu_backtitle))
3.643 + menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
3.644 +
3.645 + size = snprintf(filename, sizeof(filename), "%s", config_filename);
3.646 + if (size >= sizeof(filename))
3.647 + filename[sizeof(filename)-1] = '\0';
3.648 + return menu_backtitle;
3.649 +}
3.650 +
3.651 +/* return = 0 means we are successful.
3.652 + * -1 means go on doing what you were doing
3.653 + */
3.654 +static int do_exit(void)
3.655 +{
3.656 + int res;
3.657 + if (!conf_get_changed()) {
3.658 + global_exit = 1;
3.659 + return 0;
3.660 + }
3.661 + res = btn_dialog(main_window,
3.662 + _("Do you wish to save your new configuration?\n"
3.663 + "<ESC> to cancel and resume nconfig."),
3.664 + 2,
3.665 + " <save> ",
3.666 + "<don't save>");
3.667 + if (res == KEY_EXIT) {
3.668 + global_exit = 0;
3.669 + return -1;
3.670 + }
3.671 +
3.672 + /* if we got here, the user really wants to exit */
3.673 + switch (res) {
3.674 + case 0:
3.675 + res = conf_write(filename);
3.676 + if (res)
3.677 + btn_dialog(
3.678 + main_window,
3.679 + _("Error during writing of configuration.\n"
3.680 + "Your configuration changes were NOT saved."),
3.681 + 1,
3.682 + "<OK>");
3.683 + break;
3.684 + default:
3.685 + btn_dialog(
3.686 + main_window,
3.687 + _("Your configuration changes were NOT saved."),
3.688 + 1,
3.689 + "<OK>");
3.690 + break;
3.691 + }
3.692 + global_exit = 1;
3.693 + return 0;
3.694 +}
3.695 +
3.696 +
3.697 +static void search_conf(void)
3.698 +{
3.699 + struct symbol **sym_arr;
3.700 + struct gstr res;
3.701 + char dialog_input_result[100];
3.702 + char *dialog_input;
3.703 + int dres;
3.704 +again:
3.705 + dres = dialog_inputbox(main_window,
3.706 + _("Search Configuration Parameter"),
3.707 + _("Enter " CONFIG_ " (sub)string to search for "
3.708 + "(with or without \"" CONFIG_ "\")"),
3.709 + "", dialog_input_result, 99);
3.710 + switch (dres) {
3.711 + case 0:
3.712 + break;
3.713 + case 1:
3.714 + show_scroll_win(main_window,
3.715 + _("Search Configuration"), search_help);
3.716 + goto again;
3.717 + default:
3.718 + return;
3.719 + }
3.720 +
3.721 + /* strip the prefix if necessary */
3.722 + dialog_input = dialog_input_result;
3.723 + if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
3.724 + dialog_input += strlen(CONFIG_);
3.725 +
3.726 + sym_arr = sym_re_search(dialog_input);
3.727 + res = get_relations_str(sym_arr);
3.728 + free(sym_arr);
3.729 + show_scroll_win(main_window,
3.730 + _("Search Results"), str_get(&res));
3.731 + str_free(&res);
3.732 +}
3.733 +
3.734 +
3.735 +static void build_conf(struct menu *menu)
3.736 +{
3.737 + struct symbol *sym;
3.738 + struct property *prop;
3.739 + struct menu *child;
3.740 + int type, tmp, doint = 2;
3.741 + tristate val;
3.742 + char ch;
3.743 +
3.744 + if (!menu || (!show_all_items && !menu_is_visible(menu)))
3.745 + return;
3.746 +
3.747 + sym = menu->sym;
3.748 + prop = menu->prompt;
3.749 + if (!sym) {
3.750 + if (prop && menu != current_menu) {
3.751 + const char *prompt = menu_get_prompt(menu);
3.752 + enum prop_type ptype;
3.753 + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
3.754 + switch (ptype) {
3.755 + case P_MENU:
3.756 + child_count++;
3.757 + prompt = _(prompt);
3.758 + if (single_menu_mode) {
3.759 + item_make(menu, 'm',
3.760 + "%s%*c%s",
3.761 + menu->data ? "-->" : "++>",
3.762 + indent + 1, ' ', prompt);
3.763 + } else
3.764 + item_make(menu, 'm',
3.765 + " %*c%s --->",
3.766 + indent + 1,
3.767 + ' ', prompt);
3.768 +
3.769 + if (single_menu_mode && menu->data)
3.770 + goto conf_childs;
3.771 + return;
3.772 + case P_COMMENT:
3.773 + if (prompt) {
3.774 + child_count++;
3.775 + item_make(menu, ':',
3.776 + " %*c*** %s ***",
3.777 + indent + 1, ' ',
3.778 + _(prompt));
3.779 + }
3.780 + break;
3.781 + default:
3.782 + if (prompt) {
3.783 + child_count++;
3.784 + item_make(menu, ':', "---%*c%s",
3.785 + indent + 1, ' ',
3.786 + _(prompt));
3.787 + }
3.788 + }
3.789 + } else
3.790 + doint = 0;
3.791 + goto conf_childs;
3.792 + }
3.793 +
3.794 + type = sym_get_type(sym);
3.795 + if (sym_is_choice(sym)) {
3.796 + struct symbol *def_sym = sym_get_choice_value(sym);
3.797 + struct menu *def_menu = NULL;
3.798 +
3.799 + child_count++;
3.800 + for (child = menu->list; child; child = child->next) {
3.801 + if (menu_is_visible(child) && child->sym == def_sym)
3.802 + def_menu = child;
3.803 + }
3.804 +
3.805 + val = sym_get_tristate_value(sym);
3.806 + if (sym_is_changable(sym)) {
3.807 + switch (type) {
3.808 + case S_BOOLEAN:
3.809 + item_make(menu, 't', "[%c]",
3.810 + val == no ? ' ' : '*');
3.811 + break;
3.812 + case S_TRISTATE:
3.813 + switch (val) {
3.814 + case yes:
3.815 + ch = '*';
3.816 + break;
3.817 + case mod:
3.818 + ch = 'M';
3.819 + break;
3.820 + default:
3.821 + ch = ' ';
3.822 + break;
3.823 + }
3.824 + item_make(menu, 't', "<%c>", ch);
3.825 + break;
3.826 + }
3.827 + } else {
3.828 + item_make(menu, def_menu ? 't' : ':', " ");
3.829 + }
3.830 +
3.831 + item_add_str("%*c%s", indent + 1,
3.832 + ' ', _(menu_get_prompt(menu)));
3.833 + if (val == yes) {
3.834 + if (def_menu) {
3.835 + item_add_str(" (%s)",
3.836 + _(menu_get_prompt(def_menu)));
3.837 + item_add_str(" --->");
3.838 + if (def_menu->list) {
3.839 + indent += 2;
3.840 + build_conf(def_menu);
3.841 + indent -= 2;
3.842 + }
3.843 + }
3.844 + return;
3.845 + }
3.846 + } else {
3.847 + if (menu == current_menu) {
3.848 + item_make(menu, ':',
3.849 + "---%*c%s", indent + 1,
3.850 + ' ', _(menu_get_prompt(menu)));
3.851 + goto conf_childs;
3.852 + }
3.853 + child_count++;
3.854 + val = sym_get_tristate_value(sym);
3.855 + if (sym_is_choice_value(sym) && val == yes) {
3.856 + item_make(menu, ':', " ");
3.857 + } else {
3.858 + switch (type) {
3.859 + case S_BOOLEAN:
3.860 + if (sym_is_changable(sym))
3.861 + item_make(menu, 't', "[%c]",
3.862 + val == no ? ' ' : '*');
3.863 + else
3.864 + item_make(menu, 't', "-%c-",
3.865 + val == no ? ' ' : '*');
3.866 + break;
3.867 + case S_TRISTATE:
3.868 + switch (val) {
3.869 + case yes:
3.870 + ch = '*';
3.871 + break;
3.872 + case mod:
3.873 + ch = 'M';
3.874 + break;
3.875 + default:
3.876 + ch = ' ';
3.877 + break;
3.878 + }
3.879 + if (sym_is_changable(sym)) {
3.880 + if (sym->rev_dep.tri == mod)
3.881 + item_make(menu,
3.882 + 't', "{%c}", ch);
3.883 + else
3.884 + item_make(menu,
3.885 + 't', "<%c>", ch);
3.886 + } else
3.887 + item_make(menu, 't', "-%c-", ch);
3.888 + break;
3.889 + default:
3.890 + tmp = 2 + strlen(sym_get_string_value(sym));
3.891 + item_make(menu, 's', " (%s)",
3.892 + sym_get_string_value(sym));
3.893 + tmp = indent - tmp + 4;
3.894 + if (tmp < 0)
3.895 + tmp = 0;
3.896 + item_add_str("%*c%s%s", tmp, ' ',
3.897 + _(menu_get_prompt(menu)),
3.898 + (sym_has_value(sym) ||
3.899 + !sym_is_changable(sym)) ? "" :
3.900 + _(" (NEW)"));
3.901 + goto conf_childs;
3.902 + }
3.903 + }
3.904 + item_add_str("%*c%s%s", indent + 1, ' ',
3.905 + _(menu_get_prompt(menu)),
3.906 + (sym_has_value(sym) || !sym_is_changable(sym)) ?
3.907 + "" : _(" (NEW)"));
3.908 + if (menu->prompt && menu->prompt->type == P_MENU) {
3.909 + item_add_str(" --->");
3.910 + return;
3.911 + }
3.912 + }
3.913 +
3.914 +conf_childs:
3.915 + indent += doint;
3.916 + for (child = menu->list; child; child = child->next)
3.917 + build_conf(child);
3.918 + indent -= doint;
3.919 +}
3.920 +
3.921 +static void reset_menu(void)
3.922 +{
3.923 + unpost_menu(curses_menu);
3.924 + clean_items();
3.925 +}
3.926 +
3.927 +/* adjust the menu to show this item.
3.928 + * prefer not to scroll the menu if possible*/
3.929 +static void center_item(int selected_index, int *last_top_row)
3.930 +{
3.931 + int toprow;
3.932 +
3.933 + set_top_row(curses_menu, *last_top_row);
3.934 + toprow = top_row(curses_menu);
3.935 + if (selected_index < toprow ||
3.936 + selected_index >= toprow+mwin_max_lines) {
3.937 + toprow = max(selected_index-mwin_max_lines/2, 0);
3.938 + if (toprow >= item_count(curses_menu)-mwin_max_lines)
3.939 + toprow = item_count(curses_menu)-mwin_max_lines;
3.940 + set_top_row(curses_menu, toprow);
3.941 + }
3.942 + set_current_item(curses_menu,
3.943 + curses_menu_items[selected_index]);
3.944 + *last_top_row = toprow;
3.945 + post_menu(curses_menu);
3.946 + refresh_all_windows(main_window);
3.947 +}
3.948 +
3.949 +/* this function assumes reset_menu has been called before */
3.950 +static void show_menu(const char *prompt, const char *instructions,
3.951 + int selected_index, int *last_top_row)
3.952 +{
3.953 + int maxx, maxy;
3.954 + WINDOW *menu_window;
3.955 +
3.956 + current_instructions = instructions;
3.957 +
3.958 + clear();
3.959 + (void) wattrset(main_window, attributes[NORMAL]);
3.960 + print_in_middle(stdscr, 1, 0, COLS,
3.961 + menu_backtitle,
3.962 + attributes[MAIN_HEADING]);
3.963 +
3.964 + (void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
3.965 + box(main_window, 0, 0);
3.966 + (void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
3.967 + mvwprintw(main_window, 0, 3, " %s ", prompt);
3.968 + (void) wattrset(main_window, attributes[NORMAL]);
3.969 +
3.970 + set_menu_items(curses_menu, curses_menu_items);
3.971 +
3.972 + /* position the menu at the middle of the screen */
3.973 + scale_menu(curses_menu, &maxy, &maxx);
3.974 + maxx = min(maxx, mwin_max_cols-2);
3.975 + maxy = mwin_max_lines;
3.976 + menu_window = derwin(main_window,
3.977 + maxy,
3.978 + maxx,
3.979 + 2,
3.980 + (mwin_max_cols-maxx)/2);
3.981 + keypad(menu_window, TRUE);
3.982 + set_menu_win(curses_menu, menu_window);
3.983 + set_menu_sub(curses_menu, menu_window);
3.984 +
3.985 + /* must reassert this after changing items, otherwise returns to a
3.986 + * default of 16
3.987 + */
3.988 + set_menu_format(curses_menu, maxy, 1);
3.989 + center_item(selected_index, last_top_row);
3.990 + set_menu_format(curses_menu, maxy, 1);
3.991 +
3.992 + print_function_line();
3.993 +
3.994 + /* Post the menu */
3.995 + post_menu(curses_menu);
3.996 + refresh_all_windows(main_window);
3.997 +}
3.998 +
3.999 +static void adj_match_dir(match_f *match_direction)
3.1000 +{
3.1001 + if (*match_direction == FIND_NEXT_MATCH_DOWN)
3.1002 + *match_direction =
3.1003 + MATCH_TINKER_PATTERN_DOWN;
3.1004 + else if (*match_direction == FIND_NEXT_MATCH_UP)
3.1005 + *match_direction =
3.1006 + MATCH_TINKER_PATTERN_UP;
3.1007 + /* else, do no change.. */
3.1008 +}
3.1009 +
3.1010 +struct match_state
3.1011 +{
3.1012 + int in_search;
3.1013 + match_f match_direction;
3.1014 + char pattern[256];
3.1015 +};
3.1016 +
3.1017 +/* Return 0 means I have handled the key. In such a case, ans should hold the
3.1018 + * item to center, or -1 otherwise.
3.1019 + * Else return -1 .
3.1020 + */
3.1021 +static int do_match(int key, struct match_state *state, int *ans)
3.1022 +{
3.1023 + char c = (char) key;
3.1024 + int terminate_search = 0;
3.1025 + *ans = -1;
3.1026 + if (key == '/' || (state->in_search && key == 27)) {
3.1027 + move(0, 0);
3.1028 + refresh();
3.1029 + clrtoeol();
3.1030 + state->in_search = 1-state->in_search;
3.1031 + bzero(state->pattern, sizeof(state->pattern));
3.1032 + state->match_direction = MATCH_TINKER_PATTERN_DOWN;
3.1033 + return 0;
3.1034 + } else if (!state->in_search)
3.1035 + return 1;
3.1036 +
3.1037 + if (isalnum(c) || isgraph(c) || c == ' ') {
3.1038 + state->pattern[strlen(state->pattern)] = c;
3.1039 + state->pattern[strlen(state->pattern)] = '\0';
3.1040 + adj_match_dir(&state->match_direction);
3.1041 + *ans = get_mext_match(state->pattern,
3.1042 + state->match_direction);
3.1043 + } else if (key == KEY_DOWN) {
3.1044 + state->match_direction = FIND_NEXT_MATCH_DOWN;
3.1045 + *ans = get_mext_match(state->pattern,
3.1046 + state->match_direction);
3.1047 + } else if (key == KEY_UP) {
3.1048 + state->match_direction = FIND_NEXT_MATCH_UP;
3.1049 + *ans = get_mext_match(state->pattern,
3.1050 + state->match_direction);
3.1051 + } else if (key == KEY_BACKSPACE || key == 127) {
3.1052 + state->pattern[strlen(state->pattern)-1] = '\0';
3.1053 + adj_match_dir(&state->match_direction);
3.1054 + } else
3.1055 + terminate_search = 1;
3.1056 +
3.1057 + if (terminate_search) {
3.1058 + state->in_search = 0;
3.1059 + bzero(state->pattern, sizeof(state->pattern));
3.1060 + move(0, 0);
3.1061 + refresh();
3.1062 + clrtoeol();
3.1063 + return -1;
3.1064 + }
3.1065 + return 0;
3.1066 +}
3.1067 +
3.1068 +static void conf(struct menu *menu)
3.1069 +{
3.1070 + struct menu *submenu = 0;
3.1071 + const char *prompt = menu_get_prompt(menu);
3.1072 + struct symbol *sym;
3.1073 + struct menu *active_menu = NULL;
3.1074 + int res;
3.1075 + int current_index = 0;
3.1076 + int last_top_row = 0;
3.1077 + struct match_state match_state = {
3.1078 + .in_search = 0,
3.1079 + .match_direction = MATCH_TINKER_PATTERN_DOWN,
3.1080 + .pattern = "",
3.1081 + };
3.1082 +
3.1083 + while (!global_exit) {
3.1084 + reset_menu();
3.1085 + current_menu = menu;
3.1086 + build_conf(menu);
3.1087 + if (!child_count)
3.1088 + break;
3.1089 +
3.1090 + show_menu(prompt ? _(prompt) : _("Main Menu"),
3.1091 + _(menu_instructions),
3.1092 + current_index, &last_top_row);
3.1093 + keypad((menu_win(curses_menu)), TRUE);
3.1094 + while (!global_exit) {
3.1095 + if (match_state.in_search) {
3.1096 + mvprintw(0, 0,
3.1097 + "searching: %s", match_state.pattern);
3.1098 + clrtoeol();
3.1099 + }
3.1100 + refresh_all_windows(main_window);
3.1101 + res = wgetch(menu_win(curses_menu));
3.1102 + if (!res)
3.1103 + break;
3.1104 + if (do_match(res, &match_state, ¤t_index) == 0) {
3.1105 + if (current_index != -1)
3.1106 + center_item(current_index,
3.1107 + &last_top_row);
3.1108 + continue;
3.1109 + }
3.1110 + if (process_special_keys(&res,
3.1111 + (struct menu *) item_data()))
3.1112 + break;
3.1113 + switch (res) {
3.1114 + case KEY_DOWN:
3.1115 + menu_driver(curses_menu, REQ_DOWN_ITEM);
3.1116 + break;
3.1117 + case KEY_UP:
3.1118 + menu_driver(curses_menu, REQ_UP_ITEM);
3.1119 + break;
3.1120 + case KEY_NPAGE:
3.1121 + menu_driver(curses_menu, REQ_SCR_DPAGE);
3.1122 + break;
3.1123 + case KEY_PPAGE:
3.1124 + menu_driver(curses_menu, REQ_SCR_UPAGE);
3.1125 + break;
3.1126 + case KEY_HOME:
3.1127 + menu_driver(curses_menu, REQ_FIRST_ITEM);
3.1128 + break;
3.1129 + case KEY_END:
3.1130 + menu_driver(curses_menu, REQ_LAST_ITEM);
3.1131 + break;
3.1132 + case 'h':
3.1133 + case '?':
3.1134 + show_help((struct menu *) item_data());
3.1135 + break;
3.1136 + }
3.1137 + if (res == 10 || res == 27 ||
3.1138 + res == 32 || res == 'n' || res == 'y' ||
3.1139 + res == KEY_LEFT || res == KEY_RIGHT ||
3.1140 + res == 'm')
3.1141 + break;
3.1142 + refresh_all_windows(main_window);
3.1143 + }
3.1144 +
3.1145 + refresh_all_windows(main_window);
3.1146 + /* if ESC or left*/
3.1147 + if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
3.1148 + break;
3.1149 +
3.1150 + /* remember location in the menu */
3.1151 + last_top_row = top_row(curses_menu);
3.1152 + current_index = curses_item_index();
3.1153 +
3.1154 + if (!item_tag())
3.1155 + continue;
3.1156 +
3.1157 + submenu = (struct menu *) item_data();
3.1158 + active_menu = (struct menu *)item_data();
3.1159 + if (!submenu || !menu_is_visible(submenu))
3.1160 + continue;
3.1161 + if (submenu)
3.1162 + sym = submenu->sym;
3.1163 + else
3.1164 + sym = NULL;
3.1165 +
3.1166 + switch (res) {
3.1167 + case ' ':
3.1168 + if (item_is_tag('t'))
3.1169 + sym_toggle_tristate_value(sym);
3.1170 + else if (item_is_tag('m'))
3.1171 + conf(submenu);
3.1172 + break;
3.1173 + case KEY_RIGHT:
3.1174 + case 10: /* ENTER WAS PRESSED */
3.1175 + switch (item_tag()) {
3.1176 + case 'm':
3.1177 + if (single_menu_mode)
3.1178 + submenu->data =
3.1179 + (void *) (long) !submenu->data;
3.1180 + else
3.1181 + conf(submenu);
3.1182 + break;
3.1183 + case 't':
3.1184 + if (sym_is_choice(sym) &&
3.1185 + sym_get_tristate_value(sym) == yes)
3.1186 + conf_choice(submenu);
3.1187 + else if (submenu->prompt &&
3.1188 + submenu->prompt->type == P_MENU)
3.1189 + conf(submenu);
3.1190 + else if (res == 10)
3.1191 + sym_toggle_tristate_value(sym);
3.1192 + break;
3.1193 + case 's':
3.1194 + conf_string(submenu);
3.1195 + break;
3.1196 + }
3.1197 + break;
3.1198 + case 'y':
3.1199 + if (item_is_tag('t')) {
3.1200 + if (sym_set_tristate_value(sym, yes))
3.1201 + break;
3.1202 + if (sym_set_tristate_value(sym, mod))
3.1203 + btn_dialog(main_window, setmod_text, 0);
3.1204 + }
3.1205 + break;
3.1206 + case 'n':
3.1207 + if (item_is_tag('t'))
3.1208 + sym_set_tristate_value(sym, no);
3.1209 + break;
3.1210 + case 'm':
3.1211 + if (item_is_tag('t'))
3.1212 + sym_set_tristate_value(sym, mod);
3.1213 + break;
3.1214 + }
3.1215 + }
3.1216 +}
3.1217 +
3.1218 +static void conf_message_callback(const char *fmt, va_list ap)
3.1219 +{
3.1220 + char buf[1024];
3.1221 +
3.1222 + vsnprintf(buf, sizeof(buf), fmt, ap);
3.1223 + btn_dialog(main_window, buf, 1, "<OK>");
3.1224 +}
3.1225 +
3.1226 +static void show_help(struct menu *menu)
3.1227 +{
3.1228 + struct gstr help = str_new();
3.1229 +
3.1230 + if (menu && menu->sym && menu_has_help(menu)) {
3.1231 + if (menu->sym->name) {
3.1232 + str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name);
3.1233 + str_append(&help, _(menu_get_help(menu)));
3.1234 + str_append(&help, "\n");
3.1235 + get_symbol_str(&help, menu->sym);
3.1236 + } else {
3.1237 + str_append(&help, _(menu_get_help(menu)));
3.1238 + }
3.1239 + } else {
3.1240 + str_append(&help, nohelp_text);
3.1241 + }
3.1242 + show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
3.1243 + str_free(&help);
3.1244 +}
3.1245 +
3.1246 +static void conf_choice(struct menu *menu)
3.1247 +{
3.1248 + const char *prompt = _(menu_get_prompt(menu));
3.1249 + struct menu *child = 0;
3.1250 + struct symbol *active;
3.1251 + int selected_index = 0;
3.1252 + int last_top_row = 0;
3.1253 + int res, i = 0;
3.1254 + struct match_state match_state = {
3.1255 + .in_search = 0,
3.1256 + .match_direction = MATCH_TINKER_PATTERN_DOWN,
3.1257 + .pattern = "",
3.1258 + };
3.1259 +
3.1260 + active = sym_get_choice_value(menu->sym);
3.1261 + /* this is mostly duplicated from the conf() function. */
3.1262 + while (!global_exit) {
3.1263 + reset_menu();
3.1264 +
3.1265 + for (i = 0, child = menu->list; child; child = child->next) {
3.1266 + if (!show_all_items && !menu_is_visible(child))
3.1267 + continue;
3.1268 +
3.1269 + if (child->sym == sym_get_choice_value(menu->sym))
3.1270 + item_make(child, ':', "<X> %s",
3.1271 + _(menu_get_prompt(child)));
3.1272 + else if (child->sym)
3.1273 + item_make(child, ':', " %s",
3.1274 + _(menu_get_prompt(child)));
3.1275 + else
3.1276 + item_make(child, ':', "*** %s ***",
3.1277 + _(menu_get_prompt(child)));
3.1278 +
3.1279 + if (child->sym == active){
3.1280 + last_top_row = top_row(curses_menu);
3.1281 + selected_index = i;
3.1282 + }
3.1283 + i++;
3.1284 + }
3.1285 + show_menu(prompt ? _(prompt) : _("Choice Menu"),
3.1286 + _(radiolist_instructions),
3.1287 + selected_index,
3.1288 + &last_top_row);
3.1289 + while (!global_exit) {
3.1290 + if (match_state.in_search) {
3.1291 + mvprintw(0, 0, "searching: %s",
3.1292 + match_state.pattern);
3.1293 + clrtoeol();
3.1294 + }
3.1295 + refresh_all_windows(main_window);
3.1296 + res = wgetch(menu_win(curses_menu));
3.1297 + if (!res)
3.1298 + break;
3.1299 + if (do_match(res, &match_state, &selected_index) == 0) {
3.1300 + if (selected_index != -1)
3.1301 + center_item(selected_index,
3.1302 + &last_top_row);
3.1303 + continue;
3.1304 + }
3.1305 + if (process_special_keys(
3.1306 + &res,
3.1307 + (struct menu *) item_data()))
3.1308 + break;
3.1309 + switch (res) {
3.1310 + case KEY_DOWN:
3.1311 + menu_driver(curses_menu, REQ_DOWN_ITEM);
3.1312 + break;
3.1313 + case KEY_UP:
3.1314 + menu_driver(curses_menu, REQ_UP_ITEM);
3.1315 + break;
3.1316 + case KEY_NPAGE:
3.1317 + menu_driver(curses_menu, REQ_SCR_DPAGE);
3.1318 + break;
3.1319 + case KEY_PPAGE:
3.1320 + menu_driver(curses_menu, REQ_SCR_UPAGE);
3.1321 + break;
3.1322 + case KEY_HOME:
3.1323 + menu_driver(curses_menu, REQ_FIRST_ITEM);
3.1324 + break;
3.1325 + case KEY_END:
3.1326 + menu_driver(curses_menu, REQ_LAST_ITEM);
3.1327 + break;
3.1328 + case 'h':
3.1329 + case '?':
3.1330 + show_help((struct menu *) item_data());
3.1331 + break;
3.1332 + }
3.1333 + if (res == 10 || res == 27 || res == ' ' ||
3.1334 + res == KEY_LEFT){
3.1335 + break;
3.1336 + }
3.1337 + refresh_all_windows(main_window);
3.1338 + }
3.1339 + /* if ESC or left */
3.1340 + if (res == 27 || res == KEY_LEFT)
3.1341 + break;
3.1342 +
3.1343 + child = item_data();
3.1344 + if (!child || !menu_is_visible(child) || !child->sym)
3.1345 + continue;
3.1346 + switch (res) {
3.1347 + case ' ':
3.1348 + case 10:
3.1349 + case KEY_RIGHT:
3.1350 + sym_set_tristate_value(child->sym, yes);
3.1351 + return;
3.1352 + case 'h':
3.1353 + case '?':
3.1354 + show_help(child);
3.1355 + active = child->sym;
3.1356 + break;
3.1357 + case KEY_EXIT:
3.1358 + return;
3.1359 + }
3.1360 + }
3.1361 +}
3.1362 +
3.1363 +static void conf_string(struct menu *menu)
3.1364 +{
3.1365 + const char *prompt = menu_get_prompt(menu);
3.1366 + char dialog_input_result[256];
3.1367 +
3.1368 + while (1) {
3.1369 + int res;
3.1370 + const char *heading;
3.1371 +
3.1372 + switch (sym_get_type(menu->sym)) {
3.1373 + case S_INT:
3.1374 + heading = _(inputbox_instructions_int);
3.1375 + break;
3.1376 + case S_HEX:
3.1377 + heading = _(inputbox_instructions_hex);
3.1378 + break;
3.1379 + case S_STRING:
3.1380 + heading = _(inputbox_instructions_string);
3.1381 + break;
3.1382 + default:
3.1383 + heading = _("Internal nconf error!");
3.1384 + }
3.1385 + res = dialog_inputbox(main_window,
3.1386 + prompt ? _(prompt) : _("Main Menu"),
3.1387 + heading,
3.1388 + sym_get_string_value(menu->sym),
3.1389 + dialog_input_result,
3.1390 + sizeof(dialog_input_result));
3.1391 + switch (res) {
3.1392 + case 0:
3.1393 + if (sym_set_string_value(menu->sym,
3.1394 + dialog_input_result))
3.1395 + return;
3.1396 + btn_dialog(main_window,
3.1397 + _("You have made an invalid entry."), 0);
3.1398 + break;
3.1399 + case 1:
3.1400 + show_help(menu);
3.1401 + break;
3.1402 + case KEY_EXIT:
3.1403 + return;
3.1404 + }
3.1405 + }
3.1406 +}
3.1407 +
3.1408 +static void conf_load(void)
3.1409 +{
3.1410 + char dialog_input_result[256];
3.1411 + while (1) {
3.1412 + int res;
3.1413 + res = dialog_inputbox(main_window,
3.1414 + NULL, load_config_text,
3.1415 + filename,
3.1416 + dialog_input_result,
3.1417 + sizeof(dialog_input_result));
3.1418 + switch (res) {
3.1419 + case 0:
3.1420 + if (!dialog_input_result[0])
3.1421 + return;
3.1422 + if (!conf_read(dialog_input_result)) {
3.1423 + set_config_filename(dialog_input_result);
3.1424 + sym_set_change_count(1);
3.1425 + return;
3.1426 + }
3.1427 + btn_dialog(main_window, _("File does not exist!"), 0);
3.1428 + break;
3.1429 + case 1:
3.1430 + show_scroll_win(main_window,
3.1431 + _("Load Alternate Configuration"),
3.1432 + load_config_help);
3.1433 + break;
3.1434 + case KEY_EXIT:
3.1435 + return;
3.1436 + }
3.1437 + }
3.1438 +}
3.1439 +
3.1440 +static void conf_save(void)
3.1441 +{
3.1442 + char dialog_input_result[256];
3.1443 + while (1) {
3.1444 + int res;
3.1445 + res = dialog_inputbox(main_window,
3.1446 + NULL, save_config_text,
3.1447 + filename,
3.1448 + dialog_input_result,
3.1449 + sizeof(dialog_input_result));
3.1450 + switch (res) {
3.1451 + case 0:
3.1452 + if (!dialog_input_result[0])
3.1453 + return;
3.1454 + res = conf_write(dialog_input_result);
3.1455 + if (!res) {
3.1456 + set_config_filename(dialog_input_result);
3.1457 + return;
3.1458 + }
3.1459 + btn_dialog(main_window, _("Can't create file! "
3.1460 + "Probably a nonexistent directory."),
3.1461 + 1, "<OK>");
3.1462 + break;
3.1463 + case 1:
3.1464 + show_scroll_win(main_window,
3.1465 + _("Save Alternate Configuration"),
3.1466 + save_config_help);
3.1467 + break;
3.1468 + case KEY_EXIT:
3.1469 + return;
3.1470 + }
3.1471 + }
3.1472 +}
3.1473 +
3.1474 +void setup_windows(void)
3.1475 +{
3.1476 + if (main_window != NULL)
3.1477 + delwin(main_window);
3.1478 +
3.1479 + /* set up the menu and menu window */
3.1480 + main_window = newwin(LINES-2, COLS-2, 2, 1);
3.1481 + keypad(main_window, TRUE);
3.1482 + mwin_max_lines = LINES-7;
3.1483 + mwin_max_cols = COLS-6;
3.1484 +
3.1485 + /* panels order is from bottom to top */
3.1486 + new_panel(main_window);
3.1487 +}
3.1488 +
3.1489 +int main(int ac, char **av)
3.1490 +{
3.1491 + char *mode;
3.1492 +
3.1493 + setlocale(LC_ALL, "");
3.1494 + bindtextdomain(PACKAGE, LOCALEDIR);
3.1495 + textdomain(PACKAGE);
3.1496 +
3.1497 + conf_parse(av[1]);
3.1498 + conf_read(NULL);
3.1499 +
3.1500 + mode = getenv("NCONFIG_MODE");
3.1501 + if (mode) {
3.1502 + if (!strcasecmp(mode, "single_menu"))
3.1503 + single_menu_mode = 1;
3.1504 + }
3.1505 +
3.1506 + /* Initialize curses */
3.1507 + initscr();
3.1508 + /* set color theme */
3.1509 + set_colors();
3.1510 +
3.1511 + cbreak();
3.1512 + noecho();
3.1513 + keypad(stdscr, TRUE);
3.1514 + curs_set(0);
3.1515 +
3.1516 + if (COLS < 75 || LINES < 20) {
3.1517 + endwin();
3.1518 + printf("Your terminal should have at "
3.1519 + "least 20 lines and 75 columns\n");
3.1520 + return 1;
3.1521 + }
3.1522 +
3.1523 + notimeout(stdscr, FALSE);
3.1524 + ESCDELAY = 1;
3.1525 +
3.1526 + /* set btns menu */
3.1527 + curses_menu = new_menu(curses_menu_items);
3.1528 + menu_opts_off(curses_menu, O_SHOWDESC);
3.1529 + menu_opts_on(curses_menu, O_SHOWMATCH);
3.1530 + menu_opts_on(curses_menu, O_ONEVALUE);
3.1531 + menu_opts_on(curses_menu, O_NONCYCLIC);
3.1532 + menu_opts_on(curses_menu, O_IGNORECASE);
3.1533 + set_menu_mark(curses_menu, " ");
3.1534 + set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
3.1535 + set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
3.1536 + set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
3.1537 +
3.1538 + set_config_filename(conf_get_configname());
3.1539 + setup_windows();
3.1540 +
3.1541 + /* check for KEY_FUNC(1) */
3.1542 + if (has_key(KEY_F(1)) == FALSE) {
3.1543 + show_scroll_win(main_window,
3.1544 + _("Instructions"),
3.1545 + _(menu_no_f_instructions));
3.1546 + }
3.1547 +
3.1548 + conf_set_message_callback(conf_message_callback);
3.1549 + /* do the work */
3.1550 + while (!global_exit) {
3.1551 + conf(&rootmenu);
3.1552 + if (!global_exit && do_exit() == 0)
3.1553 + break;
3.1554 + }
3.1555 + /* ok, we are done */
3.1556 + unpost_menu(curses_menu);
3.1557 + free_menu(curses_menu);
3.1558 + delwin(main_window);
3.1559 + clear();
3.1560 + refresh();
3.1561 + endwin();
3.1562 + return 0;
3.1563 +}
3.1564 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/kconfig/nconf.gui.c Thu May 12 19:45:30 2011 +0200
4.3 @@ -0,0 +1,617 @@
4.4 +/*
4.5 + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
4.6 + * Released under the terms of the GNU GPL v2.0.
4.7 + *
4.8 + * Derived from menuconfig.
4.9 + *
4.10 + */
4.11 +#include "nconf.h"
4.12 +
4.13 +/* a list of all the different widgets we use */
4.14 +attributes_t attributes[ATTR_MAX+1] = {0};
4.15 +
4.16 +/* available colors:
4.17 + COLOR_BLACK 0
4.18 + COLOR_RED 1
4.19 + COLOR_GREEN 2
4.20 + COLOR_YELLOW 3
4.21 + COLOR_BLUE 4
4.22 + COLOR_MAGENTA 5
4.23 + COLOR_CYAN 6
4.24 + COLOR_WHITE 7
4.25 + */
4.26 +static void set_normal_colors(void)
4.27 +{
4.28 + init_pair(NORMAL, -1, -1);
4.29 + init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
4.30 +
4.31 + /* FORE is for the selected item */
4.32 + init_pair(MAIN_MENU_FORE, -1, -1);
4.33 + /* BACK for all the rest */
4.34 + init_pair(MAIN_MENU_BACK, -1, -1);
4.35 + init_pair(MAIN_MENU_GREY, -1, -1);
4.36 + init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
4.37 + init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
4.38 +
4.39 + init_pair(SCROLLWIN_TEXT, -1, -1);
4.40 + init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
4.41 + init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
4.42 +
4.43 + init_pair(DIALOG_TEXT, -1, -1);
4.44 + init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
4.45 + init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
4.46 + init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
4.47 +
4.48 + init_pair(INPUT_BOX, COLOR_YELLOW, -1);
4.49 + init_pair(INPUT_HEADING, COLOR_GREEN, -1);
4.50 + init_pair(INPUT_TEXT, -1, -1);
4.51 + init_pair(INPUT_FIELD, -1, -1);
4.52 +
4.53 + init_pair(FUNCTION_HIGHLIGHT, -1, -1);
4.54 + init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
4.55 +}
4.56 +
4.57 +/* available attributes:
4.58 + A_NORMAL Normal display (no highlight)
4.59 + A_STANDOUT Best highlighting mode of the terminal.
4.60 + A_UNDERLINE Underlining
4.61 + A_REVERSE Reverse video
4.62 + A_BLINK Blinking
4.63 + A_DIM Half bright
4.64 + A_BOLD Extra bright or bold
4.65 + A_PROTECT Protected mode
4.66 + A_INVIS Invisible or blank mode
4.67 + A_ALTCHARSET Alternate character set
4.68 + A_CHARTEXT Bit-mask to extract a character
4.69 + COLOR_PAIR(n) Color-pair number n
4.70 + */
4.71 +static void normal_color_theme(void)
4.72 +{
4.73 + /* automatically add color... */
4.74 +#define mkattr(name, attr) do { \
4.75 +attributes[name] = attr | COLOR_PAIR(name); } while (0)
4.76 + mkattr(NORMAL, NORMAL);
4.77 + mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
4.78 +
4.79 + mkattr(MAIN_MENU_FORE, A_REVERSE);
4.80 + mkattr(MAIN_MENU_BACK, A_NORMAL);
4.81 + mkattr(MAIN_MENU_GREY, A_NORMAL);
4.82 + mkattr(MAIN_MENU_HEADING, A_BOLD);
4.83 + mkattr(MAIN_MENU_BOX, A_NORMAL);
4.84 +
4.85 + mkattr(SCROLLWIN_TEXT, A_NORMAL);
4.86 + mkattr(SCROLLWIN_HEADING, A_BOLD);
4.87 + mkattr(SCROLLWIN_BOX, A_BOLD);
4.88 +
4.89 + mkattr(DIALOG_TEXT, A_BOLD);
4.90 + mkattr(DIALOG_BOX, A_BOLD);
4.91 + mkattr(DIALOG_MENU_FORE, A_STANDOUT);
4.92 + mkattr(DIALOG_MENU_BACK, A_NORMAL);
4.93 +
4.94 + mkattr(INPUT_BOX, A_NORMAL);
4.95 + mkattr(INPUT_HEADING, A_BOLD);
4.96 + mkattr(INPUT_TEXT, A_NORMAL);
4.97 + mkattr(INPUT_FIELD, A_UNDERLINE);
4.98 +
4.99 + mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
4.100 + mkattr(FUNCTION_TEXT, A_REVERSE);
4.101 +}
4.102 +
4.103 +static void no_colors_theme(void)
4.104 +{
4.105 + /* automatically add highlight, no color */
4.106 +#define mkattrn(name, attr) { attributes[name] = attr; }
4.107 +
4.108 + mkattrn(NORMAL, NORMAL);
4.109 + mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
4.110 +
4.111 + mkattrn(MAIN_MENU_FORE, A_STANDOUT);
4.112 + mkattrn(MAIN_MENU_BACK, A_NORMAL);
4.113 + mkattrn(MAIN_MENU_GREY, A_NORMAL);
4.114 + mkattrn(MAIN_MENU_HEADING, A_BOLD);
4.115 + mkattrn(MAIN_MENU_BOX, A_NORMAL);
4.116 +
4.117 + mkattrn(SCROLLWIN_TEXT, A_NORMAL);
4.118 + mkattrn(SCROLLWIN_HEADING, A_BOLD);
4.119 + mkattrn(SCROLLWIN_BOX, A_BOLD);
4.120 +
4.121 + mkattrn(DIALOG_TEXT, A_NORMAL);
4.122 + mkattrn(DIALOG_BOX, A_BOLD);
4.123 + mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
4.124 + mkattrn(DIALOG_MENU_BACK, A_NORMAL);
4.125 +
4.126 + mkattrn(INPUT_BOX, A_BOLD);
4.127 + mkattrn(INPUT_HEADING, A_BOLD);
4.128 + mkattrn(INPUT_TEXT, A_NORMAL);
4.129 + mkattrn(INPUT_FIELD, A_UNDERLINE);
4.130 +
4.131 + mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
4.132 + mkattrn(FUNCTION_TEXT, A_REVERSE);
4.133 +}
4.134 +
4.135 +void set_colors()
4.136 +{
4.137 + start_color();
4.138 + use_default_colors();
4.139 + set_normal_colors();
4.140 + if (has_colors()) {
4.141 + normal_color_theme();
4.142 + } else {
4.143 + /* give defaults */
4.144 + no_colors_theme();
4.145 + }
4.146 +}
4.147 +
4.148 +
4.149 +/* this changes the windows attributes !!! */
4.150 +void print_in_middle(WINDOW *win,
4.151 + int starty,
4.152 + int startx,
4.153 + int width,
4.154 + const char *string,
4.155 + chtype color)
4.156 +{ int length, x, y;
4.157 + float temp;
4.158 +
4.159 +
4.160 + if (win == NULL)
4.161 + win = stdscr;
4.162 + getyx(win, y, x);
4.163 + if (startx != 0)
4.164 + x = startx;
4.165 + if (starty != 0)
4.166 + y = starty;
4.167 + if (width == 0)
4.168 + width = 80;
4.169 +
4.170 + length = strlen(string);
4.171 + temp = (width - length) / 2;
4.172 + x = startx + (int)temp;
4.173 + (void) wattrset(win, color);
4.174 + mvwprintw(win, y, x, "%s", string);
4.175 + refresh();
4.176 +}
4.177 +
4.178 +int get_line_no(const char *text)
4.179 +{
4.180 + int i;
4.181 + int total = 1;
4.182 +
4.183 + if (!text)
4.184 + return 0;
4.185 +
4.186 + for (i = 0; text[i] != '\0'; i++)
4.187 + if (text[i] == '\n')
4.188 + total++;
4.189 + return total;
4.190 +}
4.191 +
4.192 +const char *get_line(const char *text, int line_no)
4.193 +{
4.194 + int i;
4.195 + int lines = 0;
4.196 +
4.197 + if (!text)
4.198 + return 0;
4.199 +
4.200 + for (i = 0; text[i] != '\0' && lines < line_no; i++)
4.201 + if (text[i] == '\n')
4.202 + lines++;
4.203 + return text+i;
4.204 +}
4.205 +
4.206 +int get_line_length(const char *line)
4.207 +{
4.208 + int res = 0;
4.209 + while (*line != '\0' && *line != '\n') {
4.210 + line++;
4.211 + res++;
4.212 + }
4.213 + return res;
4.214 +}
4.215 +
4.216 +/* print all lines to the window. */
4.217 +void fill_window(WINDOW *win, const char *text)
4.218 +{
4.219 + int x, y;
4.220 + int total_lines = get_line_no(text);
4.221 + int i;
4.222 +
4.223 + getmaxyx(win, y, x);
4.224 + /* do not go over end of line */
4.225 + total_lines = min(total_lines, y);
4.226 + for (i = 0; i < total_lines; i++) {
4.227 + char tmp[x+10];
4.228 + const char *line = get_line(text, i);
4.229 + int len = get_line_length(line);
4.230 + strncpy(tmp, line, min(len, x));
4.231 + tmp[len] = '\0';
4.232 + mvwprintw(win, i, 0, "%s", tmp);
4.233 + }
4.234 +}
4.235 +
4.236 +/* get the message, and buttons.
4.237 + * each button must be a char*
4.238 + * return the selected button
4.239 + *
4.240 + * this dialog is used for 2 different things:
4.241 + * 1) show a text box, no buttons.
4.242 + * 2) show a dialog, with horizontal buttons
4.243 + */
4.244 +int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
4.245 +{
4.246 + va_list ap;
4.247 + char *btn;
4.248 + int btns_width = 0;
4.249 + int msg_lines = 0;
4.250 + int msg_width = 0;
4.251 + int total_width;
4.252 + int win_rows = 0;
4.253 + WINDOW *win;
4.254 + WINDOW *msg_win;
4.255 + WINDOW *menu_win;
4.256 + MENU *menu;
4.257 + ITEM *btns[btn_num+1];
4.258 + int i, x, y;
4.259 + int res = -1;
4.260 +
4.261 +
4.262 + va_start(ap, btn_num);
4.263 + for (i = 0; i < btn_num; i++) {
4.264 + btn = va_arg(ap, char *);
4.265 + btns[i] = new_item(btn, "");
4.266 + btns_width += strlen(btn)+1;
4.267 + }
4.268 + va_end(ap);
4.269 + btns[btn_num] = NULL;
4.270 +
4.271 + /* find the widest line of msg: */
4.272 + msg_lines = get_line_no(msg);
4.273 + for (i = 0; i < msg_lines; i++) {
4.274 + const char *line = get_line(msg, i);
4.275 + int len = get_line_length(line);
4.276 + if (msg_width < len)
4.277 + msg_width = len;
4.278 + }
4.279 +
4.280 + total_width = max(msg_width, btns_width);
4.281 + /* place dialog in middle of screen */
4.282 + y = (LINES-(msg_lines+4))/2;
4.283 + x = (COLS-(total_width+4))/2;
4.284 +
4.285 +
4.286 + /* create the windows */
4.287 + if (btn_num > 0)
4.288 + win_rows = msg_lines+4;
4.289 + else
4.290 + win_rows = msg_lines+2;
4.291 +
4.292 + win = newwin(win_rows, total_width+4, y, x);
4.293 + keypad(win, TRUE);
4.294 + menu_win = derwin(win, 1, btns_width, win_rows-2,
4.295 + 1+(total_width+2-btns_width)/2);
4.296 + menu = new_menu(btns);
4.297 + msg_win = derwin(win, win_rows-2, msg_width, 1,
4.298 + 1+(total_width+2-msg_width)/2);
4.299 +
4.300 + set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
4.301 + set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
4.302 +
4.303 + (void) wattrset(win, attributes[DIALOG_BOX]);
4.304 + box(win, 0, 0);
4.305 +
4.306 + /* print message */
4.307 + (void) wattrset(msg_win, attributes[DIALOG_TEXT]);
4.308 + fill_window(msg_win, msg);
4.309 +
4.310 + set_menu_win(menu, win);
4.311 + set_menu_sub(menu, menu_win);
4.312 + set_menu_format(menu, 1, btn_num);
4.313 + menu_opts_off(menu, O_SHOWDESC);
4.314 + menu_opts_off(menu, O_SHOWMATCH);
4.315 + menu_opts_on(menu, O_ONEVALUE);
4.316 + menu_opts_on(menu, O_NONCYCLIC);
4.317 + set_menu_mark(menu, "");
4.318 + post_menu(menu);
4.319 +
4.320 +
4.321 + touchwin(win);
4.322 + refresh_all_windows(main_window);
4.323 + while ((res = wgetch(win))) {
4.324 + switch (res) {
4.325 + case KEY_LEFT:
4.326 + menu_driver(menu, REQ_LEFT_ITEM);
4.327 + break;
4.328 + case KEY_RIGHT:
4.329 + menu_driver(menu, REQ_RIGHT_ITEM);
4.330 + break;
4.331 + case 10: /* ENTER */
4.332 + case 27: /* ESCAPE */
4.333 + case ' ':
4.334 + case KEY_F(F_BACK):
4.335 + case KEY_F(F_EXIT):
4.336 + break;
4.337 + }
4.338 + touchwin(win);
4.339 + refresh_all_windows(main_window);
4.340 +
4.341 + if (res == 10 || res == ' ') {
4.342 + res = item_index(current_item(menu));
4.343 + break;
4.344 + } else if (res == 27 || res == KEY_F(F_BACK) ||
4.345 + res == KEY_F(F_EXIT)) {
4.346 + res = KEY_EXIT;
4.347 + break;
4.348 + }
4.349 + }
4.350 +
4.351 + unpost_menu(menu);
4.352 + free_menu(menu);
4.353 + for (i = 0; i < btn_num; i++)
4.354 + free_item(btns[i]);
4.355 +
4.356 + delwin(win);
4.357 + return res;
4.358 +}
4.359 +
4.360 +int dialog_inputbox(WINDOW *main_window,
4.361 + const char *title, const char *prompt,
4.362 + const char *init, char *result, int result_len)
4.363 +{
4.364 + int prompt_lines = 0;
4.365 + int prompt_width = 0;
4.366 + WINDOW *win;
4.367 + WINDOW *prompt_win;
4.368 + WINDOW *form_win;
4.369 + PANEL *panel;
4.370 + int i, x, y;
4.371 + int res = -1;
4.372 + int cursor_position = strlen(init);
4.373 +
4.374 +
4.375 + /* find the widest line of msg: */
4.376 + prompt_lines = get_line_no(prompt);
4.377 + for (i = 0; i < prompt_lines; i++) {
4.378 + const char *line = get_line(prompt, i);
4.379 + int len = get_line_length(line);
4.380 + prompt_width = max(prompt_width, len);
4.381 + }
4.382 +
4.383 + if (title)
4.384 + prompt_width = max(prompt_width, strlen(title));
4.385 +
4.386 + /* place dialog in middle of screen */
4.387 + y = (LINES-(prompt_lines+4))/2;
4.388 + x = (COLS-(prompt_width+4))/2;
4.389 +
4.390 + strncpy(result, init, result_len);
4.391 +
4.392 + /* create the windows */
4.393 + win = newwin(prompt_lines+6, prompt_width+7, y, x);
4.394 + prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
4.395 + form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
4.396 + keypad(form_win, TRUE);
4.397 +
4.398 + (void) wattrset(form_win, attributes[INPUT_FIELD]);
4.399 +
4.400 + (void) wattrset(win, attributes[INPUT_BOX]);
4.401 + box(win, 0, 0);
4.402 + (void) wattrset(win, attributes[INPUT_HEADING]);
4.403 + if (title)
4.404 + mvwprintw(win, 0, 3, "%s", title);
4.405 +
4.406 + /* print message */
4.407 + (void) wattrset(prompt_win, attributes[INPUT_TEXT]);
4.408 + fill_window(prompt_win, prompt);
4.409 +
4.410 + mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
4.411 + mvwprintw(form_win, 0, 0, "%s", result);
4.412 +
4.413 + /* create panels */
4.414 + panel = new_panel(win);
4.415 +
4.416 + /* show the cursor */
4.417 + curs_set(1);
4.418 +
4.419 + touchwin(win);
4.420 + refresh_all_windows(main_window);
4.421 + while ((res = wgetch(form_win))) {
4.422 + int len = strlen(result);
4.423 + switch (res) {
4.424 + case 10: /* ENTER */
4.425 + case 27: /* ESCAPE */
4.426 + case KEY_F(F_HELP):
4.427 + case KEY_F(F_EXIT):
4.428 + case KEY_F(F_BACK):
4.429 + break;
4.430 + case 127:
4.431 + case KEY_BACKSPACE:
4.432 + if (cursor_position > 0) {
4.433 + memmove(&result[cursor_position-1],
4.434 + &result[cursor_position],
4.435 + len-cursor_position+1);
4.436 + cursor_position--;
4.437 + }
4.438 + break;
4.439 + case KEY_DC:
4.440 + if (cursor_position >= 0 && cursor_position < len) {
4.441 + memmove(&result[cursor_position],
4.442 + &result[cursor_position+1],
4.443 + len-cursor_position+1);
4.444 + }
4.445 + break;
4.446 + case KEY_UP:
4.447 + case KEY_RIGHT:
4.448 + if (cursor_position < len &&
4.449 + cursor_position < min(result_len, prompt_width))
4.450 + cursor_position++;
4.451 + break;
4.452 + case KEY_DOWN:
4.453 + case KEY_LEFT:
4.454 + if (cursor_position > 0)
4.455 + cursor_position--;
4.456 + break;
4.457 + default:
4.458 + if ((isgraph(res) || isspace(res)) &&
4.459 + len-2 < result_len) {
4.460 + /* insert the char at the proper position */
4.461 + memmove(&result[cursor_position+1],
4.462 + &result[cursor_position],
4.463 + len+1);
4.464 + result[cursor_position] = res;
4.465 + cursor_position++;
4.466 + } else {
4.467 + mvprintw(0, 0, "unknow key: %d\n", res);
4.468 + }
4.469 + break;
4.470 + }
4.471 + wmove(form_win, 0, 0);
4.472 + wclrtoeol(form_win);
4.473 + mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
4.474 + mvwprintw(form_win, 0, 0, "%s", result);
4.475 + wmove(form_win, 0, cursor_position);
4.476 + touchwin(win);
4.477 + refresh_all_windows(main_window);
4.478 +
4.479 + if (res == 10) {
4.480 + res = 0;
4.481 + break;
4.482 + } else if (res == 27 || res == KEY_F(F_BACK) ||
4.483 + res == KEY_F(F_EXIT)) {
4.484 + res = KEY_EXIT;
4.485 + break;
4.486 + } else if (res == KEY_F(F_HELP)) {
4.487 + res = 1;
4.488 + break;
4.489 + }
4.490 + }
4.491 +
4.492 + /* hide the cursor */
4.493 + curs_set(0);
4.494 + del_panel(panel);
4.495 + delwin(prompt_win);
4.496 + delwin(form_win);
4.497 + delwin(win);
4.498 + return res;
4.499 +}
4.500 +
4.501 +/* refresh all windows in the correct order */
4.502 +void refresh_all_windows(WINDOW *main_window)
4.503 +{
4.504 + update_panels();
4.505 + touchwin(main_window);
4.506 + refresh();
4.507 +}
4.508 +
4.509 +/* layman's scrollable window... */
4.510 +void show_scroll_win(WINDOW *main_window,
4.511 + const char *title,
4.512 + const char *text)
4.513 +{
4.514 + int res;
4.515 + int total_lines = get_line_no(text);
4.516 + int x, y;
4.517 + int start_x = 0, start_y = 0;
4.518 + int text_lines = 0, text_cols = 0;
4.519 + int total_cols = 0;
4.520 + int win_cols = 0;
4.521 + int win_lines = 0;
4.522 + int i = 0;
4.523 + WINDOW *win;
4.524 + WINDOW *pad;
4.525 + PANEL *panel;
4.526 +
4.527 + /* find the widest line of msg: */
4.528 + total_lines = get_line_no(text);
4.529 + for (i = 0; i < total_lines; i++) {
4.530 + const char *line = get_line(text, i);
4.531 + int len = get_line_length(line);
4.532 + total_cols = max(total_cols, len+2);
4.533 + }
4.534 +
4.535 + /* create the pad */
4.536 + pad = newpad(total_lines+10, total_cols+10);
4.537 + (void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
4.538 + fill_window(pad, text);
4.539 +
4.540 + win_lines = min(total_lines+4, LINES-2);
4.541 + win_cols = min(total_cols+2, COLS-2);
4.542 + text_lines = max(win_lines-4, 0);
4.543 + text_cols = max(win_cols-2, 0);
4.544 +
4.545 + /* place window in middle of screen */
4.546 + y = (LINES-win_lines)/2;
4.547 + x = (COLS-win_cols)/2;
4.548 +
4.549 + win = newwin(win_lines, win_cols, y, x);
4.550 + keypad(win, TRUE);
4.551 + /* show the help in the help window, and show the help panel */
4.552 + (void) wattrset(win, attributes[SCROLLWIN_BOX]);
4.553 + box(win, 0, 0);
4.554 + (void) wattrset(win, attributes[SCROLLWIN_HEADING]);
4.555 + mvwprintw(win, 0, 3, " %s ", title);
4.556 + panel = new_panel(win);
4.557 +
4.558 + /* handle scrolling */
4.559 + do {
4.560 +
4.561 + copywin(pad, win, start_y, start_x, 2, 2, text_lines,
4.562 + text_cols, 0);
4.563 + print_in_middle(win,
4.564 + text_lines+2,
4.565 + 0,
4.566 + text_cols,
4.567 + "<OK>",
4.568 + attributes[DIALOG_MENU_FORE]);
4.569 + wrefresh(win);
4.570 +
4.571 + res = wgetch(win);
4.572 + switch (res) {
4.573 + case KEY_NPAGE:
4.574 + case ' ':
4.575 + start_y += text_lines-2;
4.576 + break;
4.577 + case KEY_PPAGE:
4.578 + start_y -= text_lines+2;
4.579 + break;
4.580 + case KEY_HOME:
4.581 + start_y = 0;
4.582 + break;
4.583 + case KEY_END:
4.584 + start_y = total_lines-text_lines;
4.585 + break;
4.586 + case KEY_DOWN:
4.587 + case 'j':
4.588 + start_y++;
4.589 + break;
4.590 + case KEY_UP:
4.591 + case 'k':
4.592 + start_y--;
4.593 + break;
4.594 + case KEY_LEFT:
4.595 + case 'h':
4.596 + start_x--;
4.597 + break;
4.598 + case KEY_RIGHT:
4.599 + case 'l':
4.600 + start_x++;
4.601 + break;
4.602 + }
4.603 + if (res == 10 || res == 27 || res == 'q'
4.604 + || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
4.605 + break;
4.606 + }
4.607 + if (start_y < 0)
4.608 + start_y = 0;
4.609 + if (start_y >= total_lines-text_lines)
4.610 + start_y = total_lines-text_lines;
4.611 + if (start_x < 0)
4.612 + start_x = 0;
4.613 + if (start_x >= total_cols-text_cols)
4.614 + start_x = total_cols-text_cols;
4.615 + } while (res);
4.616 +
4.617 + del_panel(panel);
4.618 + delwin(win);
4.619 + refresh_all_windows(main_window);
4.620 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/kconfig/nconf.h Thu May 12 19:45:30 2011 +0200
5.3 @@ -0,0 +1,96 @@
5.4 +/*
5.5 + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
5.6 + * Released under the terms of the GNU GPL v2.0.
5.7 + *
5.8 + * Derived from menuconfig.
5.9 + *
5.10 + */
5.11 +
5.12 +#include <ctype.h>
5.13 +#include <errno.h>
5.14 +#include <fcntl.h>
5.15 +#include <limits.h>
5.16 +#include <stdarg.h>
5.17 +#include <stdlib.h>
5.18 +#include <string.h>
5.19 +#include <unistd.h>
5.20 +#include <locale.h>
5.21 +#include <curses.h>
5.22 +#include <menu.h>
5.23 +#include <panel.h>
5.24 +#include <form.h>
5.25 +
5.26 +#include <stdio.h>
5.27 +#include <time.h>
5.28 +#include <sys/time.h>
5.29 +
5.30 +#include "ncurses.h"
5.31 +
5.32 +#define max(a, b) ({\
5.33 + typeof(a) _a = a;\
5.34 + typeof(b) _b = b;\
5.35 + _a > _b ? _a : _b; })
5.36 +
5.37 +#define min(a, b) ({\
5.38 + typeof(a) _a = a;\
5.39 + typeof(b) _b = b;\
5.40 + _a < _b ? _a : _b; })
5.41 +
5.42 +typedef enum {
5.43 + NORMAL = 1,
5.44 + MAIN_HEADING,
5.45 + MAIN_MENU_BOX,
5.46 + MAIN_MENU_FORE,
5.47 + MAIN_MENU_BACK,
5.48 + MAIN_MENU_GREY,
5.49 + MAIN_MENU_HEADING,
5.50 + SCROLLWIN_TEXT,
5.51 + SCROLLWIN_HEADING,
5.52 + SCROLLWIN_BOX,
5.53 + DIALOG_TEXT,
5.54 + DIALOG_MENU_FORE,
5.55 + DIALOG_MENU_BACK,
5.56 + DIALOG_BOX,
5.57 + INPUT_BOX,
5.58 + INPUT_HEADING,
5.59 + INPUT_TEXT,
5.60 + INPUT_FIELD,
5.61 + FUNCTION_TEXT,
5.62 + FUNCTION_HIGHLIGHT,
5.63 + ATTR_MAX
5.64 +} attributes_t;
5.65 +extern attributes_t attributes[];
5.66 +
5.67 +typedef enum {
5.68 + F_HELP = 1,
5.69 + F_SYMBOL = 2,
5.70 + F_INSTS = 3,
5.71 + F_CONF = 4,
5.72 + F_BACK = 5,
5.73 + F_SAVE = 6,
5.74 + F_LOAD = 7,
5.75 + F_SEARCH = 8,
5.76 + F_EXIT = 9,
5.77 +} function_key;
5.78 +
5.79 +void set_colors(void);
5.80 +
5.81 +/* this changes the windows attributes !!! */
5.82 +void print_in_middle(WINDOW *win,
5.83 + int starty,
5.84 + int startx,
5.85 + int width,
5.86 + const char *string,
5.87 + chtype color);
5.88 +int get_line_length(const char *line);
5.89 +int get_line_no(const char *text);
5.90 +const char *get_line(const char *text, int line_no);
5.91 +void fill_window(WINDOW *win, const char *text);
5.92 +int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
5.93 +int dialog_inputbox(WINDOW *main_window,
5.94 + const char *title, const char *prompt,
5.95 + const char *init, char *result, int result_len);
5.96 +void refresh_all_windows(WINDOW *main_window);
5.97 +void show_scroll_win(WINDOW *main_window,
5.98 + const char *title,
5.99 + const char *text);