* [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
@ 2006-07-27 20:27 Sam Ravnborg
2006-07-28 14:09 ` Roman Zippel
0 siblings, 1 reply; 8+ messages in thread
From: Sam Ravnborg @ 2006-07-27 20:27 UTC (permalink / raw)
To: LKML, Roman Zippel, Petr Baudis
Dedided to take another stamp on an old TODO item of making lxdialog
a built-in. Following patch is first step to do so.
The patch makes it a built-in - but with two open issues that I yet
have to address.
It is loosly based on a patch from Petr Baudis <pasky@suse.cz>:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0211.2/1978.html
The diffstat tells a nice story even if you ignore the three deleted
files. (lxdialog.c msgbox.c and lxdialog/Makefile).
I will not claim that the lxdialog files became readable by this but
they are now less unreadable compared to before.
Comments welcome of course.
I will during the weekend try to address the resize issue.
The double ESC ESC thing I dunno how to fix.
Sam
>From 34a1fd9aa089e814e8ba3e0a99ac9bd10d220032 Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@mars.ravnborg.org>
Date: Thu, 27 Jul 2006 22:10:27 +0200
Subject: [PATCH] kconfig/menuconfig: lxdialog is now built-in
lxdialog was previously called as an external program causing screen
to flicker when used. With this patch lxdialog is now built-in.
It is loosly based om previous work by: Petr Baudis <pasky@ucw.cz>
Following is a list of changes:
o Moved build of dialog routings to kconfig Makefile
o menubox + checklist uses a new item list to hold all menu items
o in util.c implmented helper function to deal with item list
o menubox now uses parameters to save scroll state (avoids temp file)
o textbox now get text to be displayed as parameter and not a file
o make sure to properly delete subwin's before main windows
o killed unused files: lxdialog.c msgbox.c
o modified return value for ESC to match direct calling
o in a few places the code has been adjusted to 80 char wide
o in textbox a small refactoring was made to make code remotely readable
o in mconf removed all unused stuff (functions/variables)
Following is a list of know short comings:
a) pressing ESC twice will be interpreted as two ESC presses
b) resize does not work. menuconfig needs to be restarted to be adjusted
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
scripts/kconfig/Makefile | 23 +-
scripts/kconfig/lxdialog/Makefile | 21 -
scripts/kconfig/lxdialog/checklist.c | 136 ++++------
scripts/kconfig/lxdialog/dialog.h | 50 +++-
scripts/kconfig/lxdialog/inputbox.c | 2
scripts/kconfig/lxdialog/lxdialog.c | 204 --------------
| 95 +++----
scripts/kconfig/lxdialog/msgbox.c | 72 -----
scripts/kconfig/lxdialog/textbox.c | 298 +++++----------------
scripts/kconfig/lxdialog/util.c | 133 +++++++++
scripts/kconfig/lxdialog/yesno.c | 2
scripts/kconfig/mconf.c | 480 ++++++++++------------------------
12 files changed, 499 insertions(+), 1017 deletions(-)
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index e6499db..6cf45fa 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
@@ -80,6 +79,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
@@ -91,9 +107,12 @@ # gconf: Used for the gconfig target
# Based on GTK which needs to be installed to compile it
# object files used by all kconfig flavours
+lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
+lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
+
hostprogs-y := conf mconf qconf gconf kxgettext
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
ifeq ($(MAKECMDGOALS),xconfig)
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
deleted file mode 100644
index a8b0263..0000000
--- 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 b90e888..2825110 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -28,8 +28,7 @@ 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;
@@ -42,12 +41,12 @@ static void print_item(WINDOW * win, con
wmove(win, choice, check_x);
wattrset(win, selected ? dlg.check_selected.atr
: dlg.check.atr);
- wprintw(win, "(%c)", status ? 'X' : ' ');
+ wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
- mvwaddch(win, choice, item_x, item[0]);
+ mvwaddch(win, choice, item_x, item_str()[0]);
wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
- waddstr(win, (char *)item + 1);
+ waddstr(win, (char *)item_str() + 1);
if (selected) {
wmove(win, choice, check_x + 1);
wrefresh(win);
@@ -110,32 +109,23 @@ static void print_buttons(WINDOW * dialo
* 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);
- }
-
- /* 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;
+ /* which item to highlight */
+ item_foreach() {
+ if (item_is_tag('X'))
+ choice = item_n();
+ if (item_is_selected()) {
+ choice = item_n();
+ break;
+ }
}
- if (choice)
- choice--;
- max_choice = MIN(list_height, item_no);
+ max_choice = MIN(list_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -176,8 +166,8 @@ int dialog_checklist(const char *title,
/* 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;
@@ -189,14 +179,11 @@ int dialog_checklist(const char *title,
/* 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);
@@ -208,10 +195,11 @@ int dialog_checklist(const char *title,
while (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 == '-') {
@@ -222,15 +210,16 @@ int dialog_checklist(const char *title,
/* 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);
@@ -241,23 +230,24 @@ int dialog_checklist(const char *title,
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);
@@ -269,12 +259,12 @@ int dialog_checklist(const char *title,
}
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);
}
@@ -284,10 +274,19 @@ int dialog_checklist(const char *title,
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:
@@ -297,30 +296,6 @@ int dialog_checklist(const char *title,
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;
@@ -331,8 +306,7 @@ int dialog_checklist(const char *title,
/* Now, update everything... */
doupdate();
}
-
+ delwin(list);
delwin(dialog);
- free(status);
- return -1; /* ESC pressed */
+ return 255; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index 2f4c19d..dd25ca7 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -133,11 +133,53 @@ struct dialog_info {
* Global variables
*/
extern struct dialog_info dlg;
+extern char dialog_input_result[];
/*
* Function prototypes
*/
-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_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_cur; item_cur = item_cur->next)
+
+
+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);
@@ -154,11 +196,9 @@ int dialog_msgbox(const char *title, con
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 menu_height, 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 f75b51f..9c53098 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -222,5 +222,5 @@ int dialog_inputbox(const char *title, c
}
delwin(dialog);
- return -1; /* ESC pressed */
+ return 255; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c
deleted file mode 100644
index c264e02..0000000
--- 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 (dlg.backtitle != NULL) {
- Usage(argv[0]);
- exit(-1);
- } else {
- dlg.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, dlg.screen.atr);
- 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);
-}
--git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index ff991db..f39ae29 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -99,10 +99,10 @@ #endif
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)
/*
@@ -180,16 +180,14 @@ static void do_scroll(WINDOW *win, int *
* 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 menu_height, const void *selected, int *s_scroll)
{
int i, j, x, y, box_x, box_y;
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);
+ max_choice = MIN(menu_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -231,28 +229,21 @@ int dialog_menu(const char *title, const
item_x = (menu_width - 70) / 2;
/* 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;
@@ -265,7 +256,7 @@ int dialog_menu(const char *title, const
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);
@@ -282,14 +273,16 @@ int dialog_menu(const char *title, const
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;
}
}
@@ -314,7 +307,7 @@ int dialog_menu(const char *title, const
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);
@@ -337,7 +330,7 @@ int dialog_menu(const char *title, const
} 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);
@@ -351,7 +344,7 @@ int dialog_menu(const char *title, const
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);
@@ -377,12 +370,11 @@ int dialog_menu(const char *title, const
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;
@@ -402,17 +394,11 @@ int dialog_menu(const char *title, const
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':
@@ -421,8 +407,7 @@ int dialog_menu(const char *title, const
break;
}
}
-
+ delwin(menu);
delwin(dialog);
- remove("lxdialog.scrltmp");
- return -1; /* ESC pressed */
+ return 255; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
deleted file mode 100644
index 236759f..0000000
--- a/scripts/kconfig/lxdialog/msgbox.c
+++ /dev/null
@@ -1,72 +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,
- dlg.dialog.atr, dlg.border.atr);
-
- print_title(dialog, title, width);
-
- wattrset(dialog, dlg.dialog.atr);
- print_autowrap(dialog, prompt, width - 2, 1, 2);
-
- if (pause) {
- 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, dlg.dialog.atr);
- 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 336793b..b28f8aa 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -27,54 +27,27 @@ static void print_line(WINDOW * win, int
static char *get_line(void);
static void print_position(WINDOW * win, int height, int width);
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
+static int hscroll;
+static int begin_reached, end_reached, page_length;
+static const char *buf;
+static const char *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 height, int width)
{
- int i, x, y, cur_x, cur_y, fpos, key = 0;
+ int i, x, y, cur_x, cur_y, key = 0;
+ int texth, textw;
int passed_end;
- char search_term[MAX_LEN + 1];
WINDOW *dialog, *text;
- search_term[0] = '\0'; /* no search term entered yet */
-
- /* 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 */
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -86,7 +59,9 @@ int dialog_textbox(const char *title, co
keypad(dialog, TRUE);
/* Create window for text region, used for scrolling text */
- text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
+ texth = height - 4;
+ textw = width - 2;
+ text = subwin(dialog, texth, textw, y + 1, x + 1);
wattrset(text, dlg.dialog.atr);
wbkgdset(text, dlg.dialog.atr & A_COLOR);
@@ -111,8 +86,8 @@ int dialog_textbox(const char *title, co
getyx(dialog, cur_y, cur_x); /* Save cursor position */
/* Print first page of text */
- attr_clear(text, height - 4, width - 2, dlg.dialog.atr);
- print_page(text, height - 4, width - 2);
+ attr_clear(text, texth, textw, dlg.dialog.atr);
+ print_page(text, texth, textw);
print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
@@ -124,37 +99,15 @@ int dialog_textbox(const char *title, co
case 'e':
case 'X':
case 'x':
+ delwin(text);
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_page(text, texth, textw);
print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
@@ -164,29 +117,10 @@ int dialog_textbox(const char *title, co
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);
+ /* point to last char in buf */
+ page = buf + strlen(buf);
+ back_lines(texth);
+ print_page(text, texth, textw);
print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
@@ -197,20 +131,22 @@ int dialog_textbox(const char *title, co
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. */
+ /* 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);
page_length = 0;
passed_end = 0;
- for (i = 0; i < height - 4; i++) {
+ for (i = 0; i < texth; i++) {
if (!i) {
/* print first line of page */
- print_line(text, 0, width - 2);
+ print_line(text, 0, textw);
wnoutrefresh(text);
} else
/* Called to update 'end_reached' and 'page' */
@@ -231,8 +167,8 @@ int dialog_textbox(const char *title, co
case KEY_PPAGE:
if (begin_reached)
break;
- back_lines(page_length + height - 4);
- print_page(text, height - 4, width - 2);
+ back_lines(page_length + texth);
+ print_page(text, texth, textw);
print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x);
wrefresh(dialog);
@@ -245,7 +181,7 @@ int dialog_textbox(const char *title, co
scrollok(text, TRUE);
scroll(text); /* Scroll text region up one line */
scrollok(text, FALSE);
- print_line(text, height - 5, width - 2);
+ print_line(text, texth - 1, textw);
wnoutrefresh(text);
print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
@@ -258,7 +194,7 @@ int dialog_textbox(const char *title, co
break;
begin_reached = 0;
- print_page(text, height - 4, width - 2);
+ print_page(text, texth, textw);
print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x);
wrefresh(dialog);
@@ -276,7 +212,7 @@ int dialog_textbox(const char *title, co
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- print_page(text, height - 4, width - 2);
+ print_page(text, texth, textw);
wmove(dialog, cur_y, cur_x);
wrefresh(dialog);
break;
@@ -288,7 +224,7 @@ int dialog_textbox(const char *title, co
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- print_page(text, height - 4, width - 2);
+ print_page(text, texth, textw);
wmove(dialog, cur_y, cur_x);
wrefresh(dialog);
break;
@@ -296,123 +232,42 @@ int dialog_textbox(const char *title, co
break;
}
}
-
+ delwin(text);
delwin(dialog);
- free(buf);
- close(fd);
- return -1; /* ESC pressed */
+ return 255; /* 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++;
+ }
}
/*
@@ -467,33 +322,14 @@ #endif
*/
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)
@@ -518,17 +354,11 @@ static char *get_line(void)
*/
static void print_position(WINDOW * win, int height, int width)
{
- 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, dlg.position_indicator.atr);
wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
- percent = !file_size ?
- 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
+ percent = (page - buf) * 100 / strlen(buf);
wmove(win, height - 3, width - 9);
wprintw(win, "(%3d%%)", percent);
}
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index e73a36d..d9a056a 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -268,13 +268,18 @@ 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();
- color_setup(getenv("MENUCONFIG_COLOR"));
dialog_clear();
}
@@ -471,3 +476,127 @@ int first_alpha(const char *string, cons
return 0;
}
+
+struct dialog_list *item_cur;
+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 = NULL;
+}
+
+void item_make(const char *fmt, ...)
+{
+ va_list ap;
+ struct dialog_list *p = malloc(sizeof(*p));
+
+ if (item_cur)
+ 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 e938037..9fc2449 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -99,5 +99,5 @@ int dialog_yesno(const char *title, cons
}
delwin(dialog);
- return -1; /* ESC pressed */
+ return 255; /* ESC pressed */
}
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 5992673..54464e6 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -24,6 +24,7 @@ #include <locale.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
+#include "lxdialog/dialog.h"
static char menu_backtitle[128];
static const char mconf_readme[] = N_(
@@ -270,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);
@@ -290,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)
{
@@ -332,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;
@@ -452,108 +395,17 @@ static struct gstr get_relations_str(str
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) {
+ reset_dialog();
+ dres = dialog_inputbox(_("Search Configuration Parameter"),
+ _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
+ 10, 75, "");
+ switch (dres) {
case 0:
break;
case 1:
@@ -563,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);
@@ -590,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
@@ -628,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) {
@@ -639,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:
@@ -731,59 +585,43 @@ 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)
+ reset_dialog();
+ res = dialog_menu(prompt ? prompt : _("Main Menu"),
+ _(menu_instructions),
+ rows, cols, rows - 10,
+ active_menu, &s_scroll);
+ if (res == 1 || res == 255)
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)
- sym = submenu->sym;
+ submenu = item_data();
+ active_menu = item_data();
+ sym = submenu->sym;
- switch (stat) {
+ switch (res) {
case 0:
- switch (type) {
+ switch (item_tag()) {
case 'm':
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
@@ -814,7 +652,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))
@@ -822,17 +660,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:
@@ -844,13 +682,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");
+ reset_dialog();
+ dialog_textbox(title, text, r ? r : rows, c ? c : cols);
}
static void show_helptext(const char *title, const char *text)
@@ -878,62 +711,44 @@ 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) {
+ reset_dialog();
+ 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
@@ -948,33 +763,31 @@ static void conf_choice(struct menu *men
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) {
+ reset_dialog();
+ 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;
@@ -989,21 +802,17 @@ static void conf_string(struct menu *men
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;
+ reset_dialog();
+ 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;
@@ -1018,21 +827,16 @@ 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;
+ reset_dialog();
+ 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;
@@ -1056,7 +860,7 @@ int main(int ac, char **av)
{
struct symbol *sym;
char *mode;
- int stat;
+ int res;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1079,18 +883,16 @@ int main(int ac, char **av)
tcgetattr(1, &ios_org);
atexit(conf_cleanup);
init_wsize();
+ reset_dialog();
+ init_dialog(menu_backtitle);
conf(&rootmenu);
-
- 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) {
+ reset_dialog();
+ res = dialog_yesno(NULL,
+ _("Do you wish to save your "
+ "new kernel configuration?"),
+ 5, 60);
+ end_dialog();
+ if (res == 0) {
if (conf_write(NULL)) {
fprintf(stderr, _("\n\n"
"Error during writing of the kernel configuration.\n"
--
1.4.1.rc2.gfc04
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
2006-07-27 20:27 [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in Sam Ravnborg
@ 2006-07-28 14:09 ` Roman Zippel
2006-07-28 14:59 ` Sam Ravnborg
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Roman Zippel @ 2006-07-28 14:09 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: LKML, Petr Baudis
Hi,
On Thu, 27 Jul 2006, Sam Ravnborg wrote:
> Dedided to take another stamp on an old TODO item of making lxdialog
> a built-in. Following patch is first step to do so.
> The patch makes it a built-in - but with two open issues that I yet
> have to address.
Looks good. :)
There is a NULL pointer problem with empty menus, item_cur is NULL and a
select or exit will cause a segfault in item_set_selected().
> I will during the weekend try to address the resize issue.
Wasn't it working at some point?
Anyway, it doesn't has to be overly complex either, e.g. if you delay it
to the next key event, it's fine too. The signal handler would just set a
flag and when wgetch returns, the display is reinitialized.
> The double ESC ESC thing I dunno how to fix.
I think the easiest would be to just ignore the first ESC, it matches the
documented behaviour and e.g. mc has the same behaviour. The delay of the
single ESC makes it a bit annoying/confusing to use, so that sticking to
the double ESC is IMO safer.
I played with it a little and below is an example, which implements this
behaviour for the menu window.
bye, Roman
Index: linux-2.6-git/scripts/kconfig/lxdialog/menubox.c
===================================================================
--- linux-2.6-git.orig/scripts/kconfig/lxdialog/menubox.c 2006-07-28 14:54:49.000000000 +0200
+++ linux-2.6-git/scripts/kconfig/lxdialog/menubox.c 2006-07-28 15:50:15.000000000 +0200
@@ -265,6 +265,14 @@ int dialog_menu(const char *title, const
while (key != ESC) {
key = wgetch(menu);
+ if (key == ESC) {
+ notimeout(menu, TRUE);
+ keypad(menu, FALSE);
+ key = wgetch(menu);
+ notimeout(menu, FALSE);
+ keypad(menu, TRUE);
+ }
+
if (key < 256 && isalpha(key))
key = tolower(key);
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
2006-07-28 14:09 ` Roman Zippel
@ 2006-07-28 14:59 ` Sam Ravnborg
2006-07-30 12:42 ` Denis Vlasenko
2006-07-29 20:53 ` Sam Ravnborg
2006-07-29 20:56 ` Sam Ravnborg
2 siblings, 1 reply; 8+ messages in thread
From: Sam Ravnborg @ 2006-07-28 14:59 UTC (permalink / raw)
To: Roman Zippel; +Cc: LKML, Petr Baudis
On Fri, Jul 28, 2006 at 04:09:03PM +0200, Roman Zippel wrote:
> Hi,
>
> On Thu, 27 Jul 2006, Sam Ravnborg wrote:
>
> > Dedided to take another stamp on an old TODO item of making lxdialog
> > a built-in. Following patch is first step to do so.
> > The patch makes it a built-in - but with two open issues that I yet
> > have to address.
>
> Looks good. :)
> There is a NULL pointer problem with empty menus, item_cur is NULL and a
> select or exit will cause a segfault in item_set_selected().
Fixed. Introduced a dummy variable "item_nil" that item_cur points to in
the empty case. So no need for special cases all over.
>
> > I will during the weekend try to address the resize issue.
>
> Wasn't it working at some point?
> Anyway, it doesn't has to be overly complex either, e.g. if you delay it
> to the next key event, it's fine too. The signal handler would just set a
> flag and when wgetch returns, the display is reinitialized.
My experiments so far tells me that a resize generates KEY_RESIZE so it
is a simple matter of handling KEY_RESIZE correct in the different
dialog_* functions - and no signal handler needed. Thats looks like the
approach taken in the dialog package too.
>
> > The double ESC ESC thing I dunno how to fix.
>
> I think the easiest would be to just ignore the first ESC, it matches the
> documented behaviour and e.g. mc has the same behaviour. The delay of the
> single ESC makes it a bit annoying/confusing to use, so that sticking to
> the double ESC is IMO safer.
> I played with it a little and below is an example, which implements this
> behaviour for the menu window.
Thanks - will implment this for all the dialog_* functions.
Sam
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
2006-07-28 14:59 ` Sam Ravnborg
@ 2006-07-30 12:42 ` Denis Vlasenko
2006-07-30 21:44 ` Sam Ravnborg
2006-07-30 22:19 ` Roman Zippel
0 siblings, 2 replies; 8+ messages in thread
From: Denis Vlasenko @ 2006-07-30 12:42 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: Roman Zippel, LKML, Petr Baudis
On Friday 28 July 2006 16:59, Sam Ravnborg wrote:
> > > The double ESC ESC thing I dunno how to fix.
> >
> > I think the easiest would be to just ignore the first ESC, it matches the
> > documented behaviour and e.g. mc has the same behaviour. The delay of the
> > single ESC makes it a bit annoying/confusing to use, so that sticking to
> > the double ESC is IMO safer.
> > I played with it a little and below is an example, which implements this
> > behaviour for the menu window.
>
> Thanks - will implment this for all the dialog_* functions.
I don't like "double ESC" idea at all.
I am a Midnight Commander user and I use "old ESC mode"
where single ESC works after a delay.
I patched mc to look at KEYBOARD_KEY_TIMEOUT_US environment variable
so that delay is configurable (instead of hardcoded 0.5 second one).
Will push the patch to mc-devel.
25 millisecond timeout works just fine on local ttys, serial lines,
and over ssh. So I am setting KEYBOARD_KEY_TIMEOUT_US=25000.
--
vda
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
2006-07-30 12:42 ` Denis Vlasenko
@ 2006-07-30 21:44 ` Sam Ravnborg
2006-07-30 22:19 ` Roman Zippel
1 sibling, 0 replies; 8+ messages in thread
From: Sam Ravnborg @ 2006-07-30 21:44 UTC (permalink / raw)
To: Denis Vlasenko; +Cc: Roman Zippel, LKML, Petr Baudis
On Sun, Jul 30, 2006 at 02:42:07PM +0200, Denis Vlasenko wrote:
>
> I don't like "double ESC" idea at all.
>
> I am a Midnight Commander user and I use "old ESC mode"
> where single ESC works after a delay.
>
> I patched mc to look at KEYBOARD_KEY_TIMEOUT_US environment variable
> so that delay is configurable (instead of hardcoded 0.5 second one).
> Will push the patch to mc-devel.
How did you tell ncurses to change timeout value?
notimeout() and wnotimeout() did not work out when I tried it. Delay was
still ~.5 seconds.
Any help aprpeciated.
Sam
My try:
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index bf8052f..2b59657 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -198,6 +198,7 @@ int dialog_menu(const char *title, const
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
+ wtimeout(dialog, 25);
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset(dialog, border_attr);
@@ -221,6 +222,7 @@ int dialog_menu(const char *title, const
menu = subwin(dialog, menu_height, menu_width,
y + box_y + 1, x + box_x + 1);
keypad(menu, TRUE);
+ wtimeout(menu, 25);
/* draw a box around the menu items */
draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index f82cebb..0973b53 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -142,7 +142,7 @@ void init_dialog(void)
keypad(stdscr, TRUE);
cbreak();
noecho();
-
+ timeout(25);
if (use_colors) /* Set up colors */
color_setup();
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
2006-07-30 12:42 ` Denis Vlasenko
2006-07-30 21:44 ` Sam Ravnborg
@ 2006-07-30 22:19 ` Roman Zippel
1 sibling, 0 replies; 8+ messages in thread
From: Roman Zippel @ 2006-07-30 22:19 UTC (permalink / raw)
To: Denis Vlasenko; +Cc: Sam Ravnborg, LKML, Petr Baudis
Hi,
On Sun, 30 Jul 2006, Denis Vlasenko wrote:
> I don't like "double ESC" idea at all.
>
> I am a Midnight Commander user and I use "old ESC mode"
> where single ESC works after a delay.
As you noticed this is not the default mode in mc either.
> I patched mc to look at KEYBOARD_KEY_TIMEOUT_US environment variable
> so that delay is configurable (instead of hardcoded 0.5 second one).
> Will push the patch to mc-devel.
If you want to make it an _option_ for menuconfig, please go ahead.
bye, Roman
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
2006-07-28 14:09 ` Roman Zippel
2006-07-28 14:59 ` Sam Ravnborg
@ 2006-07-29 20:53 ` Sam Ravnborg
2006-07-29 20:56 ` Sam Ravnborg
2 siblings, 0 replies; 8+ messages in thread
From: Sam Ravnborg @ 2006-07-29 20:53 UTC (permalink / raw)
To: Roman Zippel; +Cc: LKML, Petr Baudis
On Fri, Jul 28, 2006 at 04:09:03PM +0200, Roman Zippel wrote:
> > The double ESC ESC thing I dunno how to fix.
>
> I think the easiest would be to just ignore the first ESC, it matches the
> documented behaviour and e.g. mc has the same behaviour. The delay of the
> single ESC makes it a bit annoying/confusing to use, so that sticking to
> the double ESC is IMO safer.
> I played with it a little and below is an example, which implements this
> behaviour for the menu window.
It became a bit more complicated to support ESC-space resulting in
space. That makes sense since one press ESC - wonder what is going on
and then press space (for example).
It does not support ESC-left (or any other key that generate meta
chars).
Sam
>From 0d9076ae65ffa0a1d7bbaf8cf0b16ac1eac63b6e Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@mars.ravnborg.org>
Date: Fri, 28 Jul 2006 23:57:48 +0200
Subject: [PATCH] kconfig/lxdialog: let <ESC><ESC> behave as expected
<ESC><ESC> is used to step one back in the dialogs.
When lxdialog became built-in pressing <ESC> once would cause one step back
and pressing <ESC><ESC> would cause two steps back.
This patch - based on concept from Roman Zippel <zippel@linux-m68k.org> -
makes one <ESC> a noop and pressing <ESC><ESC> will cause one step backward.
In addition the final yes/no dialog now has the option to go back to the
the kernel configuration. So if you get too far out you can now go back
to configuring the kernel without saving and starting all over again.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
scripts/kconfig/lxdialog/checklist.c | 10 ++++++----
scripts/kconfig/lxdialog/dialog.h | 4 +++-
scripts/kconfig/lxdialog/inputbox.c | 10 ++++++----
| 10 ++++++----
scripts/kconfig/lxdialog/textbox.c | 7 ++++---
scripts/kconfig/lxdialog/util.c | 33 +++++++++++++++++++++++++++++++++
scripts/kconfig/lxdialog/yesno.c | 7 ++++---
scripts/kconfig/mconf.c | 25 ++++++++++++++-----------
8 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index 2825110..39becb7 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -192,7 +192,7 @@ int dialog_checklist(const char *title,
wnoutrefresh(list);
doupdate();
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
for (i = 0; i < max_choice; i++) {
@@ -298,8 +298,10 @@ int dialog_checklist(const char *title,
break;
case 'X':
case 'x':
- key = ESC;
- case ESC:
+ key = KEY_ESC;
+ break;
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
}
@@ -308,5 +310,5 @@ int dialog_checklist(const char *title,
}
delwin(list);
delwin(dialog);
- return 255; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index 065ded0..a7cfdec 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -48,7 +48,7 @@ #endif
#define TR(params) _tracef params
-#define ESC 27
+#define KEY_ESC 27
#define TAB 9
#define MAX_LEN 2048
#define BUF_SIZE (10*1024)
@@ -179,6 +179,8 @@ #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);
void init_dialog(const char *backtitle);
void reset_dialog(void);
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 9c53098..edb7975 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -106,7 +106,7 @@ int dialog_inputbox(const char *title, c
wrefresh(dialog);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
if (button == -1) { /* Input box selected */
@@ -215,12 +215,14 @@ int dialog_inputbox(const char *title, c
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;
}
}
delwin(dialog);
- return 255; /* ESC pressed */
+ return KEY_ESC; /* ESC pressed */
}
--git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index f39ae29..d3305ba 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -263,7 +263,7 @@ int dialog_menu(const char *title, const
wmove(menu, choice, item_x + 1);
wrefresh(menu);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(menu);
if (key < 256 && isalpha(key))
@@ -402,12 +402,14 @@ int dialog_menu(const char *title, const
return button;
case 'e':
case 'x':
- key = ESC;
- case ESC:
+ key = KEY_ESC;
+ break;
+ case KEY_ESC:
+ key = on_key_esc(menu);
break;
}
}
delwin(menu);
delwin(dialog);
- return 255; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 86b0770..a99e1f4 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -92,7 +92,7 @@ int dialog_textbox(const char *title, co
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
- while ((key != ESC) && (key != '\n')) {
+ while ((key != KEY_ESC) && (key != '\n')) {
key = wgetch(dialog);
switch (key) {
case 'E': /* Exit */
@@ -228,13 +228,14 @@ int dialog_textbox(const char *title, co
wmove(dialog, cur_y, cur_x);
wrefresh(dialog);
break;
- case ESC:
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
}
}
delwin(text);
delwin(dialog);
- return 255; /* ESC pressed */
+ return key; /* ESC pressed */
}
/*
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index 0b3118d..cb21dc4 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -477,6 +477,39 @@ int first_alpha(const char *string, cons
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;
+}
+
+
struct dialog_list *item_cur;
struct dialog_list item_nil;
struct dialog_list *item_head;
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index 9fc2449..8364f9d 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -69,7 +69,7 @@ int dialog_yesno(const char *title, cons
print_buttons(dialog, height, width, 0);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
switch (key) {
case 'Y':
@@ -93,11 +93,12 @@ int dialog_yesno(const char *title, cons
case '\n':
delwin(dialog);
return button;
- case ESC:
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
}
}
delwin(dialog);
- return 255; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index b1ad9a0..ef75d6c 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -608,7 +608,7 @@ static void conf(struct menu *menu)
_(menu_instructions),
rows, cols, rows - 10,
active_menu, &s_scroll);
- if (res == 1 || res == 255)
+ if (res == 1 || res == KEY_ESC)
break;
if (!item_activate_selected())
continue;
@@ -754,7 +754,7 @@ static void conf_choice(struct menu *men
} else
show_help(menu);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -794,7 +794,7 @@ static void conf_string(struct menu *men
case 1:
show_help(menu);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -819,7 +819,7 @@ static void conf_load(void)
case 1:
show_helptext(_("Load Alternate Configuration"), load_config_help);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -843,7 +843,7 @@ static void conf_save(void)
case 1:
show_helptext(_("Save Alternate Configuration"), save_config_help);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -883,12 +883,15 @@ int main(int ac, char **av)
init_wsize();
reset_dialog();
init_dialog(menu_backtitle);
- conf(&rootmenu);
- reset_dialog();
- res = dialog_yesno(NULL,
- _("Do you wish to save your "
- "new kernel configuration?"),
- 5, 60);
+ do {
+ conf(&rootmenu);
+ reset_dialog();
+ 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)) {
--
1.4.1.rc2.gfc04
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in
2006-07-28 14:09 ` Roman Zippel
2006-07-28 14:59 ` Sam Ravnborg
2006-07-29 20:53 ` Sam Ravnborg
@ 2006-07-29 20:56 ` Sam Ravnborg
2 siblings, 0 replies; 8+ messages in thread
From: Sam Ravnborg @ 2006-07-29 20:56 UTC (permalink / raw)
To: Roman Zippel; +Cc: LKML, Petr Baudis
>
> > I will during the weekend try to address the resize issue.
>
Here is my take on the resize support. textbox.c were hit by a little
refactoring in same go. I can split it in two patches if requested.
make menuconfig looks sensible and I have now pushed all patches out to:
git://git.kernel.org/pub/scm/linux/kernel/git/sam/lxdialog.git
It will show up in next -mm for wider testing.
Comments welcome!
Sam
>From 466ac6aa895d1c25964f9fef4502bb9b1cab6dd9 Mon Sep 17 00:00:00 2001
From: Sam Ravnborg <sam@mars.ravnborg.org>
Date: Sat, 29 Jul 2006 22:48:57 +0200
Subject: [PATCH] kconfig/lxdialog: support resize
In all dialogs now properly catch KEY_RESIZE and take proper action.
In mconf try to behave sensibly when a dialog routine returns
-ERRDISPLAYTOOSMALL.
The original check for a screnn size of 80x19 is kept for now.
It may make sense to remove it later, but thats anyway what
much text is adjusted for.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
scripts/kconfig/lxdialog/checklist.c | 11 +++
scripts/kconfig/lxdialog/dialog.h | 8 +-
scripts/kconfig/lxdialog/inputbox.c | 20 ++++-
| 25 +++++-
scripts/kconfig/lxdialog/textbox.c | 140 ++++++++++++++++++++--------------
scripts/kconfig/lxdialog/util.c | 6 +
scripts/kconfig/lxdialog/yesno.c | 10 ++
scripts/kconfig/mconf.c | 12 ++-
8 files changed, 161 insertions(+), 71 deletions(-)
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index 39becb7..cf69708 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -125,6 +125,12 @@ int dialog_checklist(const char *title,
}
}
+do_resize:
+ if (getmaxy(stdscr) < (height + 6))
+ return -ERRDISPLAYTOOSMALL;
+ if (getmaxx(stdscr) < (width + 6))
+ return -ERRDISPLAYTOOSMALL;
+
max_choice = MIN(list_height, item_count());
/* center dialog box on screen */
@@ -303,6 +309,11 @@ int dialog_checklist(const char *title,
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... */
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index a7cfdec..8dea47f 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -86,6 +86,9 @@ #ifndef ACS_DARROW
#define ACS_DARROW 'v'
#endif
+/* error return codes */
+#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
+
/*
* Color definitions
*/
@@ -181,6 +184,7 @@ #define item_foreach() \
/* generic key handlers */
int on_key_esc(WINDOW *win);
+int on_key_resize(void);
void init_dialog(const char *backtitle);
void reset_dialog(void);
@@ -199,8 +203,8 @@ int dialog_yesno(const char *title, cons
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 void *selected, int *s_scroll);
+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);
extern char dialog_input_result[];
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index edb7975..05e7206 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, c
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;
@@ -86,11 +97,6 @@ int dialog_inputbox(const char *title, c
wmove(dialog, box_y, box_x);
wattrset(dialog, dlg.inputbox.atr);
- if (!init)
- instr[0] = '\0';
- else
- strcpy(instr, init);
-
input_x = strlen(instr);
if (input_x >= box_width) {
@@ -220,6 +226,10 @@ int dialog_inputbox(const char *title, c
case KEY_ESC:
key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
}
--git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index d3305ba..fcd95a9 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -179,14 +179,25 @@ static void do_scroll(WINDOW *win, int *
/*
* 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 void *selected, int *s_scroll)
+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;
+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 */
@@ -226,7 +237,10 @@ int dialog_menu(const char *title, const
draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
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 */
item_foreach()
@@ -407,6 +421,11 @@ int dialog_menu(const char *title, const
case KEY_ESC:
key = on_key_esc(menu);
break;
+ case KEY_RESIZE:
+ on_key_resize();
+ delwin(menu);
+ delwin(dialog);
+ goto do_resize;
}
}
delwin(menu);
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index a99e1f4..fabfc1a 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -25,7 +25,7 @@ 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;
@@ -33,14 +33,28 @@ 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);
+}
+
+
+/*
* Display text from a file in a dialog box.
*/
-int dialog_textbox(const char *title, const char *tbuf, 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, key = 0;
- int texth, textw;
+ int height, width, boxh, boxw;
int passed_end;
- WINDOW *dialog, *text;
+ WINDOW *dialog, *box;
begin_reached = 1;
end_reached = 0;
@@ -49,6 +63,25 @@ int dialog_textbox(const char *title, co
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;
y = (LINES - height) / 2;
@@ -58,14 +91,14 @@ int dialog_textbox(const char *title, co
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- /* Create window for text region, used for scrolling text */
- texth = height - 4;
- textw = width - 2;
- text = subwin(dialog, texth, textw, y + 1, x + 1);
- wattrset(text, dlg.dialog.atr);
- wbkgdset(text, dlg.dialog.atr & 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,
@@ -86,11 +119,8 @@ int dialog_textbox(const char *title, co
getyx(dialog, cur_y, cur_x); /* Save cursor position */
/* Print first page of text */
- attr_clear(text, texth, textw, dlg.dialog.atr);
- print_page(text, texth, textw);
- 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 != KEY_ESC) && (key != '\n')) {
key = wgetch(dialog);
@@ -99,7 +129,7 @@ int dialog_textbox(const char *title, co
case 'e':
case 'X':
case 'x':
- delwin(text);
+ delwin(box);
delwin(dialog);
return 0;
case 'g': /* First page */
@@ -107,10 +137,8 @@ int dialog_textbox(const char *title, co
if (!begin_reached) {
begin_reached = 1;
page = buf;
- print_page(text, texth, textw);
- 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 */
@@ -119,11 +147,9 @@ int dialog_textbox(const char *title, co
end_reached = 1;
/* point to last char in buf */
page = buf + strlen(buf);
- back_lines(texth);
- print_page(text, texth, textw);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x); /* Restore cursor position */
- wrefresh(dialog);
+ back_lines(boxh);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case 'K': /* Previous line */
case 'k':
@@ -138,16 +164,16 @@ int dialog_textbox(const char *title, co
* 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);
+ 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 < texth; i++) {
+ for (i = 0; i < boxh; i++) {
if (!i) {
/* print first line of page */
- print_line(text, 0, textw);
- wnoutrefresh(text);
+ print_line(box, 0, boxw);
+ wnoutrefresh(box);
} else
/* Called to update 'end_reached' and 'page' */
get_line();
@@ -157,7 +183,7 @@ int dialog_textbox(const char *title, co
passed_end = 1;
}
- print_position(dialog, height, width);
+ print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
@@ -167,23 +193,21 @@ int dialog_textbox(const char *title, co
case KEY_PPAGE:
if (begin_reached)
break;
- back_lines(page_length + texth);
- print_page(text, texth, textw);
- 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, texth - 1, textw);
- 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);
}
@@ -194,10 +218,8 @@ int dialog_textbox(const char *title, co
break;
begin_reached = 0;
- print_page(text, texth, textw);
- 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 */
@@ -212,9 +234,8 @@ int dialog_textbox(const char *title, co
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- print_page(text, texth, textw);
- 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':
@@ -224,16 +245,21 @@ int dialog_textbox(const char *title, co
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- print_page(text, texth, textw);
- wmove(dialog, cur_y, cur_x);
- wrefresh(dialog);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
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(text);
+ delwin(box);
delwin(dialog);
return key; /* ESC pressed */
}
@@ -353,13 +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 percent;
wattrset(win, dlg.position_indicator.atr);
wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
percent = (page - buf) * 100 / strlen(buf);
- wmove(win, height - 3, width - 9);
+ 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 cb21dc4..ebc781b 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -509,6 +509,12 @@ int on_key_esc(WINDOW *win)
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;
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index 8364f9d..ee0a04e 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -44,6 +44,12 @@ int dialog_yesno(const char *title, cons
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;
@@ -96,6 +102,10 @@ int dialog_yesno(const char *title, cons
case KEY_ESC:
key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
}
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index ef75d6c..f7abca4 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -606,9 +606,8 @@ static void conf(struct menu *menu)
reset_dialog();
res = dialog_menu(prompt ? prompt : _("Main Menu"),
_(menu_instructions),
- rows, cols, rows - 10,
active_menu, &s_scroll);
- if (res == 1 || res == KEY_ESC)
+ if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break;
if (!item_activate_selected())
continue;
@@ -617,7 +616,10 @@ static void conf(struct menu *menu)
submenu = item_data();
active_menu = item_data();
- sym = submenu->sym;
+ if (submenu)
+ sym = submenu->sym;
+ else
+ sym = NULL;
switch (res) {
case 0:
@@ -683,7 +685,7 @@ static void conf(struct menu *menu)
static void show_textbox(const char *title, const char *text, int r, int c)
{
reset_dialog();
- dialog_textbox(title, text, r ? r : rows, c ? c : cols);
+ dialog_textbox(title, text, r, c);
}
static void show_helptext(const char *title, const char *text)
@@ -756,6 +758,8 @@ static void conf_choice(struct menu *men
break;
case KEY_ESC:
return;
+ case -ERRDISPLAYTOOSMALL:
+ return;
}
}
}
--
1.4.1.rc2.gfc04
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-07-30 22:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-27 20:27 [PATCH/RFC] kconfig/lxdialog: make lxdialof a built-in Sam Ravnborg
2006-07-28 14:09 ` Roman Zippel
2006-07-28 14:59 ` Sam Ravnborg
2006-07-30 12:42 ` Denis Vlasenko
2006-07-30 21:44 ` Sam Ravnborg
2006-07-30 22:19 ` Roman Zippel
2006-07-29 20:53 ` Sam Ravnborg
2006-07-29 20:56 ` Sam Ravnborg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox