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>
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 @@
 /*
  * 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 @@
 	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 @@
  * in the style of radiolist (only one option turned on at a time).
  */
 int dialog_checklist(const char *title, const char *prompt, int height,
-		     int width, int list_height, int item_no,
-		     const char *const *items)
+		     int width, int list_height)
 {
 	int i, x, y, box_x, box_y;
-	int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+	int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
 	WINDOW *dialog, *list;
 
-	/* Allocate space for storing item on/off status */
-	if ((status = malloc(sizeof(int) * item_no)) == NULL) {
-		endwin();
-		fprintf(stderr,
-			"\nCan't allocate memory in dialog_checklist().\n");
-		exit(-1);
+	/* which item to highlight */
+	item_foreach() {
+		if (item_is_tag('X'))
+			choice = item_n();
+		if (item_is_selected()) {
+			choice = item_n();
+			break;
+		}
 	}
 
-	/* Initializes status */
-	for (i = 0; i < item_no; i++) {
-		status[i] = !strcasecmp(items[i * 3 + 2], "on");
-		if ((!choice && status[i])
-		    || !strcasecmp(items[i * 3 + 2], "selected"))
-			choice = i + 1;
-	}
-	if (choice)
-		choice--;
-
-	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 @@
 
 	/* 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 @@
 
 	/* 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 @@
 	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 @@
 					/* 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 @@
 					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 @@
 			}
 			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 @@
 		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 @@
 			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 @@
 		/* 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..065ded0 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -133,11 +133,55 @@
  * 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_nil;
+extern struct dialog_list *item_head;
+
+int item_count(void);
+void item_set(int n);
+int item_n(void);
+const char *item_str(void);
+int item_is_selected(void);
+int item_is_tag(char tag);
+#define item_foreach() \
+	for (item_cur = item_head ? item_head: item_cur; \
+	     item_cur && (item_cur != &item_nil); item_cur = item_cur->next)
+
+
+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 +198,9 @@
 		  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 @@
 	}
 
 	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);
-}
diff --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 @@
 	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 @@
  * 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 @@
 	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 @@
 
 	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 @@
 			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 @@
 				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 @@
 
 			} 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 @@
 
 			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 @@
 		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 @@
 		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 @@
 			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..86b0770 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -27,54 +27,27 @@
 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 @@
 	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 @@
 	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 @@
 		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 @@
 		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 @@
 			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 @@
 		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 @@
 				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 @@
 				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 @@
 				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 @@
 			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 @@
 			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);
+	/* Go back 'n' lines */
+	for (i = 0; i < n; i++) {
+		if (*page == '\0') {
+			if (end_reached) {
+				end_reached = 0;
+				continue;
 			}
-			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 */
+		}
+		if (page == buf) {
+			begin_reached = 1;
+			return;
+		}
+		page--;
+		do {
+			if (page == buf) {
 				begin_reached = 1;
 				return;
 			}
-		}
-		if (*(--page) != '\n') {	/* '--page' here */
-			/* Something's wrong... */
-			endwin();
-			fprintf(stderr, "\nInternal error in back_lines().\n");
-			exit(-1);
-		}
+			page--;
+		} while (*page != '\n');
+		page++;
 	}
-	/* Go back 'n' lines */
-	for (i = 0; i < n; i++)
-		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;
-				}
-			}
-		} while (*(--page) != '\n');
-	page++;
 }
 
 /*
@@ -467,33 +322,14 @@
  */
 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 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..0b3118d 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -268,13 +268,18 @@
 /*
  * 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,128 @@
 
 	return 0;
 }
+
+struct dialog_list *item_cur;
+struct dialog_list item_nil;
+struct dialog_list *item_head;
+
+void item_reset(void)
+{
+	struct dialog_list *p, *next;
+
+	for (p = item_head; p; p = next) {
+		next = p->next;
+		free(p);
+	}
+	item_head = NULL;
+	item_cur = &item_nil;
+}
+
+void item_make(const char *fmt, ...)
+{
+	va_list ap;
+	struct dialog_list *p = malloc(sizeof(*p));
+
+	if (item_head)
+		item_cur->next = p;
+	else
+		item_head = p;
+	item_cur = p;
+	memset(p, 0, sizeof(*p));
+
+	va_start(ap, fmt);
+	vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
+	va_end(ap);
+}
+
+void item_add_str(const char *fmt, ...)
+{
+	va_list ap;
+        size_t avail;
+
+	avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
+
+	va_start(ap, fmt);
+	vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
+		  avail, fmt, ap);
+	item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
+	va_end(ap);
+}
+
+void item_set_tag(char tag)
+{
+	item_cur->node.tag = tag;
+}
+void item_set_data(void *ptr)
+{
+	item_cur->node.data = ptr;
+}
+
+void item_set_selected(int val)
+{
+	item_cur->node.selected = val;
+}
+
+int item_activate_selected(void)
+{
+	item_foreach()
+		if (item_is_selected())
+			return 1;
+	return 0;
+}
+
+void *item_data(void)
+{
+	return item_cur->node.data;
+}
+
+char item_tag(void)
+{
+	return item_cur->node.tag;
+}
+
+int item_count(void)
+{
+	int n = 0;
+	struct dialog_list *p;
+
+	for (p = item_head; p; p = p->next)
+		n++;
+	return n;
+}
+
+void item_set(int n)
+{
+	int i = 0;
+	item_foreach()
+		if (i++ == n)
+			return;
+}
+
+int item_n(void)
+{
+	int n = 0;
+	struct dialog_list *p;
+
+	for (p = item_head; p; p = p->next) {
+		if (p == item_cur)
+			return n;
+		n++;
+	}
+	return 0;
+}
+
+const char *item_str(void)
+{
+	return item_cur->node.str;
+}
+
+int item_is_selected(void)
+{
+	return (item_cur->node.selected != 0);
+}
+
+int item_is_tag(char tag)
+{
+	return (item_cur->node.tag == tag);
+}
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index e938037..9fc2449 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -99,5 +99,5 @@
 	}
 
 	delwin(dialog);
-	return -1;		/* ESC pressed */
+	return 255;		/* ESC pressed */
 }