Commit 2982de69 authored by Sam Ravnborg's avatar Sam Ravnborg Committed by Sam Ravnborg

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: default avatarSam Ravnborg <sam@ravnborg.org>
parent 350b5b76
...@@ -11,7 +11,6 @@ gconfig: $(obj)/gconf ...@@ -11,7 +11,6 @@ gconfig: $(obj)/gconf
$< arch/$(ARCH)/Kconfig $< arch/$(ARCH)/Kconfig
menuconfig: $(obj)/mconf menuconfig: $(obj)/mconf
$(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
$< arch/$(ARCH)/Kconfig $< arch/$(ARCH)/Kconfig
config: $(obj)/conf config: $(obj)/conf
...@@ -81,6 +80,23 @@ help: ...@@ -81,6 +80,23 @@ help:
@echo ' allyesconfig - New config where all options are accepted with yes' @echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New config where all options are answered with no' @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: # Shared Makefile for the various kconfig executables:
# conf: Used for defconfig, oldconfig and related targets # conf: Used for defconfig, oldconfig and related targets
...@@ -92,9 +108,12 @@ help: ...@@ -92,9 +108,12 @@ help:
# Based on GTK which needs to be installed to compile it # Based on GTK which needs to be installed to compile it
# object files used by all kconfig flavours # 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 hostprogs-y := conf mconf qconf gconf kxgettext
conf-objs := conf.o zconf.tab.o conf-objs := conf.o zconf.tab.o
mconf-objs := mconf.o zconf.tab.o mconf-objs := mconf.o zconf.tab.o $(lxdialog)
kxgettext-objs := kxgettext.o zconf.tab.o kxgettext-objs := kxgettext.o zconf.tab.o
ifeq ($(MAKECMDGOALS),xconfig) ifeq ($(MAKECMDGOALS),xconfig)
......
# 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
...@@ -28,8 +28,7 @@ static int list_width, check_x, item_x; ...@@ -28,8 +28,7 @@ static int list_width, check_x, item_x;
/* /*
* Print list item * Print list item
*/ */
static void print_item(WINDOW * win, const char *item, int status, int choice, static void print_item(WINDOW * win, int choice, int selected)
int selected)
{ {
int i; int i;
...@@ -42,12 +41,12 @@ static void print_item(WINDOW * win, const char *item, int status, int choice, ...@@ -42,12 +41,12 @@ static void print_item(WINDOW * win, const char *item, int status, int choice,
wmove(win, choice, check_x); wmove(win, choice, check_x);
wattrset(win, selected ? dlg.check_selected.atr wattrset(win, selected ? dlg.check_selected.atr
: dlg.check.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); 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); wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
waddstr(win, (char *)item + 1); waddstr(win, (char *)item_str() + 1);
if (selected) { if (selected) {
wmove(win, choice, check_x + 1); wmove(win, choice, check_x + 1);
wrefresh(win); wrefresh(win);
...@@ -110,32 +109,23 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) ...@@ -110,32 +109,23 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
* in the style of radiolist (only one option turned on at a time). * 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 dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height, int item_no, int width, int list_height)
const char *const *items)
{ {
int i, x, y, box_x, box_y; 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; WINDOW *dialog, *list;
/* Allocate space for storing item on/off status */ /* which item to highlight */
if ((status = malloc(sizeof(int) * item_no)) == NULL) { item_foreach() {
endwin(); if (item_is_tag('X'))
fprintf(stderr, choice = item_n();
"\nCan't allocate memory in dialog_checklist().\n"); if (item_is_selected()) {
exit(-1); 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 */ /* center dialog box on screen */
x = (COLS - width) / 2; x = (COLS - width) / 2;
...@@ -176,8 +166,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -176,8 +166,8 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Find length of longest item in order to center checklist */ /* Find length of longest item in order to center checklist */
check_x = 0; check_x = 0;
for (i = 0; i < item_no; i++) item_foreach()
check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4); check_x = MAX(check_x, strlen(item_str()) + 4);
check_x = (list_width - check_x) / 2; check_x = (list_width - check_x) / 2;
item_x = check_x + 4; item_x = check_x + 4;
...@@ -189,14 +179,11 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -189,14 +179,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Print the list */ /* Print the list */
for (i = 0; i < max_choice; i++) { for (i = 0; i < max_choice; i++) {
if (i != choice) item_set(scroll + i);
print_item(list, items[(scroll + i) * 3 + 1], print_item(list, i, i == choice);
status[i + scroll], i, 0);
} }
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); box_y, box_x + check_x + 5, list_height);
print_buttons(dialog, height, width, 0); print_buttons(dialog, height, width, 0);
...@@ -208,10 +195,11 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -208,10 +195,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
while (key != ESC) { while (key != ESC) {
key = wgetch(dialog); key = wgetch(dialog);
for (i = 0; i < max_choice; i++) for (i = 0; i < max_choice; i++) {
if (toupper(key) == item_set(i + scroll);
toupper(items[(scroll + i) * 3 + 1][0])) if (toupper(key) == toupper(item_str()[0]))
break; break;
}
if (i < max_choice || key == KEY_UP || key == KEY_DOWN || if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
key == '+' || key == '-') { key == '+' || key == '-') {
...@@ -222,15 +210,16 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -222,15 +210,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Scroll list down */ /* Scroll list down */
if (list_height > 1) { if (list_height > 1) {
/* De-highlight current first item */ /* De-highlight current first item */
print_item(list, items[scroll * 3 + 1], item_set(scroll);
status[scroll], 0, FALSE); print_item(list, 0, FALSE);
scrollok(list, TRUE); scrollok(list, TRUE);
wscrl(list, -1); wscrl(list, -1);
scrollok(list, FALSE); scrollok(list, FALSE);
} }
scroll--; scroll--;
print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); item_set(scroll);
print_arrows(dialog, choice, item_no, print_item(list, 0, TRUE);
print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height); scroll, box_y, box_x + check_x + 5, list_height);
wnoutrefresh(dialog); wnoutrefresh(dialog);
...@@ -241,23 +230,24 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -241,23 +230,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
i = choice - 1; i = choice - 1;
} else if (key == KEY_DOWN || key == '+') { } else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) { if (choice == max_choice - 1) {
if (scroll + choice >= item_no - 1) if (scroll + choice >= item_count() - 1)
continue; continue;
/* Scroll list up */ /* Scroll list up */
if (list_height > 1) { if (list_height > 1) {
/* De-highlight current last item before scrolling up */ /* De-highlight current last item before scrolling up */
print_item(list, items[(scroll + max_choice - 1) * 3 + 1], item_set(scroll + max_choice - 1);
status[scroll + max_choice - 1], print_item(list,
max_choice - 1, FALSE); max_choice - 1,
FALSE);
scrollok(list, TRUE); scrollok(list, TRUE);
wscrl(list, 1); wscrl(list, 1);
scrollok(list, FALSE); scrollok(list, FALSE);
} }
scroll++; scroll++;
print_item(list, items[(scroll + max_choice - 1) * 3 + 1], item_set(scroll + max_choice - 1);
status[scroll + max_choice - 1], max_choice - 1, TRUE); 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); scroll, box_y, box_x + check_x + 5, list_height);
wnoutrefresh(dialog); wnoutrefresh(dialog);
...@@ -269,12 +259,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -269,12 +259,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
} }
if (i != choice) { if (i != choice) {
/* De-highlight current item */ /* De-highlight current item */
print_item(list, items[(scroll + choice) * 3 + 1], item_set(scroll + choice);
status[scroll + choice], choice, FALSE); print_item(list, choice, FALSE);
/* Highlight new item */ /* Highlight new item */
choice = i; choice = i;
print_item(list, items[(scroll + choice) * 3 + 1], item_set(scroll + choice);
status[scroll + choice], choice, TRUE); print_item(list, choice, TRUE);
wnoutrefresh(dialog); wnoutrefresh(dialog);
wrefresh(list); wrefresh(list);
} }
...@@ -284,10 +274,19 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -284,10 +274,19 @@ int dialog_checklist(const char *title, const char *prompt, int height,
case 'H': case 'H':
case 'h': case 'h':
case '?': 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); delwin(dialog);
free(status); return button;
return 1;
case TAB: case TAB:
case KEY_LEFT: case KEY_LEFT:
case KEY_RIGHT: case KEY_RIGHT:
...@@ -297,30 +296,6 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -297,30 +296,6 @@ int dialog_checklist(const char *title, const char *prompt, int height,
print_buttons(dialog, height, width, button); print_buttons(dialog, height, width, button);
wrefresh(dialog); wrefresh(dialog);
break; 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':
case 'x': case 'x':
key = ESC; key = ESC;
...@@ -331,8 +306,7 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -331,8 +306,7 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Now, update everything... */ /* Now, update everything... */
doupdate(); doupdate();
} }
delwin(list);
delwin(dialog); delwin(dialog);
free(status); return 255; /* ESC pressed */
return -1; /* ESC pressed */
} }
...@@ -133,11 +133,55 @@ struct dialog_info { ...@@ -133,11 +133,55 @@ struct dialog_info {
* Global variables * Global variables
*/ */
extern struct dialog_info dlg; extern struct dialog_info dlg;
extern char dialog_input_result[];
/* /*
* Function prototypes * 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 end_dialog(void);
void attr_clear(WINDOW * win, int height, int width, chtype attr); void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void); void dialog_clear(void);
...@@ -154,11 +198,9 @@ int dialog_msgbox(const char *title, const char *prompt, int height, ...@@ -154,11 +198,9 @@ int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause); int width, int pause);
int dialog_textbox(const char *title, const char *file, int height, int width); 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 dialog_menu(const char *title, const char *prompt, int height, int width,
int menu_height, const char *choice, int item_no, int menu_height, const void *selected, int *s_scroll);
const char *const *items);
int dialog_checklist(const char *title, const char *prompt, int height, int dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height, int item_no, int width, int list_height);
const char *const *items);
extern char dialog_input_result[]; extern char dialog_input_result[];
int dialog_inputbox(const char *title, const char *prompt, int height, int dialog_inputbox(const char *title, const char *prompt, int height,
int width, const char *init); int width, const char *init);
......
...@@ -222,5 +222,5 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width ...@@ -222,5 +222,5 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
} }
delwin(dialog); delwin(dialog);
return -1; /* ESC pressed */ return 255; /* ESC pressed */
} }
/*
* 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);
}
...@@ -99,10 +99,10 @@ static void do_print_item(WINDOW * win, const char *item, int choice, ...@@ -99,10 +99,10 @@ static void do_print_item(WINDOW * win, const char *item, int choice,
wrefresh(win); wrefresh(win);
} }
#define print_item(index, choice, selected) \ #define print_item(index, choice, selected) \
do {\ do { \
int hotkey = (items[(index) * 2][0] != ':'); \ item_set(index); \
do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \ do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
} while (0) } while (0)
/* /*
...@@ -180,16 +180,14 @@ static void do_scroll(WINDOW *win, int *scroll, int n) ...@@ -180,16 +180,14 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
* Display a menu for choosing among a number of options * Display a menu for choosing among a number of options
*/ */
int dialog_menu(const char *title, const char *prompt, int height, int width, int dialog_menu(const char *title, const char *prompt, int height, int width,
int menu_height, const char *current, int item_no, int menu_height, const void *selected, int *s_scroll)
const char *const *items)
{ {
int i, j, x, y, box_x, box_y; int i, j, x, y, box_x, box_y;
int key = 0, button = 0, scroll = 0, choice = 0; int key = 0, button = 0, scroll = 0, choice = 0;
int first_item = 0, max_choice; int first_item = 0, max_choice;
WINDOW *dialog, *menu; WINDOW *dialog, *menu;
FILE *f;
max_choice = MIN(menu_height, item_no); max_choice = MIN(menu_height, item_count());
/* center dialog box on screen */ /* center dialog box on screen */
x = (COLS - width) / 2; x = (COLS - width) / 2;
...@@ -231,28 +229,21 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -231,28 +229,21 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
item_x = (menu_width - 70) / 2; item_x = (menu_width - 70) / 2;
/* Set choice to default item */ /* Set choice to default item */
for (i = 0; i < item_no; i++) item_foreach()
if (strcmp(current, items[i * 2]) == 0) if (selected && (selected == item_data()))
choice = i; choice = item_n();
/* get the saved scroll info */
/* get the scroll info from the temp file */ scroll = *s_scroll;
if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) { if ((scroll <= choice) && (scroll + max_choice > choice) &&
if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) && (scroll >= 0) && (scroll + max_choice <= item_count())) {
(scroll + max_choice > choice) && (scroll >= 0) && first_item = scroll;
(scroll + max_choice <= item_no)) { choice = choice - scroll;
first_item = scroll; } else {
choice = choice - scroll; scroll = 0;
fclose(f);
} else {
scroll = 0;
remove("lxdialog.scrltmp");
fclose(f);
f = NULL;
}
} }
if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) { if ((choice >= max_choice)) {
if (choice >= item_no - max_choice / 2) if (choice >= item_count() - max_choice / 2)
scroll = first_item = item_no - max_choice; scroll = first_item = item_count() - max_choice;
else else
scroll = first_item = choice - max_choice / 2; scroll = first_item = choice - max_choice / 2;
choice = choice - scroll; choice = choice - scroll;
...@@ -265,7 +256,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -265,7 +256,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
wnoutrefresh(menu); wnoutrefresh(menu);
print_arrows(dialog, item_no, scroll, print_arrows(dialog, item_count(), scroll,
box_y, box_x + item_x + 1, menu_height); box_y, box_x + item_x + 1, menu_height);
print_buttons(dialog, height, width, 0); print_buttons(dialog, height, width, 0);
...@@ -282,14 +273,16 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -282,14 +273,16 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
i = max_choice; i = max_choice;
else { else {
for (i = choice + 1; i < max_choice; i++) { for (i = choice + 1; i < max_choice; i++) {
j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh"); item_set(scroll + i);
if (key == tolower(items[(scroll + i) * 2 + 1][j])) j = first_alpha(item_str(), "YyNnMmHh");
if (key == tolower(item_str()[j]))
break; break;
} }
if (i == max_choice) if (i == max_choice)
for (i = 0; i < max_choice; i++) { for (i = 0; i < max_choice; i++) {
j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh"); item_set(scroll + i);
if (key == tolower(items[(scroll + i) * 2 + 1][j])) j = first_alpha(item_str(), "YyNnMmHh");
if (key == tolower(item_str()[j]))
break; break;
} }
} }
...@@ -314,7 +307,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -314,7 +307,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
print_item(scroll+choice, choice, FALSE); print_item(scroll+choice, choice, FALSE);
if ((choice > max_choice - 3) && if ((choice > max_choice - 3) &&
(scroll + max_choice < item_no)) { (scroll + max_choice < item_count())) {
/* Scroll menu up */ /* Scroll menu up */
do_scroll(menu, &scroll, 1); do_scroll(menu, &scroll, 1);
...@@ -337,7 +330,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -337,7 +330,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
} else if (key == KEY_NPAGE) { } else if (key == KEY_NPAGE) {
for (i = 0; (i < max_choice); i++) { for (i = 0; (i < max_choice); i++) {
if (scroll + max_choice < item_no) { if (scroll + max_choice < item_count()) {
do_scroll(menu, &scroll, 1); do_scroll(menu, &scroll, 1);
print_item(scroll+max_choice-1, print_item(scroll+max_choice-1,
max_choice - 1, FALSE); max_choice - 1, FALSE);
...@@ -351,7 +344,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -351,7 +344,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
print_item(scroll + choice, choice, TRUE); 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); box_y, box_x + item_x + 1, menu_height);
wnoutrefresh(dialog); wnoutrefresh(dialog);
...@@ -377,12 +370,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -377,12 +370,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
case 'm': case 'm':
case '/': case '/':
/* save scroll info */ /* save scroll info */
if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) { *s_scroll = scroll;
fprintf(f, "%d\n", scroll); delwin(menu);
fclose(f);
}
delwin(dialog); delwin(dialog);
fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); item_set(scroll + choice);
item_set_selected(1);
switch (key) { switch (key) {
case 's': case 's':
return 3; return 3;
...@@ -402,17 +394,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -402,17 +394,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
case '?': case '?':
button = 2; button = 2;
case '\n': case '\n':
*s_scroll = scroll;
delwin(menu);
delwin(dialog); delwin(dialog);
if (button == 2) item_set(scroll + choice);
fprintf(stderr, "%s \"%s\"\n", item_set_selected(1);
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");
return button; return button;
case 'e': case 'e':
case 'x': case 'x':
...@@ -421,8 +407,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, ...@@ -421,8 +407,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
break; break;
} }
} }
delwin(menu);
delwin(dialog); delwin(dialog);
remove("lxdialog.scrltmp"); return 255; /* ESC pressed */
return -1; /* ESC pressed */
} }
/*
* 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;
}
...@@ -27,54 +27,27 @@ static void print_line(WINDOW * win, int row, int width); ...@@ -27,54 +27,27 @@ static void print_line(WINDOW * win, int row, int width);
static char *get_line(void); static char *get_line(void);
static void print_position(WINDOW * win, int height, int width); static void print_position(WINDOW * win, int height, int width);
static int hscroll, fd, file_size, bytes_read; static int hscroll;
static int begin_reached = 1, end_reached, page_length; static int begin_reached, end_reached, page_length;
static char *buf, *page; static const char *buf;
static const char *page;
/* /*
* Display text from a file in a dialog box. * 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; int passed_end;
char search_term[MAX_LEN + 1];
WINDOW *dialog, *text; WINDOW *dialog, *text;
search_term[0] = '\0'; /* no search term entered yet */ begin_reached = 1;
end_reached = 0;
/* Open input file for reading */ page_length = 0;
if ((fd = open(file, O_RDONLY)) == -1) { hscroll = 0;
endwin(); buf = tbuf;
fprintf(stderr, "\nCan't open input file in dialog_textbox().\n"); page = buf; /* page is pointer to start of page to be displayed */
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 */
/* center dialog box on screen */ /* center dialog box on screen */
x = (COLS - width) / 2; x = (COLS - width) / 2;
...@@ -86,7 +59,9 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -86,7 +59,9 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
keypad(dialog, TRUE); keypad(dialog, TRUE);
/* Create window for text region, used for scrolling text */ /* 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); wattrset(text, dlg.dialog.atr);
wbkgdset(text, dlg.dialog.atr & A_COLOR); wbkgdset(text, dlg.dialog.atr & A_COLOR);
...@@ -111,8 +86,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -111,8 +86,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
getyx(dialog, cur_y, cur_x); /* Save cursor position */ getyx(dialog, cur_y, cur_x); /* Save cursor position */
/* Print first page of text */ /* Print first page of text */
attr_clear(text, height - 4, width - 2, dlg.dialog.atr); attr_clear(text, texth, textw, dlg.dialog.atr);
print_page(text, height - 4, width - 2); print_page(text, texth, textw);
print_position(dialog, height, width); print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog); wrefresh(dialog);
...@@ -124,37 +99,15 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -124,37 +99,15 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
case 'e': case 'e':
case 'X': case 'X':
case 'x': case 'x':
delwin(text);
delwin(dialog); delwin(dialog);
free(buf);
close(fd);
return 0; return 0;
case 'g': /* First page */ case 'g': /* First page */
case KEY_HOME: case KEY_HOME:
if (!begin_reached) { if (!begin_reached) {
begin_reached = 1; 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; page = buf;
print_page(text, height - 4, width - 2); print_page(text, texth, textw);
print_position(dialog, height, width); print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog); wrefresh(dialog);
...@@ -164,29 +117,10 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -164,29 +117,10 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
case KEY_END: case KEY_END:
end_reached = 1; end_reached = 1;
/* Last page not in buffer? */ /* point to last char in buf */
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { page = buf + strlen(buf);
endwin(); back_lines(texth);
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); print_page(text, texth, textw);
exit(-1);
}
if (fpos < file_size) { /* Yes, we have to read it in */
if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
endwin();
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
exit(-1);
}
if ((bytes_read =
read(fd, buf, BUF_SIZE)) == -1) {
endwin();
fprintf(stderr, "\nError reading file in dialog_textbox().\n");
exit(-1);
}
buf[bytes_read] = '\0';
}
page = buf + bytes_read;
back_lines(height - 4);
print_page(text, height - 4, width - 2);
print_position(dialog, height, width); print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog); wrefresh(dialog);
...@@ -197,20 +131,22 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -197,20 +131,22 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
if (!begin_reached) { if (!begin_reached) {
back_lines(page_length + 1); back_lines(page_length + 1);
/* We don't call print_page() here but use scrolling to ensure /* We don't call print_page() here but use
faster screen update. However, 'end_reached' and * scrolling to ensure faster screen update.
'page_length' should still be updated, and 'page' should * However, 'end_reached' and 'page_length'
point to start of next page. This is done by calling * should still be updated, and 'page' should
get_line() in the following 'for' loop. */ * point to start of next page. This is done
* by calling get_line() in the following
* 'for' loop. */
scrollok(text, TRUE); scrollok(text, TRUE);
wscrl(text, -1); /* Scroll text region down one line */ wscrl(text, -1); /* Scroll text region down one line */
scrollok(text, FALSE); scrollok(text, FALSE);
page_length = 0; page_length = 0;
passed_end = 0; passed_end = 0;
for (i = 0; i < height - 4; i++) { for (i = 0; i < texth; i++) {
if (!i) { if (!i) {
/* print first line of page */ /* print first line of page */
print_line(text, 0, width - 2); print_line(text, 0, textw);
wnoutrefresh(text); wnoutrefresh(text);
} else } else
/* Called to update 'end_reached' and 'page' */ /* Called to update 'end_reached' and 'page' */
...@@ -231,8 +167,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -231,8 +167,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
case KEY_PPAGE: case KEY_PPAGE:
if (begin_reached) if (begin_reached)
break; break;
back_lines(page_length + height - 4); back_lines(page_length + texth);
print_page(text, height - 4, width - 2); print_page(text, texth, textw);
print_position(dialog, height, width); print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); wmove(dialog, cur_y, cur_x);
wrefresh(dialog); wrefresh(dialog);
...@@ -245,7 +181,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -245,7 +181,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
scrollok(text, TRUE); scrollok(text, TRUE);
scroll(text); /* Scroll text region up one line */ scroll(text); /* Scroll text region up one line */
scrollok(text, FALSE); scrollok(text, FALSE);
print_line(text, height - 5, width - 2); print_line(text, texth - 1, textw);
wnoutrefresh(text); wnoutrefresh(text);
print_position(dialog, height, width); print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
...@@ -258,7 +194,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -258,7 +194,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
break; break;
begin_reached = 0; begin_reached = 0;
print_page(text, height - 4, width - 2); print_page(text, texth, textw);
print_position(dialog, height, width); print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); wmove(dialog, cur_y, cur_x);
wrefresh(dialog); wrefresh(dialog);
...@@ -276,7 +212,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -276,7 +212,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
hscroll--; hscroll--;
/* Reprint current page to scroll horizontally */ /* Reprint current page to scroll horizontally */
back_lines(page_length); back_lines(page_length);
print_page(text, height - 4, width - 2); print_page(text, texth, textw);
wmove(dialog, cur_y, cur_x); wmove(dialog, cur_y, cur_x);
wrefresh(dialog); wrefresh(dialog);
break; break;
...@@ -288,7 +224,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -288,7 +224,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
hscroll++; hscroll++;
/* Reprint current page to scroll horizontally */ /* Reprint current page to scroll horizontally */
back_lines(page_length); back_lines(page_length);
print_page(text, height - 4, width - 2); print_page(text, texth, textw);
wmove(dialog, cur_y, cur_x); wmove(dialog, cur_y, cur_x);
wrefresh(dialog); wrefresh(dialog);
break; break;
...@@ -296,123 +232,42 @@ int dialog_textbox(const char *title, const char *file, int height, int width) ...@@ -296,123 +232,42 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
break; break;
} }
} }
delwin(text);
delwin(dialog); delwin(dialog);
free(buf); return 255; /* ESC pressed */
close(fd);
return -1; /* 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'. * 'page' will be updated to point to the desired line in 'buf'.
*/ */
static void back_lines(int n) static void back_lines(int n)
{ {
int i, fpos; int i;
begin_reached = 0; begin_reached = 0;
/* We have to distinguish between end_reached and !end_reached /* Go back 'n' lines */
since at end of file, the line is not ended by a '\n'. for (i = 0; i < n; i++) {
The code inside 'if' basically does a '--page' to move one if (*page == '\0') {
character backward so as to skip '\n' of the previous line */ if (end_reached) {
if (!end_reached) { end_reached = 0;
/* Either beginning of buffer or beginning of file reached? */ continue;
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;
} }
} }
if (*(--page) != '\n') { /* '--page' here */ if (page == buf) {
/* Something's wrong... */ begin_reached = 1;
endwin(); return;
fprintf(stderr, "\nInternal error in back_lines().\n");
exit(-1);
} }
} page--;
/* Go back 'n' lines */
for (i = 0; i < n; i++)
do { do {
if (page == buf) { if (page == buf) {
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { begin_reached = 1;
endwin(); return;
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--;
page++; } while (*page != '\n');
page++;
}
} }
/* /*
...@@ -467,33 +322,14 @@ static void print_line(WINDOW * win, int row, int width) ...@@ -467,33 +322,14 @@ static void print_line(WINDOW * win, int row, int width)
*/ */
static char *get_line(void) static char *get_line(void)
{ {
int i = 0, fpos; int i = 0;
static char line[MAX_LEN + 1]; static char line[MAX_LEN + 1];
end_reached = 0; end_reached = 0;
while (*page != '\n') { while (*page != '\n') {
if (*page == '\0') { if (*page == '\0') {
/* Either end of file or end of buffer reached */ if (!end_reached) {
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { end_reached = 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;
break; break;
} }
} else if (i < MAX_LEN) } else if (i < MAX_LEN)
...@@ -518,17 +354,11 @@ static char *get_line(void) ...@@ -518,17 +354,11 @@ static char *get_line(void)
*/ */
static void print_position(WINDOW * win, int height, int width) 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); wattrset(win, dlg.position_indicator.atr);
wbkgdset(win, dlg.position_indicator.atr & A_COLOR); wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
percent = !file_size ? percent = (page - buf) * 100 / strlen(buf);
100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
wmove(win, height - 3, width - 9); wmove(win, height - 3, width - 9);
wprintw(win, "(%3d%%)", percent); wprintw(win, "(%3d%%)", percent);
} }
...@@ -268,13 +268,18 @@ void dialog_clear(void) ...@@ -268,13 +268,18 @@ void dialog_clear(void)
/* /*
* Do some initialization for dialog * 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 */ initscr(); /* Init curses */
keypad(stdscr, TRUE); keypad(stdscr, TRUE);
cbreak(); cbreak();
noecho(); noecho();
color_setup(getenv("MENUCONFIG_COLOR"));
dialog_clear(); dialog_clear();
} }
...@@ -471,3 +476,128 @@ int first_alpha(const char *string, const char *exempt) ...@@ -471,3 +476,128 @@ int first_alpha(const char *string, const char *exempt)
return 0; 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);
}
...@@ -99,5 +99,5 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) ...@@ -99,5 +99,5 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
} }
delwin(dialog); delwin(dialog);
return -1; /* ESC pressed */ return 255; /* ESC pressed */
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define LKC_DIRECT_LINK #define LKC_DIRECT_LINK
#include "lkc.h" #include "lkc.h"
#include "lxdialog/dialog.h"
static char menu_backtitle[128]; static char menu_backtitle[128];
static const char mconf_readme[] = N_( static const char mconf_readme[] = N_(
...@@ -270,16 +271,12 @@ search_help[] = N_( ...@@ -270,16 +271,12 @@ search_help[] = N_(
" USB$ => find all CONFIG_ symbols ending with USB\n" " USB$ => find all CONFIG_ symbols ending with USB\n"
"\n"); "\n");
static char buf[4096], *bufptr = buf;
static char input_buf[4096];
static char filename[PATH_MAX+1] = ".config"; static char filename[PATH_MAX+1] = ".config";
static char *args[1024], **argptr = args;
static int indent; static int indent;
static struct termios ios_org; static struct termios ios_org;
static int rows = 0, cols = 0; static int rows = 0, cols = 0;
static struct menu *current_menu; static struct menu *current_menu;
static int child_count; static int child_count;
static int do_resize;
static int single_menu_mode; static int single_menu_mode;
static void conf(struct menu *menu); static void conf(struct menu *menu);
...@@ -290,12 +287,6 @@ static void conf_save(void); ...@@ -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_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text); static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu); 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) static void init_wsize(void)
{ {
...@@ -332,54 +323,6 @@ static void init_wsize(void) ...@@ -332,54 +323,6 @@ static void init_wsize(void)
cols -= 5; 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) static void get_prompt_str(struct gstr *r, struct property *prop)
{ {
int i, j; int i, j;
...@@ -452,108 +395,17 @@ static struct gstr get_relations_str(struct symbol **sym_arr) ...@@ -452,108 +395,17 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
return res; 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) static void search_conf(void)
{ {
struct symbol **sym_arr; struct symbol **sym_arr;
int stat;
struct gstr res; struct gstr res;
int dres;
again: again:
cprint_init(); reset_dialog();
cprint("--title"); dres = dialog_inputbox(_("Search Configuration Parameter"),
cprint(_("Search Configuration Parameter")); _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
cprint("--inputbox"); 10, 75, "");
cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)")); switch (dres) {
cprint("10");
cprint("75");
cprint("");
stat = exec_conf();
if (stat < 0)
goto again;
switch (stat) {
case 0: case 0:
break; break;
case 1: case 1:
...@@ -563,7 +415,7 @@ again: ...@@ -563,7 +415,7 @@ again:
return; return;
} }
sym_arr = sym_re_search(input_buf); sym_arr = sym_re_search(dialog_input_result);
res = get_relations_str(sym_arr); res = get_relations_str(sym_arr);
free(sym_arr); free(sym_arr);
show_textbox(_("Search Results"), str_get(&res), 0, 0); show_textbox(_("Search Results"), str_get(&res), 0, 0);
...@@ -590,24 +442,24 @@ static void build_conf(struct menu *menu) ...@@ -590,24 +442,24 @@ static void build_conf(struct menu *menu)
switch (prop->type) { switch (prop->type) {
case P_MENU: case P_MENU:
child_count++; child_count++;
cprint("m%p", menu);
if (single_menu_mode) { if (single_menu_mode) {
cprint1("%s%*c%s", item_make("%s%*c%s",
menu->data ? "-->" : "++>", menu->data ? "-->" : "++>",
indent + 1, ' ', prompt); indent + 1, ' ', prompt);
} else } 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) if (single_menu_mode && menu->data)
goto conf_childs; goto conf_childs;
return; return;
default: default:
if (prompt) { if (prompt) {
child_count++; child_count++;
cprint(":%p", menu); item_make("---%*c%s", indent + 1, ' ', prompt);
cprint("---%*c%s", indent + 1, ' ', prompt); item_set_tag(':');
item_set_data(menu);
} }
} }
} else } else
...@@ -628,10 +480,9 @@ static void build_conf(struct menu *menu) ...@@ -628,10 +480,9 @@ static void build_conf(struct menu *menu)
val = sym_get_tristate_value(sym); val = sym_get_tristate_value(sym);
if (sym_is_changable(sym)) { if (sym_is_changable(sym)) {
cprint("t%p", menu);
switch (type) { switch (type) {
case S_BOOLEAN: case S_BOOLEAN:
cprint1("[%c]", val == no ? ' ' : '*'); item_make("[%c]", val == no ? ' ' : '*');
break; break;
case S_TRISTATE: case S_TRISTATE:
switch (val) { switch (val) {
...@@ -639,84 +490,87 @@ static void build_conf(struct menu *menu) ...@@ -639,84 +490,87 @@ static void build_conf(struct menu *menu)
case mod: ch = 'M'; break; case mod: ch = 'M'; break;
default: ch = ' '; break; default: ch = ' '; break;
} }
cprint1("<%c>", ch); item_make("<%c>", ch);
break; break;
} }
item_set_tag('t');
item_set_data(menu);
} else { } else {
cprint("%c%p", def_menu ? 't' : ':', menu); item_make(" ");
cprint1(" "); 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 (val == yes) {
if (def_menu) { if (def_menu) {
cprint1(" (%s)", menu_get_prompt(def_menu)); item_add_str(" (%s)", menu_get_prompt(def_menu));
cprint1(" --->"); item_add_str(" --->");
cprint_done();
if (def_menu->list) { if (def_menu->list) {
indent += 2; indent += 2;
build_conf(def_menu); build_conf(def_menu);
indent -= 2; indent -= 2;
} }
} else }
cprint_done();
return; return;
} }
cprint_done();
} else { } else {
if (menu == current_menu) { if (menu == current_menu) {
cprint(":%p", menu); item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); item_set_tag(':');
item_set_data(menu);
goto conf_childs; goto conf_childs;
} }
child_count++; child_count++;
val = sym_get_tristate_value(sym); val = sym_get_tristate_value(sym);
if (sym_is_choice_value(sym) && val == yes) { if (sym_is_choice_value(sym) && val == yes) {
cprint(":%p", menu); item_make(" ");
cprint1(" "); item_set_tag(':');
item_set_data(menu);
} else { } else {
switch (type) { switch (type) {
case S_BOOLEAN: case S_BOOLEAN:
cprint("t%p", menu);
if (sym_is_changable(sym)) if (sym_is_changable(sym))
cprint1("[%c]", val == no ? ' ' : '*'); item_make("[%c]", val == no ? ' ' : '*');
else else
cprint1("---"); item_make("---");
item_set_tag('t');
item_set_data(menu);
break; break;
case S_TRISTATE: case S_TRISTATE:
cprint("t%p", menu);
switch (val) { switch (val) {
case yes: ch = '*'; break; case yes: ch = '*'; break;
case mod: ch = 'M'; break; case mod: ch = 'M'; break;
default: ch = ' '; break; default: ch = ' '; break;
} }
if (sym_is_changable(sym)) if (sym_is_changable(sym))
cprint1("<%c>", ch); item_make("<%c>", ch);
else else
cprint1("---"); item_make("---");
item_set_tag('t');
item_set_data(menu);
break; break;
default: default:
cprint("s%p", menu); tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
tmp = cprint1("(%s)", sym_get_string_value(sym)); item_make("(%s)", sym_get_string_value(sym));
tmp = indent - tmp + 4; tmp = indent - tmp + 4;
if (tmp < 0) if (tmp < 0)
tmp = 0; tmp = 0;
cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
(sym_has_value(sym) || !sym_is_changable(sym)) ? (sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : " (NEW)"); "" : " (NEW)");
cprint_done(); item_set_tag('s');
item_set_data(menu);
goto conf_childs; goto conf_childs;
} }
} }
cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
(sym_has_value(sym) || !sym_is_changable(sym)) ? (sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : " (NEW)"); "" : " (NEW)");
if (menu->prompt->type == P_MENU) { if (menu->prompt->type == P_MENU) {
cprint1(" --->"); item_add_str(" --->");
cprint_done();
return; return;
} }
cprint_done();
} }
conf_childs: conf_childs:
...@@ -731,59 +585,43 @@ static void conf(struct menu *menu) ...@@ -731,59 +585,43 @@ static void conf(struct menu *menu)
struct menu *submenu; struct menu *submenu;
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
struct symbol *sym; struct symbol *sym;
char active_entry[40]; struct menu *active_menu = NULL;
int stat, type, i; int res;
int s_scroll = 0;
unlink("lxdialog.scrltmp");
active_entry[0] = 0;
while (1) { while (1) {
cprint_init(); item_reset();
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);
current_menu = menu; current_menu = menu;
build_conf(menu); build_conf(menu);
if (!child_count) if (!child_count)
break; break;
if (menu == &rootmenu) { if (menu == &rootmenu) {
cprint(":"); item_make("--- ");
cprint("--- "); item_set_tag(':');
cprint("L"); item_make(_(" Load an Alternate Configuration File"));
cprint(_(" Load an Alternate Configuration File")); item_set_tag('L');
cprint("S"); item_make(_(" Save an Alternate Configuration File"));
cprint(_(" Save Configuration to an Alternate File")); item_set_tag('S');
} }
stat = exec_conf(); reset_dialog();
if (stat < 0) res = dialog_menu(prompt ? prompt : _("Main Menu"),
continue; _(menu_instructions),
rows, cols, rows - 10,
if (stat == 1 || stat == 255) active_menu, &s_scroll);
if (res == 1 || res == 255)
break; break;
if (!item_activate_selected())
type = input_buf[0]; continue;
if (!type) if (!item_tag())
continue; continue;
for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++) submenu = item_data();
; active_menu = item_data();
if (i >= sizeof(active_entry)) sym = submenu->sym;
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;
switch (stat) { switch (res) {
case 0: case 0:
switch (type) { switch (item_tag()) {
case 'm': case 'm':
if (single_menu_mode) if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data; submenu->data = (void *) (long) !submenu->data;
...@@ -814,7 +652,7 @@ static void conf(struct menu *menu) ...@@ -814,7 +652,7 @@ static void conf(struct menu *menu)
show_helptext("README", _(mconf_readme)); show_helptext("README", _(mconf_readme));
break; break;
case 3: case 3:
if (type == 't') { if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes)) if (sym_set_tristate_value(sym, yes))
break; break;
if (sym_set_tristate_value(sym, mod)) if (sym_set_tristate_value(sym, mod))
...@@ -822,17 +660,17 @@ static void conf(struct menu *menu) ...@@ -822,17 +660,17 @@ static void conf(struct menu *menu)
} }
break; break;
case 4: case 4:
if (type == 't') if (item_is_tag('t'))
sym_set_tristate_value(sym, no); sym_set_tristate_value(sym, no);
break; break;
case 5: case 5:
if (type == 't') if (item_is_tag('t'))
sym_set_tristate_value(sym, mod); sym_set_tristate_value(sym, mod);
break; break;
case 6: case 6:
if (type == 't') if (item_is_tag('t'))
sym_toggle_tristate_value(sym); sym_toggle_tristate_value(sym);
else if (type == 'm') else if (item_is_tag('m'))
conf(submenu); conf(submenu);
break; break;
case 7: case 7:
...@@ -844,13 +682,8 @@ static void conf(struct menu *menu) ...@@ -844,13 +682,8 @@ static void conf(struct menu *menu)
static void show_textbox(const char *title, const char *text, int r, int c) static void show_textbox(const char *title, const char *text, int r, int c)
{ {
int fd; reset_dialog();
dialog_textbox(title, text, r ? r : rows, c ? c : cols);
fd = creat(".help.tmp", 0777);
write(fd, text, strlen(text));
close(fd);
show_file(".help.tmp", title, r, c);
unlink(".help.tmp");
} }
static void show_helptext(const char *title, const char *text) static void show_helptext(const char *title, const char *text)
...@@ -878,62 +711,44 @@ static void show_help(struct menu *menu) ...@@ -878,62 +711,44 @@ static void show_help(struct menu *menu)
str_free(&help); 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) static void conf_choice(struct menu *menu)
{ {
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
struct menu *child; struct menu *child;
struct symbol *active; struct symbol *active;
int stat;
active = sym_get_choice_value(menu->sym); active = sym_get_choice_value(menu->sym);
while (1) { while (1) {
cprint_init(); int res;
cprint("--title"); int selected;
cprint("%s", prompt ? prompt : _("Main Menu")); item_reset();
cprint("--radiolist");
cprint(_(radiolist_instructions));
cprint("15");
cprint("70");
cprint("6");
current_menu = menu; current_menu = menu;
for (child = menu->list; child; child = child->next) { for (child = menu->list; child; child = child->next) {
if (!menu_is_visible(child)) if (!menu_is_visible(child))
continue; continue;
cprint("%p", child); item_make("%s", menu_get_prompt(child));
cprint("%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)) if (child->sym == sym_get_choice_value(menu->sym))
cprint("ON"); item_set_tag('X');
else if (child->sym == active)
cprint("SELECTED");
else
cprint("OFF");
} }
reset_dialog();
stat = exec_conf(); res = dialog_checklist(prompt ? prompt : _("Main Menu"),
switch (stat) { _(radiolist_instructions),
15, 70, 6);
selected = item_activate_selected();
switch (res) {
case 0: case 0:
if (sscanf(input_buf, "%p", &child) != 1) if (selected) {
break; child = item_data();
sym_set_tristate_value(child->sym, yes); sym_set_tristate_value(child->sym, yes);
}
return; return;
case 1: case 1:
if (sscanf(input_buf, "%p", &child) == 1) { if (selected) {
child = item_data();
show_help(child); show_help(child);
active = child->sym; active = child->sym;
} else } else
...@@ -948,33 +763,31 @@ static void conf_choice(struct menu *menu) ...@@ -948,33 +763,31 @@ static void conf_choice(struct menu *menu)
static void conf_string(struct menu *menu) static void conf_string(struct menu *menu)
{ {
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
int stat;
while (1) { while (1) {
cprint_init(); int res;
cprint("--title"); char *heading;
cprint("%s", prompt ? prompt : _("Main Menu"));
cprint("--inputbox");
switch (sym_get_type(menu->sym)) { switch (sym_get_type(menu->sym)) {
case S_INT: case S_INT:
cprint(_(inputbox_instructions_int)); heading = _(inputbox_instructions_int);
break; break;
case S_HEX: case S_HEX:
cprint(_(inputbox_instructions_hex)); heading = _(inputbox_instructions_hex);
break; break;
case S_STRING: case S_STRING:
cprint(_(inputbox_instructions_string)); heading = _(inputbox_instructions_string);
break; break;
default: default:
/* panic? */; heading = "Internal mconf error!";
} }
cprint("10"); reset_dialog();
cprint("75"); res = dialog_inputbox(prompt ? prompt : _("Main Menu"),
cprint("%s", sym_get_string_value(menu->sym)); heading, 10, 75,
stat = exec_conf(); sym_get_string_value(menu->sym));
switch (stat) { switch (res) {
case 0: case 0:
if (sym_set_string_value(menu->sym, input_buf)) if (sym_set_string_value(menu->sym, dialog_input_result))
return; return;
show_textbox(NULL, _("You have made an invalid entry."), 5, 43); show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
break; break;
...@@ -989,21 +802,17 @@ static void conf_string(struct menu *menu) ...@@ -989,21 +802,17 @@ static void conf_string(struct menu *menu)
static void conf_load(void) static void conf_load(void)
{ {
int stat;
while (1) { while (1) {
cprint_init(); int res;
cprint("--inputbox"); reset_dialog();
cprint(load_config_text); res = dialog_inputbox(NULL, load_config_text,
cprint("11"); 11, 55, filename);
cprint("55"); switch(res) {
cprint("%s", filename);
stat = exec_conf();
switch(stat) {
case 0: case 0:
if (!input_buf[0]) if (!dialog_input_result[0])
return; return;
if (!conf_read(input_buf)) if (!conf_read(dialog_input_result))
return; return;
show_textbox(NULL, _("File does not exist!"), 5, 38); show_textbox(NULL, _("File does not exist!"), 5, 38);
break; break;
...@@ -1018,21 +827,16 @@ static void conf_load(void) ...@@ -1018,21 +827,16 @@ static void conf_load(void)
static void conf_save(void) static void conf_save(void)
{ {
int stat;
while (1) { while (1) {
cprint_init(); int res;
cprint("--inputbox"); reset_dialog();
cprint(save_config_text); res = dialog_inputbox(NULL, save_config_text,
cprint("11"); 11, 55, filename);
cprint("55"); switch(res) {
cprint("%s", filename);
stat = exec_conf();
switch(stat) {
case 0: case 0:
if (!input_buf[0]) if (!dialog_input_result[0])
return; return;
if (!conf_write(input_buf)) if (!conf_write(dialog_input_result))
return; return;
show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
break; break;
...@@ -1048,15 +852,13 @@ static void conf_save(void) ...@@ -1048,15 +852,13 @@ static void conf_save(void)
static void conf_cleanup(void) static void conf_cleanup(void)
{ {
tcsetattr(1, TCSAFLUSH, &ios_org); tcsetattr(1, TCSAFLUSH, &ios_org);
unlink(".help.tmp");
unlink("lxdialog.scrltmp");
} }
int main(int ac, char **av) int main(int ac, char **av)
{ {
struct symbol *sym; struct symbol *sym;
char *mode; char *mode;
int stat; int res;
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
...@@ -1079,18 +881,16 @@ int main(int ac, char **av) ...@@ -1079,18 +881,16 @@ int main(int ac, char **av)
tcgetattr(1, &ios_org); tcgetattr(1, &ios_org);
atexit(conf_cleanup); atexit(conf_cleanup);
init_wsize(); init_wsize();
reset_dialog();
init_dialog(menu_backtitle);
conf(&rootmenu); conf(&rootmenu);
reset_dialog();
do { res = dialog_yesno(NULL,
cprint_init(); _("Do you wish to save your "
cprint("--yesno"); "new kernel configuration?"),
cprint(_("Do you wish to save your new kernel configuration?")); 5, 60);
cprint("5"); end_dialog();
cprint("60"); if (res == 0) {
stat = exec_conf();
} while (stat < 0);
if (stat == 0) {
if (conf_write(NULL)) { if (conf_write(NULL)) {
fprintf(stderr, _("\n\n" fprintf(stderr, _("\n\n"
"Error during writing of the kernel configuration.\n" "Error during writing of the kernel configuration.\n"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment