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>
This commit is contained in:
parent
350b5b7638
commit
2982de6993
|
@ -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:
|
||||||
@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:
|
||||||
# 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)
|
||||||
|
|
|
@ -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
|
|
|
@ -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,
|
||||||
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)
|
||||||
* 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 */
|
max_choice = MIN(list_height, item_count());
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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,
|
||||||
|
|
||||||
/* 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,
|
||||||
|
|
||||||
/* 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,
|
||||||
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,
|
||||||
/* 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
/* 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 {
|
||||||
* 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,
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
delwin(dialog);
|
delwin(dialog);
|
||||||
return -1; /* ESC pressed */
|
return 255; /* ESC pressed */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -101,8 +101,8 @@ static void do_print_item(WINDOW * win, const char *item, int choice,
|
||||||
|
|
||||||
#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)
|
||||||
* 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,
|
||||||
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) &&
|
|
||||||
(scroll + max_choice <= item_no)) {
|
|
||||||
first_item = scroll;
|
first_item = scroll;
|
||||||
choice = choice - scroll;
|
choice = choice - scroll;
|
||||||
fclose(f);
|
|
||||||
} else {
|
} else {
|
||||||
scroll = 0;
|
scroll = 0;
|
||||||
remove("lxdialog.scrltmp");
|
|
||||||
fclose(f);
|
|
||||||
f = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
if ((choice >= max_choice)) {
|
||||||
if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
|
if (choice >= item_count() - max_choice / 2)
|
||||||
if (choice >= item_no - max_choice / 2)
|
scroll = first_item = item_count() - max_choice;
|
||||||
scroll = first_item = item_no - 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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
} 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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delwin(menu);
|
||||||
delwin(dialog);
|
delwin(dialog);
|
||||||
remove("lxdialog.scrltmp");
|
return 255; /* ESC pressed */
|
||||||
return -1; /* ESC pressed */
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -27,53 +27,26 @@ 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");
|
|
||||||
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 */
|
page = buf; /* page is pointer to start of page to be displayed */
|
||||||
|
|
||||||
/* center dialog box on screen */
|
/* center dialog box on screen */
|
||||||
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,124 +232,43 @@ 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 (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;
|
begin_reached = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
page--;
|
||||||
if (*(--page) != '\n') { /* '--page' here */
|
|
||||||
/* Something's wrong... */
|
|
||||||
endwin();
|
|
||||||
fprintf(stderr, "\nInternal error in back_lines().\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* 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) {
|
|
||||||
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;
|
begin_reached = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
page--;
|
||||||
} while (*(--page) != '\n');
|
} while (*page != '\n');
|
||||||
page++;
|
page++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print a new page of text. Called by dialog_textbox().
|
* Print a new page of text. Called by dialog_textbox().
|
||||||
|
@ -467,32 +322,13 @@ 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) {
|
|
||||||
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;
|
end_reached = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
delwin(dialog);
|
delwin(dialog);
|
||||||
return -1; /* ESC pressed */
|
return 255; /* ESC pressed */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_(
|
||||||
" 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);
|
||||||
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)
|
||||||
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)
|
||||||
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:
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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))
|
|
||||||
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;
|
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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"
|
||||||
|
|
Loading…
Reference in New Issue