diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile.modpost | 11 | ||||
-rw-r--r-- | scripts/kconfig/Makefile | 31 | ||||
-rw-r--r-- | scripts/kconfig/confdata.c | 2 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/Makefile | 21 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/checklist.c | 183 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/colors.h | 154 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/dialog.h | 144 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/inputbox.c | 48 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/lxdialog.c | 204 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/menubox.c | 166 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/msgbox.c | 71 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/textbox.c | 416 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/util.c | 502 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/yesno.c | 26 | ||||
-rw-r--r-- | scripts/kconfig/mconf.c | 511 |
15 files changed, 1048 insertions, 1442 deletions
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 4b2721ca97da..6c5469b1473b 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -32,6 +32,10 @@ # Step 4 is solely used to allow module versioning in external modules, # where the CRC of each module is retrieved from the Module.symers file. +# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined +# symbols in the final module linking stage +# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. +# This is solely usefull to speed up test compiles PHONY := _modpost _modpost: __modpost @@ -46,7 +50,8 @@ modulesymfile := $(KBUILD_EXTMOD)/Module.symvers __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o))) -_modpost: $(modules) +# Stop after building .o files if NOFINAL is set. Makes compile tests quicker +_modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules)) # Step 2), invoke modpost @@ -58,7 +63,7 @@ quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ - $(if $(KBUILD_EXTMOD),-w) \ + $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \ $(wildcard vmlinux) $(filter-out FORCE,$^) PHONY += __modpost @@ -92,7 +97,7 @@ targets += $(modules:.ko=.mod.o) # Step 6), final link of the modules quiet_cmd_ld_ko_o = LD [M] $@ - cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ + cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ $(filter-out FORCE,$^) $(modules): %.ko :%.o %.mod.o FORCE diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index a90d3cc76bfa..7e7e147875bf 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -11,7 +11,6 @@ gconfig: $(obj)/gconf $< arch/$(ARCH)/Kconfig menuconfig: $(obj)/mconf - $(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog $< arch/$(ARCH)/Kconfig config: $(obj)/conf @@ -81,6 +80,23 @@ help: @echo ' allyesconfig - New config where all options are accepted with yes' @echo ' allnoconfig - New config where all options are answered with no' +# lxdialog stuff +check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh + +# Use reursively expanded variables so we do not call gcc unless +# we really need to do so. (Do not call gcc as part of make mrproper) +HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) +HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) + +HOST_EXTRACFLAGS += -DLOCALE + +PHONY += $(obj)/dochecklxdialog +$(obj)/dochecklxdialog: + $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) + +always := dochecklxdialog + + # =========================================================================== # Shared Makefile for the various kconfig executables: # conf: Used for defconfig, oldconfig and related targets @@ -92,11 +108,19 @@ help: # Based on GTK which needs to be installed to compile it # object files used by all kconfig flavours -hostprogs-y := conf mconf qconf gconf kxgettext +lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o +lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o + conf-objs := conf.o zconf.tab.o -mconf-objs := mconf.o zconf.tab.o +mconf-objs := mconf.o zconf.tab.o $(lxdialog) kxgettext-objs := kxgettext.o zconf.tab.o +hostprogs-y := conf qconf gconf kxgettext + +ifeq ($(MAKECMDGOALS),menuconfig) + hostprogs-y += mconf +endif + ifeq ($(MAKECMDGOALS),xconfig) qconf-target := 1 endif @@ -116,7 +140,6 @@ endif clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c -subdir- += lxdialog # Needed for systems without gettext KBUILD_HAVE_NLS := $(shell \ diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 69f96b398c22..66b15ef02931 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -517,7 +517,7 @@ int conf_write(const char *name) fclose(out); if (*tmpname) { - strcat(dirname, name ? name : conf_get_configname()); + strcat(dirname, basename); strcat(dirname, ".old"); rename(newname, dirname); if (rename(tmpname, newname)) diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile deleted file mode 100644 index a8b026326247..000000000000 --- a/scripts/kconfig/lxdialog/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Makefile to build lxdialog package -# - -check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh - -# Use reursively expanded variables so we do not call gcc unless -# we really need to do so. (Do not call gcc as part of make mrproper) -HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) -HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) - -HOST_EXTRACFLAGS += -DLOCALE - -PHONY += dochecklxdialog -$(obj)/dochecklxdialog: - $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) - -hostprogs-y := lxdialog -always := $(hostprogs-y) dochecklxdialog - -lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \ - util.o lxdialog.o msgbox.o diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index 79886413b6d5..cf697080dddd 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -28,25 +28,25 @@ static int list_width, check_x, item_x; /* * Print list item */ -static void print_item(WINDOW * win, const char *item, int status, int choice, - int selected) +static void print_item(WINDOW * win, int choice, int selected) { int i; /* Clear 'residue' of last item */ - wattrset(win, menubox_attr); + wattrset(win, dlg.menubox.atr); wmove(win, choice, 0); for (i = 0; i < list_width; i++) waddch(win, ' '); wmove(win, choice, check_x); - wattrset(win, selected ? check_selected_attr : check_attr); - wprintw(win, "(%c)", status ? 'X' : ' '); - - wattrset(win, selected ? tag_selected_attr : tag_attr); - mvwaddch(win, choice, item_x, item[0]); - wattrset(win, selected ? item_selected_attr : item_attr); - waddstr(win, (char *)item + 1); + wattrset(win, selected ? dlg.check_selected.atr + : dlg.check.atr); + wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); + + wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); + mvwaddch(win, choice, item_x, item_str()[0]); + wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); + waddstr(win, (char *)item_str() + 1); if (selected) { wmove(win, choice, check_x + 1); wrefresh(win); @@ -62,11 +62,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, wmove(win, y, x); if (scroll > 0) { - wattrset(win, uarrow_attr); + wattrset(win, dlg.uarrow.atr); waddch(win, ACS_UARROW); waddstr(win, "(-)"); } else { - wattrset(win, menubox_attr); + wattrset(win, dlg.menubox.atr); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); @@ -77,11 +77,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, wmove(win, y, x); if ((height < item_no) && (scroll + choice < item_no - 1)) { - wattrset(win, darrow_attr); + wattrset(win, dlg.darrow.atr); waddch(win, ACS_DARROW); waddstr(win, "(+)"); } else { - wattrset(win, menubox_border_attr); + wattrset(win, dlg.menubox_border.atr); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); @@ -109,32 +109,29 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) * in the style of radiolist (only one option turned on at a time). */ int dialog_checklist(const char *title, const char *prompt, int height, - int width, int list_height, int item_no, - const char *const *items) + int width, int list_height) { int i, x, y, box_x, box_y; - int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; + int key = 0, button = 0, choice = 0, scroll = 0, max_choice; WINDOW *dialog, *list; - /* Allocate space for storing item on/off status */ - if ((status = malloc(sizeof(int) * item_no)) == NULL) { - endwin(); - fprintf(stderr, - "\nCan't allocate memory in dialog_checklist().\n"); - exit(-1); + /* which item to highlight */ + item_foreach() { + if (item_is_tag('X')) + choice = item_n(); + if (item_is_selected()) { + choice = item_n(); + break; + } } - /* Initializes status */ - for (i = 0; i < item_no; i++) { - status[i] = !strcasecmp(items[i * 3 + 2], "on"); - if ((!choice && status[i]) - || !strcasecmp(items[i * 3 + 2], "selected")) - choice = i + 1; - } - if (choice) - choice--; +do_resize: + if (getmaxy(stdscr) < (height + 6)) + return -ERRDISPLAYTOOSMALL; + if (getmaxx(stdscr) < (width + 6)) + return -ERRDISPLAYTOOSMALL; - max_choice = MIN(list_height, item_no); + max_choice = MIN(list_height, item_count()); /* center dialog box on screen */ x = (COLS - width) / 2; @@ -145,17 +142,18 @@ int dialog_checklist(const char *title, const char *prompt, int height, dialog = newwin(height, width, y, x); keypad(dialog, TRUE); - draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); - wattrset(dialog, border_attr); + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); - wattrset(dialog, dialog_attr); + wattrset(dialog, dlg.dialog.atr); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); - wattrset(dialog, dialog_attr); + wattrset(dialog, dlg.dialog.atr); print_autowrap(dialog, prompt, width - 2, 1, 3); list_width = width - 6; @@ -170,12 +168,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, /* draw a box around the list items */ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, - menubox_border_attr, menubox_attr); + dlg.menubox_border.atr, dlg.menubox.atr); /* Find length of longest item in order to center checklist */ check_x = 0; - for (i = 0; i < item_no; i++) - check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4); + item_foreach() + check_x = MAX(check_x, strlen(item_str()) + 4); check_x = (list_width - check_x) / 2; item_x = check_x + 4; @@ -187,14 +185,11 @@ int dialog_checklist(const char *title, const char *prompt, int height, /* Print the list */ for (i = 0; i < max_choice; i++) { - if (i != choice) - print_item(list, items[(scroll + i) * 3 + 1], - status[i + scroll], i, 0); + item_set(scroll + i); + print_item(list, i, i == choice); } - print_item(list, items[(scroll + choice) * 3 + 1], - status[choice + scroll], choice, 1); - print_arrows(dialog, choice, item_no, scroll, + print_arrows(dialog, choice, item_count(), scroll, box_y, box_x + check_x + 5, list_height); print_buttons(dialog, height, width, 0); @@ -203,13 +198,14 @@ int dialog_checklist(const char *title, const char *prompt, int height, wnoutrefresh(list); doupdate(); - while (key != ESC) { + while (key != KEY_ESC) { key = wgetch(dialog); - for (i = 0; i < max_choice; i++) - if (toupper(key) == - toupper(items[(scroll + i) * 3 + 1][0])) + for (i = 0; i < max_choice; i++) { + item_set(i + scroll); + if (toupper(key) == toupper(item_str()[0])) break; + } if (i < max_choice || key == KEY_UP || key == KEY_DOWN || key == '+' || key == '-') { @@ -220,15 +216,16 @@ int dialog_checklist(const char *title, const char *prompt, int height, /* Scroll list down */ if (list_height > 1) { /* De-highlight current first item */ - print_item(list, items[scroll * 3 + 1], - status[scroll], 0, FALSE); + item_set(scroll); + print_item(list, 0, FALSE); scrollok(list, TRUE); wscrl(list, -1); scrollok(list, FALSE); } scroll--; - print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); - print_arrows(dialog, choice, item_no, + item_set(scroll); + print_item(list, 0, TRUE); + print_arrows(dialog, choice, item_count(), scroll, box_y, box_x + check_x + 5, list_height); wnoutrefresh(dialog); @@ -239,23 +236,24 @@ int dialog_checklist(const char *title, const char *prompt, int height, i = choice - 1; } else if (key == KEY_DOWN || key == '+') { if (choice == max_choice - 1) { - if (scroll + choice >= item_no - 1) + if (scroll + choice >= item_count() - 1) continue; /* Scroll list up */ if (list_height > 1) { /* De-highlight current last item before scrolling up */ - print_item(list, items[(scroll + max_choice - 1) * 3 + 1], - status[scroll + max_choice - 1], - max_choice - 1, FALSE); + item_set(scroll + max_choice - 1); + print_item(list, + max_choice - 1, + FALSE); scrollok(list, TRUE); wscrl(list, 1); scrollok(list, FALSE); } scroll++; - print_item(list, items[(scroll + max_choice - 1) * 3 + 1], - status[scroll + max_choice - 1], max_choice - 1, TRUE); + item_set(scroll + max_choice - 1); + print_item(list, max_choice - 1, TRUE); - print_arrows(dialog, choice, item_no, + print_arrows(dialog, choice, item_count(), scroll, box_y, box_x + check_x + 5, list_height); wnoutrefresh(dialog); @@ -267,12 +265,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, } if (i != choice) { /* De-highlight current item */ - print_item(list, items[(scroll + choice) * 3 + 1], - status[scroll + choice], choice, FALSE); + item_set(scroll + choice); + print_item(list, choice, FALSE); /* Highlight new item */ choice = i; - print_item(list, items[(scroll + choice) * 3 + 1], - status[scroll + choice], choice, TRUE); + item_set(scroll + choice); + print_item(list, choice, TRUE); wnoutrefresh(dialog); wrefresh(list); } @@ -282,10 +280,19 @@ int dialog_checklist(const char *title, const char *prompt, int height, case 'H': case 'h': case '?': - fprintf(stderr, "%s", items[(scroll + choice) * 3]); + button = 1; + /* fall-through */ + case 'S': + case 's': + case ' ': + case '\n': + item_foreach() + item_set_selected(0); + item_set(scroll + choice); + item_set_selected(1); + delwin(list); delwin(dialog); - free(status); - return 1; + return button; case TAB: case KEY_LEFT: case KEY_RIGHT: @@ -295,42 +302,24 @@ int dialog_checklist(const char *title, const char *prompt, int height, print_buttons(dialog, height, width, button); wrefresh(dialog); break; - case 'S': - case 's': - case ' ': - case '\n': - if (!button) { - if (!status[scroll + choice]) { - for (i = 0; i < item_no; i++) - status[i] = 0; - status[scroll + choice] = 1; - for (i = 0; i < max_choice; i++) - print_item(list, items[(scroll + i) * 3 + 1], - status[scroll + i], i, i == choice); - } - wnoutrefresh(dialog); - wrefresh(list); - - for (i = 0; i < item_no; i++) - if (status[i]) - fprintf(stderr, "%s", items[i * 3]); - } else - fprintf(stderr, "%s", items[(scroll + choice) * 3]); - delwin(dialog); - free(status); - return button; case 'X': case 'x': - key = ESC; - case ESC: + key = KEY_ESC; + break; + case KEY_ESC: + key = on_key_esc(dialog); break; + case KEY_RESIZE: + delwin(list); + delwin(dialog); + on_key_resize(); + goto do_resize; } /* Now, update everything... */ doupdate(); } - + delwin(list); delwin(dialog); - free(status); - return -1; /* ESC pressed */ + return key; /* ESC pressed */ } diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h deleted file mode 100644 index db071df12bbb..000000000000 --- a/scripts/kconfig/lxdialog/colors.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * colors.h -- color attribute definitions - * - * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Default color definitions - * - * *_FG = foreground - * *_BG = background - * *_HL = highlight? - */ -#define SCREEN_FG COLOR_CYAN -#define SCREEN_BG COLOR_BLUE -#define SCREEN_HL TRUE - -#define SHADOW_FG COLOR_BLACK -#define SHADOW_BG COLOR_BLACK -#define SHADOW_HL TRUE - -#define DIALOG_FG COLOR_BLACK -#define DIALOG_BG COLOR_WHITE -#define DIALOG_HL FALSE - -#define TITLE_FG COLOR_YELLOW -#define TITLE_BG COLOR_WHITE -#define TITLE_HL TRUE - -#define BORDER_FG COLOR_WHITE -#define BORDER_BG COLOR_WHITE -#define BORDER_HL TRUE - -#define BUTTON_ACTIVE_FG COLOR_WHITE -#define BUTTON_ACTIVE_BG COLOR_BLUE -#define BUTTON_ACTIVE_HL TRUE - -#define BUTTON_INACTIVE_FG COLOR_BLACK -#define BUTTON_INACTIVE_BG COLOR_WHITE -#define BUTTON_INACTIVE_HL FALSE - -#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE -#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE -#define BUTTON_KEY_ACTIVE_HL TRUE - -#define BUTTON_KEY_INACTIVE_FG COLOR_RED -#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE -#define BUTTON_KEY_INACTIVE_HL FALSE - -#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW -#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE -#define BUTTON_LABEL_ACTIVE_HL TRUE - -#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK -#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE -#define BUTTON_LABEL_INACTIVE_HL TRUE - -#define INPUTBOX_FG COLOR_BLACK -#define INPUTBOX_BG COLOR_WHITE -#define INPUTBOX_HL FALSE - -#define INPUTBOX_BORDER_FG COLOR_BLACK -#define INPUTBOX_BORDER_BG COLOR_WHITE -#define INPUTBOX_BORDER_HL FALSE - -#define SEARCHBOX_FG COLOR_BLACK -#define SEARCHBOX_BG COLOR_WHITE -#define SEARCHBOX_HL FALSE - -#define SEARCHBOX_TITLE_FG COLOR_YELLOW -#define SEARCHBOX_TITLE_BG COLOR_WHITE -#define SEARCHBOX_TITLE_HL TRUE - -#define SEARCHBOX_BORDER_FG COLOR_WHITE -#define SEARCHBOX_BORDER_BG COLOR_WHITE -#define SEARCHBOX_BORDER_HL TRUE - -#define POSITION_INDICATOR_FG COLOR_YELLOW -#define POSITION_INDICATOR_BG COLOR_WHITE -#define POSITION_INDICATOR_HL TRUE - -#define MENUBOX_FG COLOR_BLACK -#define MENUBOX_BG COLOR_WHITE -#define MENUBOX_HL FALSE - -#define MENUBOX_BORDER_FG COLOR_WHITE -#define MENUBOX_BORDER_BG COLOR_WHITE -#define MENUBOX_BORDER_HL TRUE - -#define ITEM_FG COLOR_BLACK -#define ITEM_BG COLOR_WHITE -#define ITEM_HL FALSE - -#define ITEM_SELECTED_FG COLOR_WHITE -#define ITEM_SELECTED_BG COLOR_BLUE -#define ITEM_SELECTED_HL TRUE - -#define TAG_FG COLOR_YELLOW -#define TAG_BG COLOR_WHITE -#define TAG_HL TRUE - -#define TAG_SELECTED_FG COLOR_YELLOW -#define TAG_SELECTED_BG COLOR_BLUE -#define TAG_SELECTED_HL TRUE - -#define TAG_KEY_FG COLOR_YELLOW -#define TAG_KEY_BG COLOR_WHITE -#define TAG_KEY_HL TRUE - -#define TAG_KEY_SELECTED_FG COLOR_YELLOW -#define TAG_KEY_SELECTED_BG COLOR_BLUE -#define TAG_KEY_SELECTED_HL TRUE - -#define CHECK_FG COLOR_BLACK -#define CHECK_BG COLOR_WHITE -#define CHECK_HL FALSE - -#define CHECK_SELECTED_FG COLOR_WHITE -#define CHECK_SELECTED_BG COLOR_BLUE -#define CHECK_SELECTED_HL TRUE - -#define UARROW_FG COLOR_GREEN -#define UARROW_BG COLOR_WHITE -#define UARROW_HL TRUE - -#define DARROW_FG COLOR_GREEN -#define DARROW_BG COLOR_WHITE -#define DARROW_HL TRUE - -/* End of default color definitions */ - -#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) -#define COLOR_NAME_LEN 10 -#define COLOR_COUNT 8 - -/* - * Global variables - */ - -extern int color_table[][3]; diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index af3cf716e215..8dea47f9d3e4 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h @@ -48,7 +48,7 @@ #define TR(params) _tracef params -#define ESC 27 +#define KEY_ESC 27 #define TAB 9 #define MAX_LEN 2048 #define BUF_SIZE (10*1024) @@ -86,63 +86,111 @@ #define ACS_DARROW 'v' #endif +/* error return codes */ +#define ERRDISPLAYTOOSMALL (KEY_MAX + 1) + /* - * Attribute names + * Color definitions */ -#define screen_attr attributes[0] -#define shadow_attr attributes[1] -#define dialog_attr attributes[2] -#define title_attr attributes[3] -#define border_attr attributes[4] -#define button_active_attr attributes[5] -#define button_inactive_attr attributes[6] -#define button_key_active_attr attributes[7] -#define button_key_inactive_attr attributes[8] -#define button_label_active_attr attributes[9] -#define button_label_inactive_attr attributes[10] -#define inputbox_attr attributes[11] -#define inputbox_border_attr attributes[12] -#define searchbox_attr attributes[13] -#define searchbox_title_attr attributes[14] -#define searchbox_border_attr attributes[15] -#define position_indicator_attr attributes[16] -#define menubox_attr attributes[17] -#define menubox_border_attr attributes[18] -#define item_attr attributes[19] -#define item_selected_attr attributes[20] -#define tag_attr attributes[21] -#define tag_selected_attr attributes[22] -#define tag_key_attr attributes[23] -#define tag_key_selected_attr attributes[24] -#define check_attr attributes[25] -#define check_selected_attr attributes[26] -#define uarrow_attr attributes[27] -#define darrow_attr attributes[28] - -/* number of attributes */ -#define ATTRIBUTE_COUNT 29 +struct dialog_color { + chtype atr; /* Color attribute */ + int fg; /* foreground */ + int bg; /* background */ + int hl; /* highlight this item */ +}; + +struct dialog_info { + const char *backtitle; + struct dialog_color screen; + struct dialog_color shadow; + struct dialog_color dialog; + struct dialog_color title; + struct dialog_color border; + struct dialog_color button_active; + struct dialog_color button_inactive; + struct dialog_color button_key_active; + struct dialog_color button_key_inactive; + struct dialog_color button_label_active; + struct dialog_color button_label_inactive; + struct dialog_color inputbox; + struct dialog_color inputbox_border; + struct dialog_color searchbox; + struct dialog_color searchbox_title; + struct dialog_color searchbox_border; + struct dialog_color position_indicator; + struct dialog_color menubox; + struct dialog_color menubox_border; + struct dialog_color item; + struct dialog_color item_selected; + struct dialog_color tag; + struct dialog_color tag_selected; + struct dialog_color tag_key; + struct dialog_color tag_key_selected; + struct dialog_color check; + struct dialog_color check_selected; + struct dialog_color uarrow; + struct dialog_color darrow; +}; /* * Global variables */ -extern bool use_colors; -extern bool use_shadow; - -extern chtype attributes[]; - -extern const char *backtitle; +extern struct dialog_info dlg; +extern char dialog_input_result[]; /* * Function prototypes */ -extern void create_rc(const char *filename); -extern int parse_rc(void); -void init_dialog(void); +/* item list as used by checklist and menubox */ +void item_reset(void); +void item_make(const char *fmt, ...); +void item_add_str(const char *fmt, ...); +void item_set_tag(char tag); +void item_set_data(void *p); +void item_set_selected(int val); +int item_activate_selected(void); +void *item_data(void); +char item_tag(void); + +/* item list manipulation for lxdialog use */ +#define MAXITEMSTR 200 +struct dialog_item { + char str[MAXITEMSTR]; /* promtp displayed */ + char tag; + void *data; /* pointer to menu item - used by menubox+checklist */ + int selected; /* Set to 1 by dialog_*() function if selected. */ +}; + +/* list of lialog_items */ +struct dialog_list { + struct dialog_item node; + struct dialog_list *next; +}; + +extern struct dialog_list *item_cur; +extern struct dialog_list item_nil; +extern struct dialog_list *item_head; + +int item_count(void); +void item_set(int n); +int item_n(void); +const char *item_str(void); +int item_is_selected(void); +int item_is_tag(char tag); +#define item_foreach() \ + for (item_cur = item_head ? item_head: item_cur; \ + item_cur && (item_cur != &item_nil); item_cur = item_cur->next) + +/* generic key handlers */ +int on_key_esc(WINDOW *win); +int on_key_resize(void); + +void init_dialog(const char *backtitle); +void reset_dialog(void); void end_dialog(void); void attr_clear(WINDOW * win, int height, int width, chtype attr); void dialog_clear(void); -void color_setup(void); void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); void print_button(WINDOW * win, const char *label, int y, int x, int selected); void print_title(WINDOW *dialog, const char *title, int width); @@ -155,12 +203,10 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width); int dialog_msgbox(const char *title, const char *prompt, int height, int width, int pause); int dialog_textbox(const char *title, const char *file, int height, int width); -int dialog_menu(const char *title, const char *prompt, int height, int width, - int menu_height, const char *choice, int item_no, - const char *const *items); +int dialog_menu(const char *title, const char *prompt, + const void *selected, int *s_scroll); int dialog_checklist(const char *title, const char *prompt, int height, - int width, int list_height, int item_no, - const char *const *items); + int width, int list_height); extern char dialog_input_result[]; int dialog_inputbox(const char *title, const char *prompt, int height, int width, const char *init); diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index 779503726b0a..05e72066b359 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width char *instr = dialog_input_result; WINDOW *dialog; + if (!init) + instr[0] = '\0'; + else + strcpy(instr, init); + +do_resize: + if (getmaxy(stdscr) <= (height - 2)) + return -ERRDISPLAYTOOSMALL; + if (getmaxx(stdscr) <= (width - 2)) + return -ERRDISPLAYTOOSMALL; + /* center dialog box on screen */ x = (COLS - width) / 2; y = (LINES - height) / 2; @@ -58,17 +69,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width dialog = newwin(height, width, y, x); keypad(dialog, TRUE); - draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); - wattrset(dialog, border_attr); + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); - wattrset(dialog, dialog_attr); + wattrset(dialog, dlg.dialog.atr); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); - wattrset(dialog, dialog_attr); + wattrset(dialog, dlg.dialog.atr); print_autowrap(dialog, prompt, width - 2, 1, 3); /* Draw the input field box */ @@ -76,18 +88,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width getyx(dialog, y, x); box_y = y + 2; box_x = (width - box_width) / 2; - draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr); + draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, + dlg.border.atr, dlg.dialog.atr); print_buttons(dialog, height, width, 0); /* Set up the initial value */ wmove(dialog, box_y, box_x); - wattrset(dialog, inputbox_attr); - - if (!init) - instr[0] = '\0'; - else - strcpy(instr, init); + wattrset(dialog, dlg.inputbox.atr); input_x = strlen(instr); @@ -104,7 +112,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width wrefresh(dialog); - while (key != ESC) { + while (key != KEY_ESC) { key = wgetch(dialog); if (button == -1) { /* Input box selected */ @@ -120,7 +128,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width case KEY_BACKSPACE: case 127: if (input_x || scroll) { - wattrset(dialog, inputbox_attr); + wattrset(dialog, dlg.inputbox.atr); if (!input_x) { scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); wmove(dialog, box_y, box_x); @@ -140,7 +148,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width default: if (key < 0x100 && isprint(key)) { if (scroll + input_x < MAX_LEN) { - wattrset(dialog, inputbox_attr); + wattrset(dialog, dlg.inputbox.atr); instr[scroll + input_x] = key; instr[scroll + input_x + 1] = '\0'; if (input_x == box_width - 1) { @@ -213,12 +221,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width return (button == -1 ? 0 : button); case 'X': case 'x': - key = ESC; - case ESC: + key = KEY_ESC; + break; + case KEY_ESC: + key = on_key_esc(dialog); break; + case KEY_RESIZE: + delwin(dialog); + on_key_resize(); + goto do_resize; } } delwin(dialog); - return -1; /* ESC pressed */ + return KEY_ESC; /* ESC pressed */ } diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c deleted file mode 100644 index 79f6c5fb5cef..000000000000 --- a/scripts/kconfig/lxdialog/lxdialog.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * dialog - Display simple dialog boxes from shell scripts - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "dialog.h" - -static void Usage(const char *name); - -typedef int (jumperFn) (const char *title, int argc, const char *const *argv); - -struct Mode { - char *name; - int argmin, argmax, argmod; - jumperFn *jumper; -}; - -jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox; -jumperFn j_msgbox, j_infobox; - -static struct Mode modes[] = { - {"--menu", 9, 0, 3, j_menu}, - {"--radiolist", 9, 0, 3, j_radiolist}, - {"--yesno", 5, 5, 1, j_yesno}, - {"--textbox", 5, 5, 1, j_textbox}, - {"--inputbox", 5, 6, 1, j_inputbox}, - {"--msgbox", 5, 5, 1, j_msgbox}, - {"--infobox", 5, 5, 1, j_infobox}, - {NULL, 0, 0, 0, NULL} -}; - -static struct Mode *modePtr; - -#ifdef LOCALE -#include <locale.h> -#endif - -int main(int argc, const char *const *argv) -{ - int offset = 0, opt_clear = 0, end_common_opts = 0, retval; - const char *title = NULL; - -#ifdef LOCALE - (void)setlocale(LC_ALL, ""); -#endif - -#ifdef TRACE - trace(TRACE_CALLS | TRACE_UPDATE); -#endif - if (argc < 2) { - Usage(argv[0]); - exit(-1); - } - - while (offset < argc - 1 && !end_common_opts) { /* Common options */ - if (!strcmp(argv[offset + 1], "--title")) { - if (argc - offset < 3 || title != NULL) { - Usage(argv[0]); - exit(-1); - } else { - title = argv[offset + 2]; - offset += 2; - } - } else if (!strcmp(argv[offset + 1], "--backtitle")) { - if (backtitle != NULL) { - Usage(argv[0]); - exit(-1); - } else { - backtitle = argv[offset + 2]; - offset += 2; - } - } else if (!strcmp(argv[offset + 1], "--clear")) { - if (opt_clear) { /* Hey, "--clear" can't appear twice! */ - Usage(argv[0]); - exit(-1); - } else if (argc == 2) { /* we only want to clear the screen */ - init_dialog(); - refresh(); /* init_dialog() will clear the screen for us */ - end_dialog(); - return 0; - } else { - opt_clear = 1; - offset++; - } - } else /* no more common options */ - end_common_opts = 1; - } - - if (argc - 1 == offset) { /* no more options */ - Usage(argv[0]); - exit(-1); - } - /* use a table to look for the requested mode, to avoid code duplication */ - - for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */ - if (!strcmp(argv[offset + 1], modePtr->name)) - break; - - if (!modePtr->name) - Usage(argv[0]); - if (argc - offset < modePtr->argmin) - Usage(argv[0]); - if (modePtr->argmax && argc - offset > modePtr->argmax) - Usage(argv[0]); - - init_dialog(); - retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset); - - if (opt_clear) { /* clear screen before exit */ - attr_clear(stdscr, LINES, COLS, screen_attr); - refresh(); - } - end_dialog(); - - exit(retval); -} - -/* - * Print program usage - */ -static void Usage(const char *name) -{ - fprintf(stderr, "\ -\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\ -\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\ -\n modified/gutted for use as a Linux kernel config tool by \ -\n William Roadcap (roadcapw@cfw.com)\ -\n\ -\n* Display dialog boxes from shell scripts *\ -\n\ -\nUsage: %s --clear\ -\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\ -\n\ -\nBox options:\ -\n\ -\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\ -\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\ -\n --textbox <file> <height> <width>\ -\n --inputbox <text> <height> <width> [<init>]\ -\n --yesno <text> <height> <width>\ -\n", name, name); - exit(-1); -} - -/* - * These are the program jumpers - */ - -int j_menu(const char *t, int ac, const char *const *av) -{ - return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]), - atoi(av[5]), av[6], (ac - 6) / 2, av + 7); -} - -int j_radiolist(const char *t, int ac, const char *const *av) -{ - return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]), - atoi(av[5]), (ac - 6) / 3, av + 6); -} - -int j_textbox(const char *t, int ac, const char *const *av) -{ - return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4])); -} - -int j_yesno(const char *t, int ac, const char *const *av) -{ - return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4])); -} - -int j_inputbox(const char *t, int ac, const char *const *av) -{ - int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]), - ac == 6 ? av[5] : (char *)NULL); - if (ret == 0) - fprintf(stderr, dialog_input_result); - return ret; -} - -int j_msgbox(const char *t, int ac, const char *const *av) -{ - return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1); -} - -int j_infobox(const char *t, int ac, const char *const *av) -{ - return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0); -} diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index bf8052f4fd4a..0d83159d9012 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -63,19 +63,19 @@ static int menu_width, item_x; /* * Print menu item */ -static void do_print_item(WINDOW * win, const char *item, int choice, +static void do_print_item(WINDOW * win, const char *item, int line_y, int selected, int hotkey) { int j; char *menu_item = malloc(menu_width + 1); strncpy(menu_item, item, menu_width - item_x); - menu_item[menu_width] = 0; + menu_item[menu_width - item_x] = '\0'; j = first_alpha(menu_item, "YyNnMmHh"); /* Clear 'residue' of last item */ - wattrset(win, menubox_attr); - wmove(win, choice, 0); + wattrset(win, dlg.menubox.atr); + wmove(win, line_y, 0); #if OLD_NCURSES { int i; @@ -85,23 +85,24 @@ static void do_print_item(WINDOW * win, const char *item, int choice, #else wclrtoeol(win); #endif - wattrset(win, selected ? item_selected_attr : item_attr); - mvwaddstr(win, choice, item_x, menu_item); + wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); + mvwaddstr(win, line_y, item_x, menu_item); if (hotkey) { - wattrset(win, selected ? tag_key_selected_attr : tag_key_attr); - mvwaddch(win, choice, item_x + j, menu_item[j]); + wattrset(win, selected ? dlg.tag_key_selected.atr + : dlg.tag_key.atr); + mvwaddch(win, line_y, item_x + j, menu_item[j]); } if (selected) { - wmove(win, choice, item_x + 1); + wmove(win, line_y, item_x + 1); } free(menu_item); wrefresh(win); } -#define print_item(index, choice, selected) \ -do {\ - int hotkey = (items[(index) * 2][0] != ':'); \ - do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \ +#define print_item(index, choice, selected) \ +do { \ + item_set(index); \ + do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \ } while (0) /* @@ -117,11 +118,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, wmove(win, y, x); if (scroll > 0) { - wattrset(win, uarrow_attr); + wattrset(win, dlg.uarrow.atr); waddch(win, ACS_UARROW); waddstr(win, "(-)"); } else { - wattrset(win, menubox_attr); + wattrset(win, dlg.menubox.atr); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); @@ -133,11 +134,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, wrefresh(win); if ((height < item_no) && (scroll + height < item_no)) { - wattrset(win, darrow_attr); + wattrset(win, dlg.darrow.atr); waddch(win, ACS_DARROW); waddstr(win, "(+)"); } else { - wattrset(win, menubox_border_attr); + wattrset(win, dlg.menubox_border.atr); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); waddch(win, ACS_HLINE); @@ -178,17 +179,26 @@ static void do_scroll(WINDOW *win, int *scroll, int n) /* * Display a menu for choosing among a number of options */ -int dialog_menu(const char *title, const char *prompt, int height, int width, - int menu_height, const char *current, int item_no, - const char *const *items) +int dialog_menu(const char *title, const char *prompt, + const void *selected, int *s_scroll) { int i, j, x, y, box_x, box_y; + int height, width, menu_height; int key = 0, button = 0, scroll = 0, choice = 0; int first_item = 0, max_choice; WINDOW *dialog, *menu; - FILE *f; - max_choice = MIN(menu_height, item_no); +do_resize: + height = getmaxy(stdscr); + width = getmaxx(stdscr); + if (height < 15 || width < 65) + return -ERRDISPLAYTOOSMALL; + + height -= 4; + width -= 5; + menu_height = height - 10; + + max_choice = MIN(menu_height, item_count()); /* center dialog box on screen */ x = (COLS - width) / 2; @@ -199,18 +209,19 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, dialog = newwin(height, width, y, x); keypad(dialog, TRUE); - draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); - wattrset(dialog, border_attr); + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); - wattrset(dialog, dialog_attr); - wbkgdset(dialog, dialog_attr & A_COLOR); + wattrset(dialog, dlg.dialog.atr); + wbkgdset(dialog, dlg.dialog.atr & A_COLOR); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); - wattrset(dialog, dialog_attr); + wattrset(dialog, dlg.dialog.atr); print_autowrap(dialog, prompt, width - 2, 1, 3); menu_width = width - 6; @@ -224,33 +235,29 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, /* draw a box around the menu items */ draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, - menubox_border_attr, menubox_attr); + dlg.menubox_border.atr, dlg.menubox.atr); - item_x = (menu_width - 70) / 2; + if (menu_width >= 80) + item_x = (menu_width - 70) / 2; + else + item_x = 4; /* Set choice to default item */ - for (i = 0; i < item_no; i++) - if (strcmp(current, items[i * 2]) == 0) - choice = i; - - /* get the scroll info from the temp file */ - if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) { - if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) && - (scroll + max_choice > choice) && (scroll >= 0) && - (scroll + max_choice <= item_no)) { - first_item = scroll; - choice = choice - scroll; - fclose(f); - } else { - scroll = 0; - remove("lxdialog.scrltmp"); - fclose(f); - f = NULL; - } + item_foreach() + if (selected && (selected == item_data())) + choice = item_n(); + /* get the saved scroll info */ + scroll = *s_scroll; + if ((scroll <= choice) && (scroll + max_choice > choice) && + (scroll >= 0) && (scroll + max_choice <= item_count())) { + first_item = scroll; + choice = choice - scroll; + } else { + scroll = 0; } - if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) { - if (choice >= item_no - max_choice / 2) - scroll = first_item = item_no - max_choice; + if ((choice >= max_choice)) { + if (choice >= item_count() - max_choice / 2) + scroll = first_item = item_count() - max_choice; else scroll = first_item = choice - max_choice / 2; choice = choice - scroll; @@ -263,14 +270,14 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, wnoutrefresh(menu); - print_arrows(dialog, item_no, scroll, + print_arrows(dialog, item_count(), scroll, box_y, box_x + item_x + 1, menu_height); print_buttons(dialog, height, width, 0); wmove(menu, choice, item_x + 1); wrefresh(menu); - while (key != ESC) { + while (key != KEY_ESC) { key = wgetch(menu); if (key < 256 && isalpha(key)) @@ -280,14 +287,16 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, i = max_choice; else { for (i = choice + 1; i < max_choice; i++) { - j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh"); - if (key == tolower(items[(scroll + i) * 2 + 1][j])) + item_set(scroll + i); + j = first_alpha(item_str(), "YyNnMmHh"); + if (key == tolower(item_str()[j])) break; } if (i == max_choice) for (i = 0; i < max_choice; i++) { - j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh"); - if (key == tolower(items[(scroll + i) * 2 + 1][j])) + item_set(scroll + i); + j = first_alpha(item_str(), "YyNnMmHh"); + if (key == tolower(item_str()[j])) break; } } @@ -312,7 +321,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, print_item(scroll+choice, choice, FALSE); if ((choice > max_choice - 3) && - (scroll + max_choice < item_no)) { + (scroll + max_choice < item_count())) { /* Scroll menu up */ do_scroll(menu, &scroll, 1); @@ -335,7 +344,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, } else if (key == KEY_NPAGE) { for (i = 0; (i < max_choice); i++) { - if (scroll + max_choice < item_no) { + if (scroll + max_choice < item_count()) { do_scroll(menu, &scroll, 1); print_item(scroll+max_choice-1, max_choice - 1, FALSE); @@ -349,7 +358,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, print_item(scroll + choice, choice, TRUE); - print_arrows(dialog, item_no, scroll, + print_arrows(dialog, item_count(), scroll, box_y, box_x + item_x + 1, menu_height); wnoutrefresh(dialog); @@ -375,12 +384,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, case 'm': case '/': /* save scroll info */ - if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) { - fprintf(f, "%d\n", scroll); - fclose(f); - } + *s_scroll = scroll; + delwin(menu); delwin(dialog); - fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); + item_set(scroll + choice); + item_set_selected(1); switch (key) { case 's': return 3; @@ -400,27 +408,27 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, case '?': button = 2; case '\n': + *s_scroll = scroll; + delwin(menu); delwin(dialog); - if (button == 2) - fprintf(stderr, "%s \"%s\"\n", - items[(scroll + choice) * 2], - items[(scroll + choice) * 2 + 1] + - first_alpha(items [(scroll + choice) * 2 + 1], "")); - else - fprintf(stderr, "%s\n", - items[(scroll + choice) * 2]); - - remove("lxdialog.scrltmp"); + item_set(scroll + choice); + item_set_selected(1); return button; case 'e': case 'x': - key = ESC; - case ESC: + key = KEY_ESC; + break; + case KEY_ESC: + key = on_key_esc(menu); break; + case KEY_RESIZE: + on_key_resize(); + delwin(menu); + delwin(dialog); + goto do_resize; } } - + delwin(menu); delwin(dialog); - remove("lxdialog.scrltmp"); - return -1; /* ESC pressed */ + return key; /* ESC pressed */ } diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c deleted file mode 100644 index 7323f5471f69..000000000000 --- a/scripts/kconfig/lxdialog/msgbox.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * msgbox.c -- implements the message box and info box - * - * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) - * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "dialog.h" - -/* - * Display a message box. Program will pause and display an "OK" button - * if the parameter 'pause' is non-zero. - */ -int dialog_msgbox(const char *title, const char *prompt, int height, int width, - int pause) -{ - int i, x, y, key = 0; - WINDOW *dialog; - - /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; - - draw_shadow(stdscr, y, x, height, width); - - dialog = newwin(height, width, y, x); - keypad(dialog, TRUE); - - draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); - - print_title(dialog, title, width); - - wattrset(dialog, dialog_attr); - print_autowrap(dialog, prompt, width - 2, 1, 2); - - if (pause) { - wattrset(dialog, border_attr); - mvwaddch(dialog, height - 3, 0, ACS_LTEE); - for (i = 0; i < width - 2; i++) - waddch(dialog, ACS_HLINE); - wattrset(dialog, dialog_attr); - waddch(dialog, ACS_RTEE); - - print_button(dialog, " Ok ", height - 2, width / 2 - 4, TRUE); - - wrefresh(dialog); - while (key != ESC && key != '\n' && key != ' ' && - key != 'O' && key != 'o' && key != 'X' && key != 'x') - key = wgetch(dialog); - } else { - key = '\n'; - wrefresh(dialog); - } - - delwin(dialog); - return key == ESC ? -1 : 0; -} diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 77848bb8e07f..fabfc1ad789d 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -25,56 +25,62 @@ static void back_lines(int n); static void print_page(WINDOW * win, int height, int width); static void print_line(WINDOW * win, int row, int width); static char *get_line(void); -static void print_position(WINDOW * win, int height, int width); +static void print_position(WINDOW * win); + +static int hscroll; +static int begin_reached, end_reached, page_length; +static const char *buf; +static const char *page; + +/* + * refresh window content + */ +static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, + int cur_y, int cur_x) +{ + print_page(box, boxh, boxw); + print_position(dialog); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); +} -static int hscroll, fd, file_size, bytes_read; -static int begin_reached = 1, end_reached, page_length; -static char *buf, *page; /* * Display text from a file in a dialog box. */ -int dialog_textbox(const char *title, const char *file, int height, int width) +int dialog_textbox(const char *title, const char *tbuf, + int initial_height, int initial_width) { - int i, x, y, cur_x, cur_y, fpos, key = 0; + int i, x, y, cur_x, cur_y, key = 0; + int height, width, boxh, boxw; int passed_end; - char search_term[MAX_LEN + 1]; - WINDOW *dialog, *text; - - search_term[0] = '\0'; /* no search term entered yet */ + WINDOW *dialog, *box; - /* Open input file for reading */ - if ((fd = open(file, O_RDONLY)) == -1) { - endwin(); - fprintf(stderr, "\nCan't open input file in dialog_textbox().\n"); - exit(-1); - } - /* Get file size. Actually, 'file_size' is the real file size - 1, - since it's only the last byte offset from the beginning */ - if ((file_size = lseek(fd, 0, SEEK_END)) == -1) { - endwin(); - fprintf(stderr, "\nError getting file size in dialog_textbox().\n"); - exit(-1); - } - /* Restore file pointer to beginning of file after getting file size */ - if (lseek(fd, 0, SEEK_SET) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); - exit(-1); - } - /* Allocate space for read buffer */ - if ((buf = malloc(BUF_SIZE + 1)) == NULL) { - endwin(); - fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n"); - exit(-1); - } - if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) { - endwin(); - fprintf(stderr, "\nError reading file in dialog_textbox().\n"); - exit(-1); - } - buf[bytes_read] = '\0'; /* mark end of valid data */ - page = buf; /* page is pointer to start of page to be displayed */ + begin_reached = 1; + end_reached = 0; + page_length = 0; + hscroll = 0; + buf = tbuf; + page = buf; /* page is pointer to start of page to be displayed */ + +do_resize: + getmaxyx(stdscr, height, width); + if (height < 8 || width < 8) + return -ERRDISPLAYTOOSMALL; + if (initial_height != 0) + height = initial_height; + else + if (height > 4) + height -= 4; + else + height = 0; + if (initial_width != 0) + width = initial_width; + else + if (width > 5) + width -= 5; + else + width = 0; /* center dialog box on screen */ x = (COLS - width) / 2; @@ -85,22 +91,25 @@ int dialog_textbox(const char *title, const char *file, int height, int width) dialog = newwin(height, width, y, x); keypad(dialog, TRUE); - /* Create window for text region, used for scrolling text */ - text = subwin(dialog, height - 4, width - 2, y + 1, x + 1); - wattrset(text, dialog_attr); - wbkgdset(text, dialog_attr & A_COLOR); + /* Create window for box region, used for scrolling text */ + boxh = height - 4; + boxw = width - 2; + box = subwin(dialog, boxh, boxw, y + 1, x + 1); + wattrset(box, dlg.dialog.atr); + wbkgdset(box, dlg.dialog.atr & A_COLOR); - keypad(text, TRUE); + keypad(box, TRUE); /* register the new window, along with its borders */ - draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); - wattrset(dialog, border_attr); + wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); - wattrset(dialog, dialog_attr); - wbkgdset(dialog, dialog_attr & A_COLOR); + wattrset(dialog, dlg.dialog.atr); + wbkgdset(dialog, dlg.dialog.atr & A_COLOR); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); @@ -110,85 +119,37 @@ int dialog_textbox(const char *title, const char *file, int height, int width) getyx(dialog, cur_y, cur_x); /* Save cursor position */ /* Print first page of text */ - attr_clear(text, height - 4, width - 2, dialog_attr); - print_page(text, height - 4, width - 2); - print_position(dialog, height, width); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); + attr_clear(box, boxh, boxw, dlg.dialog.atr); + refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); - while ((key != ESC) && (key != '\n')) { + while ((key != KEY_ESC) && (key != '\n')) { key = wgetch(dialog); switch (key) { case 'E': /* Exit */ case 'e': case 'X': case 'x': + delwin(box); delwin(dialog); - free(buf); - close(fd); return 0; case 'g': /* First page */ case KEY_HOME: if (!begin_reached) { begin_reached = 1; - /* First page not in buffer? */ - if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); - exit(-1); - } - if (fpos > bytes_read) { /* Yes, we have to read it in */ - if (lseek(fd, 0, SEEK_SET) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in " - "dialog_textbox().\n"); - exit(-1); - } - if ((bytes_read = - read(fd, buf, BUF_SIZE)) == -1) { - endwin(); - fprintf(stderr, "\nError reading file in dialog_textbox().\n"); - exit(-1); - } - buf[bytes_read] = '\0'; - } page = buf; - print_page(text, height - 4, width - 2); - print_position(dialog, height, width); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); } break; case 'G': /* Last page */ case KEY_END: end_reached = 1; - /* Last page not in buffer? */ - if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); - exit(-1); - } - if (fpos < file_size) { /* Yes, we have to read it in */ - if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); - exit(-1); - } - if ((bytes_read = - read(fd, buf, BUF_SIZE)) == -1) { - endwin(); - fprintf(stderr, "\nError reading file in dialog_textbox().\n"); - exit(-1); - } - buf[bytes_read] = '\0'; - } - page = buf + bytes_read; - back_lines(height - 4); - print_page(text, height - 4, width - 2); - print_position(dialog, height, width); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); + /* point to last char in buf */ + page = buf + strlen(buf); + back_lines(boxh); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); break; case 'K': /* Previous line */ case 'k': @@ -196,21 +157,23 @@ int dialog_textbox(const char *title, const char *file, int height, int width) if (!begin_reached) { back_lines(page_length + 1); - /* We don't call print_page() here but use scrolling to ensure - faster screen update. However, 'end_reached' and - 'page_length' should still be updated, and 'page' should - point to start of next page. This is done by calling - get_line() in the following 'for' loop. */ - scrollok(text, TRUE); - wscrl(text, -1); /* Scroll text region down one line */ - scrollok(text, FALSE); + /* We don't call print_page() here but use + * scrolling to ensure faster screen update. + * However, 'end_reached' and 'page_length' + * should still be updated, and 'page' should + * point to start of next page. This is done + * by calling get_line() in the following + * 'for' loop. */ + scrollok(box, TRUE); + wscrl(box, -1); /* Scroll box region down one line */ + scrollok(box, FALSE); page_length = 0; passed_end = 0; - for (i = 0; i < height - 4; i++) { + for (i = 0; i < boxh; i++) { if (!i) { /* print first line of page */ - print_line(text, 0, width - 2); - wnoutrefresh(text); + print_line(box, 0, boxw); + wnoutrefresh(box); } else /* Called to update 'end_reached' and 'page' */ get_line(); @@ -220,7 +183,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) passed_end = 1; } - print_position(dialog, height, width); + print_position(dialog); wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } @@ -230,23 +193,21 @@ int dialog_textbox(const char *title, const char *file, int height, int width) case KEY_PPAGE: if (begin_reached) break; - back_lines(page_length + height - 4); - print_page(text, height - 4, width - 2); - print_position(dialog, height, width); - wmove(dialog, cur_y, cur_x); - wrefresh(dialog); + back_lines(page_length + boxh); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); break; case 'J': /* Next line */ case 'j': case KEY_DOWN: if (!end_reached) { begin_reached = 0; - scrollok(text, TRUE); - scroll(text); /* Scroll text region up one line */ - scrollok(text, FALSE); - print_line(text, height - 5, width - 2); - wnoutrefresh(text); - print_position(dialog, height, width); + scrollok(box, TRUE); + scroll(box); /* Scroll box region up one line */ + scrollok(box, FALSE); + print_line(box, boxh - 1, boxw); + wnoutrefresh(box); + print_position(dialog); wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } @@ -257,10 +218,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) break; begin_reached = 0; - print_page(text, height - 4, width - 2); - print_position(dialog, height, width); - wmove(dialog, cur_y, cur_x); - wrefresh(dialog); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); break; case '0': /* Beginning of line */ case 'H': /* Scroll left */ @@ -275,9 +234,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) hscroll--; /* Reprint current page to scroll horizontally */ back_lines(page_length); - print_page(text, height - 4, width - 2); - wmove(dialog, cur_y, cur_x); - wrefresh(dialog); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); break; case 'L': /* Scroll right */ case 'l': @@ -287,131 +245,56 @@ int dialog_textbox(const char *title, const char *file, int height, int width) hscroll++; /* Reprint current page to scroll horizontally */ back_lines(page_length); - print_page(text, height - 4, width - 2); - wmove(dialog, cur_y, cur_x); - wrefresh(dialog); + refresh_text_box(dialog, box, boxh, boxw, + cur_y, cur_x); break; - case ESC: + case KEY_ESC: + key = on_key_esc(dialog); break; + case KEY_RESIZE: + back_lines(height); + delwin(box); + delwin(dialog); + on_key_resize(); + goto do_resize; } } - + delwin(box); delwin(dialog); - free(buf); - close(fd); - return -1; /* ESC pressed */ + return key; /* ESC pressed */ } /* - * Go back 'n' lines in text file. Called by dialog_textbox(). + * Go back 'n' lines in text. Called by dialog_textbox(). * 'page' will be updated to point to the desired line in 'buf'. */ static void back_lines(int n) { - int i, fpos; + int i; begin_reached = 0; - /* We have to distinguish between end_reached and !end_reached - since at end of file, the line is not ended by a '\n'. - The code inside 'if' basically does a '--page' to move one - character backward so as to skip '\n' of the previous line */ - if (!end_reached) { - /* Either beginning of buffer or beginning of file reached? */ - if (page == buf) { - if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in " - "back_lines().\n"); - exit(-1); - } - if (fpos > bytes_read) { /* Not beginning of file yet */ - /* We've reached beginning of buffer, but not beginning of - file yet, so read previous part of file into buffer. - Note that we only move backward for BUF_SIZE/2 bytes, - but not BUF_SIZE bytes to avoid re-reading again in - print_page() later */ - /* Really possible to move backward BUF_SIZE/2 bytes? */ - if (fpos < BUF_SIZE / 2 + bytes_read) { - /* No, move less then */ - if (lseek(fd, 0, SEEK_SET) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in " - "back_lines().\n"); - exit(-1); - } - page = buf + fpos - bytes_read; - } else { /* Move backward BUF_SIZE/2 bytes */ - if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer " - "in back_lines().\n"); - exit(-1); - } - page = buf + BUF_SIZE / 2; - } - if ((bytes_read = - read(fd, buf, BUF_SIZE)) == -1) { - endwin(); - fprintf(stderr, "\nError reading file in back_lines().\n"); - exit(-1); - } - buf[bytes_read] = '\0'; - } else { /* Beginning of file reached */ - begin_reached = 1; - return; + /* Go back 'n' lines */ + for (i = 0; i < n; i++) { + if (*page == '\0') { + if (end_reached) { + end_reached = 0; + continue; } } - if (*(--page) != '\n') { /* '--page' here */ - /* Something's wrong... */ - endwin(); - fprintf(stderr, "\nInternal error in back_lines().\n"); - exit(-1); + if (page == buf) { + begin_reached = 1; + return; } - } - /* Go back 'n' lines */ - for (i = 0; i < n; i++) + page--; do { if (page == buf) { - if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in back_lines().\n"); - exit(-1); - } - if (fpos > bytes_read) { - /* Really possible to move backward BUF_SIZE/2 bytes? */ - if (fpos < BUF_SIZE / 2 + bytes_read) { - /* No, move less then */ - if (lseek(fd, 0, SEEK_SET) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer " - "in back_lines().\n"); - exit(-1); - } - page = buf + fpos - bytes_read; - } else { /* Move backward BUF_SIZE/2 bytes */ - if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer" - " in back_lines().\n"); - exit(-1); - } - page = buf + BUF_SIZE / 2; - } - if ((bytes_read = - read(fd, buf, BUF_SIZE)) == -1) { - endwin(); - fprintf(stderr, "\nError reading file in " - "back_lines().\n"); - exit(-1); - } - buf[bytes_read] = '\0'; - } else { /* Beginning of file reached */ - begin_reached = 1; - return; - } + begin_reached = 1; + return; } - } while (*(--page) != '\n'); - page++; + page--; + } while (*page != '\n'); + page++; + } } /* @@ -466,33 +349,14 @@ static void print_line(WINDOW * win, int row, int width) */ static char *get_line(void) { - int i = 0, fpos; + int i = 0; static char line[MAX_LEN + 1]; end_reached = 0; while (*page != '\n') { if (*page == '\0') { - /* Either end of file or end of buffer reached */ - if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in " - "get_line().\n"); - exit(-1); - } - if (fpos < file_size) { /* Not end of file yet */ - /* We've reached end of buffer, but not end of file yet, - so read next part of file into buffer */ - if ((bytes_read = - read(fd, buf, BUF_SIZE)) == -1) { - endwin(); - fprintf(stderr, "\nError reading file in get_line().\n"); - exit(-1); - } - buf[bytes_read] = '\0'; - page = buf; - } else { - if (!end_reached) - end_reached = 1; + if (!end_reached) { + end_reached = 1; break; } } else if (i < MAX_LEN) @@ -515,19 +379,13 @@ static char *get_line(void) /* * Print current position */ -static void print_position(WINDOW * win, int height, int width) +static void print_position(WINDOW * win) { - int fpos, percent; + int percent; - if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { - endwin(); - fprintf(stderr, "\nError moving file pointer in print_position().\n"); - exit(-1); - } - wattrset(win, position_indicator_attr); - wbkgdset(win, position_indicator_attr & A_COLOR); - percent = !file_size ? - 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; - wmove(win, height - 3, width - 9); + wattrset(win, dlg.position_indicator.atr); + wbkgdset(win, dlg.position_indicator.atr & A_COLOR); + percent = (page - buf) * 100 / strlen(buf); + wmove(win, getmaxy(win) - 3, getmaxx(win) - 9); wprintw(win, "(%3d%%)", percent); } diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index f82cebb9ff06..ebc781b493d7 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c @@ -21,85 +21,217 @@ #include "dialog.h" -/* use colors by default? */ -bool use_colors = 1; +struct dialog_info dlg; -const char *backtitle = NULL; +static void set_mono_theme(void) +{ + dlg.screen.atr = A_NORMAL; + dlg.shadow.atr = A_NORMAL; + dlg.dialog.atr = A_NORMAL; + dlg.title.atr = A_BOLD; + dlg.border.atr = A_NORMAL; + dlg.button_active.atr = A_REVERSE; + dlg.button_inactive.atr = A_DIM; + dlg.button_key_active.atr = A_REVERSE; + dlg.button_key_inactive.atr = A_BOLD; + dlg.button_label_active.atr = A_REVERSE; + dlg.button_label_inactive.atr = A_NORMAL; + dlg.inputbox.atr = A_NORMAL; + dlg.inputbox_border.atr = A_NORMAL; + dlg.searchbox.atr = A_NORMAL; + dlg.searchbox_title.atr = A_BOLD; + dlg.searchbox_border.atr = A_NORMAL; + dlg.position_indicator.atr = A_BOLD; + dlg.menubox.atr = A_NORMAL; + dlg.menubox_border.atr = A_NORMAL; + dlg.item.atr = A_NORMAL; + dlg.item_selected.atr = A_REVERSE; + dlg.tag.atr = A_BOLD; + dlg.tag_selected.atr = A_REVERSE; + dlg.tag_key.atr = A_BOLD; + dlg.tag_key_selected.atr = A_REVERSE; + dlg.check.atr = A_BOLD; + dlg.check_selected.atr = A_REVERSE; + dlg.uarrow.atr = A_BOLD; + dlg.darrow.atr = A_BOLD; +} + +#define DLG_COLOR(dialog, f, b, h) \ +do { \ + dlg.dialog.fg = (f); \ + dlg.dialog.bg = (b); \ + dlg.dialog.hl = (h); \ +} while (0) + +static void set_classic_theme(void) +{ + DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true); + DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true); + DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true); + DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false); + DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true); + DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true); + DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true); + DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true); + DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false); + DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true); + DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true); +} + +static void set_blackbg_theme(void) +{ + DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true); + DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false); + DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false); + DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false); + DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true); + DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false); + DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false); + + DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true); + DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false); + + DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true); + + DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false); + DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false); + + DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true); + DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true); + + DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false); + DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true); + + DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false); + DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false); +} + +static void set_bluetitle_theme(void) +{ + set_classic_theme(); + DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true); + DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true); + DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true); + DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true); + +} /* - * Attribute values, default is for mono display + * Select color theme */ -chtype attributes[] = { - A_NORMAL, /* screen_attr */ - A_NORMAL, /* shadow_attr */ - A_NORMAL, /* dialog_attr */ - A_BOLD, /* title_attr */ - A_NORMAL, /* border_attr */ - A_REVERSE, /* button_active_attr */ - A_DIM, /* button_inactive_attr */ - A_REVERSE, /* button_key_active_attr */ - A_BOLD, /* button_key_inactive_attr */ - A_REVERSE, /* button_label_active_attr */ - A_NORMAL, /* button_label_inactive_attr */ - A_NORMAL, /* inputbox_attr */ - A_NORMAL, /* inputbox_border_attr */ - A_NORMAL, /* searchbox_attr */ - A_BOLD, /* searchbox_title_attr */ - A_NORMAL, /* searchbox_border_attr */ - A_BOLD, /* position_indicator_attr */ - A_NORMAL, /* menubox_attr */ - A_NORMAL, /* menubox_border_attr */ - A_NORMAL, /* item_attr */ - A_REVERSE, /* item_selected_attr */ - A_BOLD, /* tag_attr */ - A_REVERSE, /* tag_selected_attr */ - A_BOLD, /* tag_key_attr */ - A_REVERSE, /* tag_key_selected_attr */ - A_BOLD, /* check_attr */ - A_REVERSE, /* check_selected_attr */ - A_BOLD, /* uarrow_attr */ - A_BOLD /* darrow_attr */ -}; - -#include "colors.h" +static int set_theme(const char *theme) +{ + int use_color = 1; + if (!theme) + set_bluetitle_theme(); + else if (strcmp(theme, "classic") == 0) + set_classic_theme(); + else if (strcmp(theme, "bluetitle") == 0) + set_bluetitle_theme(); + else if (strcmp(theme, "blackbg") == 0) + set_blackbg_theme(); + else if (strcmp(theme, "mono") == 0) + use_color = 0; + + return use_color; +} + +static void init_one_color(struct dialog_color *color) +{ + static int pair = 0; + + pair++; + init_pair(pair, color->fg, color->bg); + if (color->hl) + color->atr = A_BOLD | COLOR_PAIR(pair); + else + color->atr = COLOR_PAIR(pair); +} + +static void init_dialog_colors(void) +{ + init_one_color(&dlg.screen); + init_one_color(&dlg.shadow); + init_one_color(&dlg.dialog); + init_one_color(&dlg.title); + init_one_color(&dlg.border); + init_one_color(&dlg.button_active); + init_one_color(&dlg.button_inactive); + init_one_color(&dlg.button_key_active); + init_one_color(&dlg.button_key_inactive); + init_one_color(&dlg.button_label_active); + init_one_color(&dlg.button_label_inactive); + init_one_color(&dlg.inputbox); + init_one_color(&dlg.inputbox_border); + init_one_color(&dlg.searchbox); + init_one_color(&dlg.searchbox_title); + init_one_color(&dlg.searchbox_border); + init_one_color(&dlg.position_indicator); + init_one_color(&dlg.menubox); + init_one_color(&dlg.menubox_border); + init_one_color(&dlg.item); + init_one_color(&dlg.item_selected); + init_one_color(&dlg.tag); + init_one_color(&dlg.tag_selected); + init_one_color(&dlg.tag_key); + init_one_color(&dlg.tag_key_selected); + init_one_color(&dlg.check); + init_one_color(&dlg.check_selected); + init_one_color(&dlg.uarrow); + init_one_color(&dlg.darrow); +} /* - * Table of color values + * Setup for color display */ -int color_table[][3] = { - {SCREEN_FG, SCREEN_BG, SCREEN_HL}, - {SHADOW_FG, SHADOW_BG, SHADOW_HL}, - {DIALOG_FG, DIALOG_BG, DIALOG_HL}, - {TITLE_FG, TITLE_BG, TITLE_HL}, - {BORDER_FG, BORDER_BG, BORDER_HL}, - {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, - {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, - {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, - {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, - BUTTON_KEY_INACTIVE_HL}, - {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, - BUTTON_LABEL_ACTIVE_HL}, - {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, - BUTTON_LABEL_INACTIVE_HL}, - {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, - {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, - {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, - {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, - {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, - {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, - {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, - {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, - {ITEM_FG, ITEM_BG, ITEM_HL}, - {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, - {TAG_FG, TAG_BG, TAG_HL}, - {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, - {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, - {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, - {CHECK_FG, CHECK_BG, CHECK_HL}, - {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, - {UARROW_FG, UARROW_BG, UARROW_HL}, - {DARROW_FG, DARROW_BG, DARROW_HL}, -}; /* color_table */ +static void color_setup(const char *theme) +{ + if (set_theme(theme)) { + if (has_colors()) { /* Terminal supports color? */ + start_color(); + init_dialog_colors(); + } + } + else + { + set_mono_theme(); + } +} /* * Set window to attribute 'attr' @@ -119,13 +251,13 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr) void dialog_clear(void) { - attr_clear(stdscr, LINES, COLS, screen_attr); + attr_clear(stdscr, LINES, COLS, dlg.screen.atr); /* Display background title if it exists ... - SLH */ - if (backtitle != NULL) { + if (dlg.backtitle != NULL) { int i; - wattrset(stdscr, screen_attr); - mvwaddstr(stdscr, 0, 1, (char *)backtitle); + wattrset(stdscr, dlg.screen.atr); + mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); wmove(stdscr, 1, 1); for (i = 1; i < COLS - 1; i++) waddch(stdscr, ACS_HLINE); @@ -136,40 +268,22 @@ void dialog_clear(void) /* * Do some initialization for dialog */ -void init_dialog(void) +void init_dialog(const char *backtitle) +{ + dlg.backtitle = backtitle; + color_setup(getenv("MENUCONFIG_COLOR")); +} + +void reset_dialog(void) { initscr(); /* Init curses */ keypad(stdscr, TRUE); cbreak(); noecho(); - - if (use_colors) /* Set up colors */ - color_setup(); - dialog_clear(); } /* - * Setup for color display - */ -void color_setup(void) -{ - int i; - - if (has_colors()) { /* Terminal supports color? */ - start_color(); - - /* Initialize color pairs */ - for (i = 0; i < ATTRIBUTE_COUNT; i++) - init_pair(i + 1, color_table[i][0], color_table[i][1]); - - /* Setup color attributes */ - for (i = 0; i < ATTRIBUTE_COUNT; i++) - attributes[i] = C_ATTR(color_table[i][2], i + 1); - } -} - -/* * End using dialog functions. */ void end_dialog(void) @@ -184,7 +298,7 @@ void print_title(WINDOW *dialog, const char *title, int width) { if (title) { int tlen = MIN(width - 2, strlen(title)); - wattrset(dialog, title_attr); + wattrset(dialog, dlg.title.atr); mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' '); mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen); waddch(dialog, ' '); @@ -264,21 +378,23 @@ void print_button(WINDOW * win, const char *label, int y, int x, int selected) int i, temp; wmove(win, y, x); - wattrset(win, selected ? button_active_attr : button_inactive_attr); + wattrset(win, selected ? dlg.button_active.atr + : dlg.button_inactive.atr); waddstr(win, "<"); temp = strspn(label, " "); label += temp; - wattrset(win, selected ? button_label_active_attr - : button_label_inactive_attr); + wattrset(win, selected ? dlg.button_label_active.atr + : dlg.button_label_inactive.atr); for (i = 0; i < temp; i++) waddch(win, ' '); - wattrset(win, selected ? button_key_active_attr - : button_key_inactive_attr); + wattrset(win, selected ? dlg.button_key_active.atr + : dlg.button_key_inactive.atr); waddch(win, label[0]); - wattrset(win, selected ? button_label_active_attr - : button_label_inactive_attr); + wattrset(win, selected ? dlg.button_label_active.atr + : dlg.button_label_inactive.atr); waddstr(win, (char *)label + 1); - wattrset(win, selected ? button_active_attr : button_inactive_attr); + wattrset(win, selected ? dlg.button_active.atr + : dlg.button_inactive.atr); waddstr(win, ">"); wmove(win, y, x + temp + 1); } @@ -326,7 +442,7 @@ void draw_shadow(WINDOW * win, int y, int x, int height, int width) int i; if (has_colors()) { /* Whether terminal supports color? */ - wattrset(win, shadow_attr); + wattrset(win, dlg.shadow.atr); wmove(win, y + height, x + 2); for (i = 0; i < width; i++) waddch(win, winch(win) & A_CHARTEXT); @@ -360,3 +476,167 @@ int first_alpha(const char *string, const char *exempt) return 0; } + +/* + * ncurses uses ESC to detect escaped char sequences. This resutl in + * a small timeout before ESC is actually delivered to the application. + * lxdialog suggest <ESC> <ESC> which is correctly translated to two + * times esc. But then we need to ignore the second esc to avoid stepping + * out one menu too much. Filter away all escaped key sequences since + * keypad(FALSE) turn off ncurses support for escape sequences - and thats + * needed to make notimeout() do as expected. + */ +int on_key_esc(WINDOW *win) +{ + int key; + int key2; + int key3; + + nodelay(win, TRUE); + keypad(win, FALSE); + key = wgetch(win); + key2 = wgetch(win); + do { + key3 = wgetch(win); + } while (key3 != ERR); + nodelay(win, FALSE); + keypad(win, TRUE); + if (key == KEY_ESC && key2 == ERR) + return KEY_ESC; + else if (key != ERR && key != KEY_ESC && key2 == ERR) + ungetch(key); + + return -1; +} + +/* redraw screen in new size */ +int on_key_resize(void) +{ + dialog_clear(); + return KEY_RESIZE; +} + +struct dialog_list *item_cur; +struct dialog_list item_nil; +struct dialog_list *item_head; + +void item_reset(void) +{ + struct dialog_list *p, *next; + + for (p = item_head; p; p = next) { + next = p->next; + free(p); + } + item_head = NULL; + item_cur = &item_nil; +} + +void item_make(const char *fmt, ...) +{ + va_list ap; + struct dialog_list *p = malloc(sizeof(*p)); + + if (item_head) + item_cur->next = p; + else + item_head = p; + item_cur = p; + memset(p, 0, sizeof(*p)); + + va_start(ap, fmt); + vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap); + va_end(ap); +} + +void item_add_str(const char *fmt, ...) +{ + va_list ap; + size_t avail; + + avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); + + va_start(ap, fmt); + vsnprintf(item_cur->node.str + strlen(item_cur->node.str), + avail, fmt, ap); + item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0'; + va_end(ap); +} + +void item_set_tag(char tag) +{ + item_cur->node.tag = tag; +} +void item_set_data(void *ptr) +{ + item_cur->node.data = ptr; +} + +void item_set_selected(int val) +{ + item_cur->node.selected = val; +} + +int item_activate_selected(void) +{ + item_foreach() + if (item_is_selected()) + return 1; + return 0; +} + +void *item_data(void) +{ + return item_cur->node.data; +} + +char item_tag(void) +{ + return item_cur->node.tag; +} + +int item_count(void) +{ + int n = 0; + struct dialog_list *p; + + for (p = item_head; p; p = p->next) + n++; + return n; +} + +void item_set(int n) +{ + int i = 0; + item_foreach() + if (i++ == n) + return; +} + +int item_n(void) +{ + int n = 0; + struct dialog_list *p; + + for (p = item_head; p; p = p->next) { + if (p == item_cur) + return n; + n++; + } + return 0; +} + +const char *item_str(void) +{ + return item_cur->node.str; +} + +int item_is_selected(void) +{ + return (item_cur->node.selected != 0); +} + +int item_is_tag(char tag) +{ + return (item_cur->node.tag == tag); +} diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c index cb2568aae3ed..ee0a04e3e012 100644 --- a/scripts/kconfig/lxdialog/yesno.c +++ b/scripts/kconfig/lxdialog/yesno.c @@ -44,6 +44,12 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) int i, x, y, key = 0, button = 0; WINDOW *dialog; +do_resize: + if (getmaxy(stdscr) < (height + 4)) + return -ERRDISPLAYTOOSMALL; + if (getmaxx(stdscr) < (width + 4)) + return -ERRDISPLAYTOOSMALL; + /* center dialog box on screen */ x = (COLS - width) / 2; y = (LINES - height) / 2; @@ -53,22 +59,23 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) dialog = newwin(height, width, y, x); keypad(dialog, TRUE); - draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); - wattrset(dialog, border_attr); + draw_box(dialog, 0, 0, height, width, + dlg.dialog.atr, dlg.border.atr); + wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); - wattrset(dialog, dialog_attr); + wattrset(dialog, dlg.dialog.atr); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); - wattrset(dialog, dialog_attr); + wattrset(dialog, dlg.dialog.atr); print_autowrap(dialog, prompt, width - 2, 1, 3); print_buttons(dialog, height, width, 0); - while (key != ESC) { + while (key != KEY_ESC) { key = wgetch(dialog); switch (key) { case 'Y': @@ -92,11 +99,16 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) case '\n': delwin(dialog); return button; - case ESC: + case KEY_ESC: + key = on_key_esc(dialog); break; + case KEY_RESIZE: + delwin(dialog); + on_key_resize(); + goto do_resize; } } delwin(dialog); - return -1; /* ESC pressed */ + return key; /* ESC pressed */ } diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 7f973195e79a..08a4c7af93ea 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -24,6 +24,7 @@ #define LKC_DIRECT_LINK #include "lkc.h" +#include "lxdialog/dialog.h" static char menu_backtitle[128]; static const char mconf_readme[] = N_( @@ -159,7 +160,21 @@ static const char mconf_readme[] = N_( "\n" "Note that this mode can eventually be a little more CPU expensive\n" "(especially with a larger number of unrolled categories) than the\n" -"default mode.\n"), +"default mode.\n" +"\n" +"Different color themes available\n" +"--------------------------------\n" +"It is possible to select different color themes using the variable\n" +"MENUCONFIG_COLOR. To select a theme use:\n" +"\n" +"make MENUCONFIG_COLOR=<theme> menuconfig\n" +"\n" +"Available themes are\n" +" mono => selects colors suitable for monochrome displays\n" +" blackbg => selects a color scheme with black background\n" +" classic => theme with blue background. The classic look\n" +" bluetitle => a LCD friendly version of classic. (default)\n" +"\n"), menu_instructions[] = N_( "Arrow keys navigate the menu. " "<Enter> selects submenus --->. " @@ -256,16 +271,12 @@ search_help[] = N_( " USB$ => find all CONFIG_ symbols ending with USB\n" "\n"); -static char buf[4096], *bufptr = buf; -static char input_buf[4096]; static char filename[PATH_MAX+1] = ".config"; -static char *args[1024], **argptr = args; static int indent; static struct termios ios_org; static int rows = 0, cols = 0; static struct menu *current_menu; static int child_count; -static int do_resize; static int single_menu_mode; static void conf(struct menu *menu); @@ -276,12 +287,6 @@ static void conf_save(void); static void show_textbox(const char *title, const char *text, int r, int c); static void show_helptext(const char *title, const char *text); static void show_help(struct menu *menu); -static void show_file(const char *filename, const char *title, int r, int c); - -static void cprint_init(void); -static int cprint1(const char *fmt, ...); -static void cprint_done(void); -static int cprint(const char *fmt, ...); static void init_wsize(void) { @@ -318,54 +323,6 @@ static void init_wsize(void) cols -= 5; } -static void cprint_init(void) -{ - bufptr = buf; - argptr = args; - memset(args, 0, sizeof(args)); - indent = 0; - child_count = 0; - cprint("./scripts/kconfig/lxdialog/lxdialog"); - cprint("--backtitle"); - cprint(menu_backtitle); -} - -static int cprint1(const char *fmt, ...) -{ - va_list ap; - int res; - - if (!*argptr) - *argptr = bufptr; - va_start(ap, fmt); - res = vsprintf(bufptr, fmt, ap); - va_end(ap); - bufptr += res; - - return res; -} - -static void cprint_done(void) -{ - *bufptr++ = 0; - argptr++; -} - -static int cprint(const char *fmt, ...) -{ - va_list ap; - int res; - - *argptr++ = bufptr; - va_start(ap, fmt); - res = vsprintf(bufptr, fmt, ap); - va_end(ap); - bufptr += res; - *bufptr++ = 0; - - return res; -} - static void get_prompt_str(struct gstr *r, struct property *prop) { int i, j; @@ -438,108 +395,17 @@ static struct gstr get_relations_str(struct symbol **sym_arr) return res; } -pid_t pid; - -static void winch_handler(int sig) -{ - if (!do_resize) { - kill(pid, SIGINT); - do_resize = 1; - } -} - -static int exec_conf(void) -{ - int pipefd[2], stat, size; - struct sigaction sa; - sigset_t sset, osset; - - sigemptyset(&sset); - sigaddset(&sset, SIGINT); - sigprocmask(SIG_BLOCK, &sset, &osset); - - signal(SIGINT, SIG_DFL); - - sa.sa_handler = winch_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sigaction(SIGWINCH, &sa, NULL); - - *argptr++ = NULL; - - pipe(pipefd); - pid = fork(); - if (pid == 0) { - sigprocmask(SIG_SETMASK, &osset, NULL); - dup2(pipefd[1], 2); - close(pipefd[0]); - close(pipefd[1]); - execv(args[0], args); - _exit(EXIT_FAILURE); - } - - close(pipefd[1]); - bufptr = input_buf; - while (1) { - size = input_buf + sizeof(input_buf) - bufptr; - size = read(pipefd[0], bufptr, size); - if (size <= 0) { - if (size < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - perror("read"); - } - break; - } - bufptr += size; - } - *bufptr++ = 0; - close(pipefd[0]); - waitpid(pid, &stat, 0); - - if (do_resize) { - init_wsize(); - do_resize = 0; - sigprocmask(SIG_SETMASK, &osset, NULL); - return -1; - } - if (WIFSIGNALED(stat)) { - printf("\finterrupted(%d)\n", WTERMSIG(stat)); - exit(1); - } -#if 0 - printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf); - sleep(1); -#endif - sigpending(&sset); - if (sigismember(&sset, SIGINT)) { - printf("\finterrupted\n"); - exit(1); - } - sigprocmask(SIG_SETMASK, &osset, NULL); - - return WEXITSTATUS(stat); -} - static void search_conf(void) { struct symbol **sym_arr; - int stat; struct gstr res; - + int dres; again: - cprint_init(); - cprint("--title"); - cprint(_("Search Configuration Parameter")); - cprint("--inputbox"); - cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)")); - cprint("10"); - cprint("75"); - cprint(""); - stat = exec_conf(); - if (stat < 0) - goto again; - switch (stat) { + dialog_clear(); + dres = dialog_inputbox(_("Search Configuration Parameter"), + _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"), + 10, 75, ""); + switch (dres) { case 0: break; case 1: @@ -549,7 +415,7 @@ again: return; } - sym_arr = sym_re_search(input_buf); + sym_arr = sym_re_search(dialog_input_result); res = get_relations_str(sym_arr); free(sym_arr); show_textbox(_("Search Results"), str_get(&res), 0, 0); @@ -576,24 +442,24 @@ static void build_conf(struct menu *menu) switch (prop->type) { case P_MENU: child_count++; - cprint("m%p", menu); - if (single_menu_mode) { - cprint1("%s%*c%s", - menu->data ? "-->" : "++>", - indent + 1, ' ', prompt); + item_make("%s%*c%s", + menu->data ? "-->" : "++>", + indent + 1, ' ', prompt); } else - cprint1(" %*c%s --->", indent + 1, ' ', prompt); + item_make(" %*c%s --->", indent + 1, ' ', prompt); - cprint_done(); + item_set_tag('m'); + item_set_data(menu); if (single_menu_mode && menu->data) goto conf_childs; return; default: if (prompt) { child_count++; - cprint(":%p", menu); - cprint("---%*c%s", indent + 1, ' ', prompt); + item_make("---%*c%s", indent + 1, ' ', prompt); + item_set_tag(':'); + item_set_data(menu); } } } else @@ -614,10 +480,9 @@ static void build_conf(struct menu *menu) val = sym_get_tristate_value(sym); if (sym_is_changable(sym)) { - cprint("t%p", menu); switch (type) { case S_BOOLEAN: - cprint1("[%c]", val == no ? ' ' : '*'); + item_make("[%c]", val == no ? ' ' : '*'); break; case S_TRISTATE: switch (val) { @@ -625,84 +490,87 @@ static void build_conf(struct menu *menu) case mod: ch = 'M'; break; default: ch = ' '; break; } - cprint1("<%c>", ch); + item_make("<%c>", ch); break; } + item_set_tag('t'); + item_set_data(menu); } else { - cprint("%c%p", def_menu ? 't' : ':', menu); - cprint1(" "); + item_make(" "); + item_set_tag(def_menu ? 't' : ':'); + item_set_data(menu); } - cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); if (val == yes) { if (def_menu) { - cprint1(" (%s)", menu_get_prompt(def_menu)); - cprint1(" --->"); - cprint_done(); + item_add_str(" (%s)", menu_get_prompt(def_menu)); + item_add_str(" --->"); if (def_menu->list) { indent += 2; build_conf(def_menu); indent -= 2; } - } else - cprint_done(); + } return; } - cprint_done(); } else { if (menu == current_menu) { - cprint(":%p", menu); - cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + item_set_tag(':'); + item_set_data(menu); goto conf_childs; } child_count++; val = sym_get_tristate_value(sym); if (sym_is_choice_value(sym) && val == yes) { - cprint(":%p", menu); - cprint1(" "); + item_make(" "); + item_set_tag(':'); + item_set_data(menu); } else { switch (type) { case S_BOOLEAN: - cprint("t%p", menu); if (sym_is_changable(sym)) - cprint1("[%c]", val == no ? ' ' : '*'); + item_make("[%c]", val == no ? ' ' : '*'); else - cprint1("---"); + item_make("---"); + item_set_tag('t'); + item_set_data(menu); break; case S_TRISTATE: - cprint("t%p", menu); switch (val) { case yes: ch = '*'; break; case mod: ch = 'M'; break; default: ch = ' '; break; } if (sym_is_changable(sym)) - cprint1("<%c>", ch); + item_make("<%c>", ch); else - cprint1("---"); + item_make("---"); + item_set_tag('t'); + item_set_data(menu); break; default: - cprint("s%p", menu); - tmp = cprint1("(%s)", sym_get_string_value(sym)); + tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ + item_make("(%s)", sym_get_string_value(sym)); tmp = indent - tmp + 4; if (tmp < 0) tmp = 0; - cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : " (NEW)"); - cprint_done(); + item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + item_set_tag('s'); + item_set_data(menu); goto conf_childs; } } - cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? - "" : " (NEW)"); + item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); if (menu->prompt->type == P_MENU) { - cprint1(" --->"); - cprint_done(); + item_add_str(" --->"); return; } - cprint_done(); } conf_childs: @@ -717,59 +585,45 @@ static void conf(struct menu *menu) struct menu *submenu; const char *prompt = menu_get_prompt(menu); struct symbol *sym; - char active_entry[40]; - int stat, type, i; + struct menu *active_menu = NULL; + int res; + int s_scroll = 0; - unlink("lxdialog.scrltmp"); - active_entry[0] = 0; while (1) { - cprint_init(); - cprint("--title"); - cprint("%s", prompt ? prompt : _("Main Menu")); - cprint("--menu"); - cprint(_(menu_instructions)); - cprint("%d", rows); - cprint("%d", cols); - cprint("%d", rows - 10); - cprint("%s", active_entry); + item_reset(); current_menu = menu; build_conf(menu); if (!child_count) break; if (menu == &rootmenu) { - cprint(":"); - cprint("--- "); - cprint("L"); - cprint(_(" Load an Alternate Configuration File")); - cprint("S"); - cprint(_(" Save Configuration to an Alternate File")); + item_make("--- "); + item_set_tag(':'); + item_make(_(" Load an Alternate Configuration File")); + item_set_tag('L'); + item_make(_(" Save an Alternate Configuration File")); + item_set_tag('S'); } - stat = exec_conf(); - if (stat < 0) - continue; - - if (stat == 1 || stat == 255) + dialog_clear(); + res = dialog_menu(prompt ? prompt : _("Main Menu"), + _(menu_instructions), + active_menu, &s_scroll); + if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) break; - - type = input_buf[0]; - if (!type) + if (!item_activate_selected()) + continue; + if (!item_tag()) continue; - for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++) - ; - if (i >= sizeof(active_entry)) - i = sizeof(active_entry) - 1; - input_buf[i] = 0; - strcpy(active_entry, input_buf); - - sym = NULL; - submenu = NULL; - if (sscanf(input_buf + 1, "%p", &submenu) == 1) + submenu = item_data(); + active_menu = item_data(); + if (submenu) sym = submenu->sym; + else + sym = NULL; - switch (stat) { + switch (res) { case 0: - switch (type) { + switch (item_tag()) { case 'm': if (single_menu_mode) submenu->data = (void *) (long) !submenu->data; @@ -800,7 +654,7 @@ static void conf(struct menu *menu) show_helptext("README", _(mconf_readme)); break; case 3: - if (type == 't') { + if (item_is_tag('t')) { if (sym_set_tristate_value(sym, yes)) break; if (sym_set_tristate_value(sym, mod)) @@ -808,17 +662,17 @@ static void conf(struct menu *menu) } break; case 4: - if (type == 't') + if (item_is_tag('t')) sym_set_tristate_value(sym, no); break; case 5: - if (type == 't') + if (item_is_tag('t')) sym_set_tristate_value(sym, mod); break; case 6: - if (type == 't') + if (item_is_tag('t')) sym_toggle_tristate_value(sym); - else if (type == 'm') + else if (item_is_tag('m')) conf(submenu); break; case 7: @@ -830,13 +684,8 @@ static void conf(struct menu *menu) static void show_textbox(const char *title, const char *text, int r, int c) { - int fd; - - fd = creat(".help.tmp", 0777); - write(fd, text, strlen(text)); - close(fd); - show_file(".help.tmp", title, r, c); - unlink(".help.tmp"); + dialog_clear(); + dialog_textbox(title, text, r, c); } static void show_helptext(const char *title, const char *text) @@ -864,68 +713,52 @@ static void show_help(struct menu *menu) str_free(&help); } -static void show_file(const char *filename, const char *title, int r, int c) -{ - do { - cprint_init(); - if (title) { - cprint("--title"); - cprint("%s", title); - } - cprint("--textbox"); - cprint("%s", filename); - cprint("%d", r ? r : rows); - cprint("%d", c ? c : cols); - } while (exec_conf() < 0); -} - static void conf_choice(struct menu *menu) { const char *prompt = menu_get_prompt(menu); struct menu *child; struct symbol *active; - int stat; active = sym_get_choice_value(menu->sym); while (1) { - cprint_init(); - cprint("--title"); - cprint("%s", prompt ? prompt : _("Main Menu")); - cprint("--radiolist"); - cprint(_(radiolist_instructions)); - cprint("15"); - cprint("70"); - cprint("6"); + int res; + int selected; + item_reset(); current_menu = menu; for (child = menu->list; child; child = child->next) { if (!menu_is_visible(child)) continue; - cprint("%p", child); - cprint("%s", menu_get_prompt(child)); + item_make("%s", menu_get_prompt(child)); + item_set_data(child); + if (child->sym == active) + item_set_selected(1); if (child->sym == sym_get_choice_value(menu->sym)) - cprint("ON"); - else if (child->sym == active) - cprint("SELECTED"); - else - cprint("OFF"); + item_set_tag('X'); } - - stat = exec_conf(); - switch (stat) { + dialog_clear(); + res = dialog_checklist(prompt ? prompt : _("Main Menu"), + _(radiolist_instructions), + 15, 70, 6); + selected = item_activate_selected(); + switch (res) { case 0: - if (sscanf(input_buf, "%p", &child) != 1) - break; - sym_set_tristate_value(child->sym, yes); + if (selected) { + child = item_data(); + sym_set_tristate_value(child->sym, yes); + } return; case 1: - if (sscanf(input_buf, "%p", &child) == 1) { + if (selected) { + child = item_data(); show_help(child); active = child->sym; } else show_help(menu); break; - case 255: + case KEY_ESC: + return; + case -ERRDISPLAYTOOSMALL: return; } } @@ -934,40 +767,38 @@ static void conf_choice(struct menu *menu) static void conf_string(struct menu *menu) { const char *prompt = menu_get_prompt(menu); - int stat; while (1) { - cprint_init(); - cprint("--title"); - cprint("%s", prompt ? prompt : _("Main Menu")); - cprint("--inputbox"); + int res; + char *heading; + switch (sym_get_type(menu->sym)) { case S_INT: - cprint(_(inputbox_instructions_int)); + heading = _(inputbox_instructions_int); break; case S_HEX: - cprint(_(inputbox_instructions_hex)); + heading = _(inputbox_instructions_hex); break; case S_STRING: - cprint(_(inputbox_instructions_string)); + heading = _(inputbox_instructions_string); break; default: - /* panic? */; + heading = "Internal mconf error!"; } - cprint("10"); - cprint("75"); - cprint("%s", sym_get_string_value(menu->sym)); - stat = exec_conf(); - switch (stat) { + dialog_clear(); + res = dialog_inputbox(prompt ? prompt : _("Main Menu"), + heading, 10, 75, + sym_get_string_value(menu->sym)); + switch (res) { case 0: - if (sym_set_string_value(menu->sym, input_buf)) + if (sym_set_string_value(menu->sym, dialog_input_result)) return; show_textbox(NULL, _("You have made an invalid entry."), 5, 43); break; case 1: show_help(menu); break; - case 255: + case KEY_ESC: return; } } @@ -975,28 +806,24 @@ static void conf_string(struct menu *menu) static void conf_load(void) { - int stat; while (1) { - cprint_init(); - cprint("--inputbox"); - cprint(load_config_text); - cprint("11"); - cprint("55"); - cprint("%s", filename); - stat = exec_conf(); - switch(stat) { + int res; + dialog_clear(); + res = dialog_inputbox(NULL, load_config_text, + 11, 55, filename); + switch(res) { case 0: - if (!input_buf[0]) + if (!dialog_input_result[0]) return; - if (!conf_read(input_buf)) + if (!conf_read(dialog_input_result)) return; show_textbox(NULL, _("File does not exist!"), 5, 38); break; case 1: show_helptext(_("Load Alternate Configuration"), load_config_help); break; - case 255: + case KEY_ESC: return; } } @@ -1004,28 +831,23 @@ static void conf_load(void) static void conf_save(void) { - int stat; - while (1) { - cprint_init(); - cprint("--inputbox"); - cprint(save_config_text); - cprint("11"); - cprint("55"); - cprint("%s", filename); - stat = exec_conf(); - switch(stat) { + int res; + dialog_clear(); + res = dialog_inputbox(NULL, save_config_text, + 11, 55, filename); + switch(res) { case 0: - if (!input_buf[0]) + if (!dialog_input_result[0]) return; - if (!conf_write(input_buf)) + if (!conf_write(dialog_input_result)) return; show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); break; case 1: show_helptext(_("Save Alternate Configuration"), save_config_help); break; - case 255: + case KEY_ESC: return; } } @@ -1034,15 +856,13 @@ static void conf_save(void) static void conf_cleanup(void) { tcsetattr(1, TCSAFLUSH, &ios_org); - unlink(".help.tmp"); - unlink("lxdialog.scrltmp"); } int main(int ac, char **av) { struct symbol *sym; char *mode; - int stat; + int res; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -1065,18 +885,19 @@ int main(int ac, char **av) tcgetattr(1, &ios_org); atexit(conf_cleanup); init_wsize(); - conf(&rootmenu); - + reset_dialog(); + init_dialog(menu_backtitle); do { - cprint_init(); - cprint("--yesno"); - cprint(_("Do you wish to save your new kernel configuration?")); - cprint("5"); - cprint("60"); - stat = exec_conf(); - } while (stat < 0); - - if (stat == 0) { + conf(&rootmenu); + dialog_clear(); + res = dialog_yesno(NULL, + _("Do you wish to save your " + "new kernel configuration?\n" + "<ESC><ESC> to continue."), + 6, 60); + } while (res == KEY_ESC); + end_dialog(); + if (res == 0) { if (conf_write(NULL)) { fprintf(stderr, _("\n\n" "Error during writing of the kernel configuration.\n" |