Skip to content

Commit

Permalink
kconfig/menuconfig: lxdialog is now built-in
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sam Ravnborg authored and Sam Ravnborg committed Sep 30, 2006
1 parent 350b5b7 commit 2982de6
Show file tree
Hide file tree
Showing 12 changed files with 502 additions and 1,019 deletions.
23 changes: 21 additions & 2 deletions scripts/kconfig/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ gconfig: $(obj)/gconf
$< arch/$(ARCH)/Kconfig

menuconfig: $(obj)/mconf
$(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
$< arch/$(ARCH)/Kconfig

config: $(obj)/conf
Expand Down Expand Up @@ -81,6 +80,23 @@ help:
@echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New config where all options are answered with no'

# lxdialog stuff
check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh

# Use reursively expanded variables so we do not call gcc unless
# we really need to do so. (Do not call gcc as part of make mrproper)
HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))

HOST_EXTRACFLAGS += -DLOCALE

PHONY += $(obj)/dochecklxdialog
$(obj)/dochecklxdialog:
$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)

always := dochecklxdialog


# ===========================================================================
# Shared Makefile for the various kconfig executables:
# conf: Used for defconfig, oldconfig and related targets
Expand All @@ -92,9 +108,12 @@ help:
# Based on GTK which needs to be installed to compile it
# object files used by all kconfig flavours

lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o

hostprogs-y := conf mconf qconf gconf kxgettext
conf-objs := conf.o zconf.tab.o
mconf-objs := mconf.o zconf.tab.o
mconf-objs := mconf.o zconf.tab.o $(lxdialog)
kxgettext-objs := kxgettext.o zconf.tab.o

ifeq ($(MAKECMDGOALS),xconfig)
Expand Down
21 changes: 0 additions & 21 deletions scripts/kconfig/lxdialog/Makefile

This file was deleted.

136 changes: 55 additions & 81 deletions scripts/kconfig/lxdialog/checklist.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ static int list_width, check_x, item_x;
/*
* Print list item
*/
static void print_item(WINDOW * win, const char *item, int status, int choice,
int selected)
static void print_item(WINDOW * win, int choice, int selected)
{
int i;

Expand All @@ -42,12 +41,12 @@ static void print_item(WINDOW * win, const char *item, int status, int choice,
wmove(win, choice, check_x);
wattrset(win, selected ? dlg.check_selected.atr
: dlg.check.atr);
wprintw(win, "(%c)", status ? 'X' : ' ');
wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');

wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
mvwaddch(win, choice, item_x, item[0]);
mvwaddch(win, choice, item_x, item_str()[0]);
wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
waddstr(win, (char *)item + 1);
waddstr(win, (char *)item_str() + 1);
if (selected) {
wmove(win, choice, check_x + 1);
wrefresh(win);
Expand Down Expand Up @@ -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).
*/
int dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height, int item_no,
const char *const *items)
int width, int list_height)
{
int i, x, y, box_x, box_y;
int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
WINDOW *dialog, *list;

/* Allocate space for storing item on/off status */
if ((status = malloc(sizeof(int) * item_no)) == NULL) {
endwin();
fprintf(stderr,
"\nCan't allocate memory in dialog_checklist().\n");
exit(-1);
}

/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = !strcasecmp(items[i * 3 + 2], "on");
if ((!choice && status[i])
|| !strcasecmp(items[i * 3 + 2], "selected"))
choice = i + 1;
/* which item to highlight */
item_foreach() {
if (item_is_tag('X'))
choice = item_n();
if (item_is_selected()) {
choice = item_n();
break;
}
}
if (choice)
choice--;

max_choice = MIN(list_height, item_no);
max_choice = MIN(list_height, item_count());

/* center dialog box on screen */
x = (COLS - width) / 2;
Expand Down Expand Up @@ -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 */
check_x = 0;
for (i = 0; i < item_no; i++)
check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
item_foreach()
check_x = MAX(check_x, strlen(item_str()) + 4);

check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
Expand All @@ -189,14 +179,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,

/* Print the list */
for (i = 0; i < max_choice; i++) {
if (i != choice)
print_item(list, items[(scroll + i) * 3 + 1],
status[i + scroll], i, 0);
item_set(scroll + i);
print_item(list, i, i == choice);
}
print_item(list, items[(scroll + choice) * 3 + 1],
status[choice + scroll], choice, 1);

print_arrows(dialog, choice, item_no, scroll,
print_arrows(dialog, choice, item_count(), scroll,
box_y, box_x + check_x + 5, list_height);

print_buttons(dialog, height, width, 0);
Expand All @@ -208,10 +195,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
while (key != ESC) {
key = wgetch(dialog);

for (i = 0; i < max_choice; i++)
if (toupper(key) ==
toupper(items[(scroll + i) * 3 + 1][0]))
for (i = 0; i < max_choice; i++) {
item_set(i + scroll);
if (toupper(key) == toupper(item_str()[0]))
break;
}

if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
key == '+' || key == '-') {
Expand All @@ -222,15 +210,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Scroll list down */
if (list_height > 1) {
/* De-highlight current first item */
print_item(list, items[scroll * 3 + 1],
status[scroll], 0, FALSE);
item_set(scroll);
print_item(list, 0, FALSE);
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
print_arrows(dialog, choice, item_no,
item_set(scroll);
print_item(list, 0, TRUE);
print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height);

wnoutrefresh(dialog);
Expand All @@ -241,23 +230,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
i = choice - 1;
} else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll + choice >= item_no - 1)
if (scroll + choice >= item_count() - 1)
continue;
/* Scroll list up */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1],
max_choice - 1, FALSE);
item_set(scroll + max_choice - 1);
print_item(list,
max_choice - 1,
FALSE);
scrollok(list, TRUE);
wscrl(list, 1);
scrollok(list, FALSE);
}
scroll++;
print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1], max_choice - 1, TRUE);
item_set(scroll + max_choice - 1);
print_item(list, max_choice - 1, TRUE);

print_arrows(dialog, choice, item_no,
print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height);

wnoutrefresh(dialog);
Expand All @@ -269,12 +259,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
}
if (i != choice) {
/* De-highlight current item */
print_item(list, items[(scroll + choice) * 3 + 1],
status[scroll + choice], choice, FALSE);
item_set(scroll + choice);
print_item(list, choice, FALSE);
/* Highlight new item */
choice = i;
print_item(list, items[(scroll + choice) * 3 + 1],
status[scroll + choice], choice, TRUE);
item_set(scroll + choice);
print_item(list, choice, TRUE);
wnoutrefresh(dialog);
wrefresh(list);
}
Expand All @@ -284,10 +274,19 @@ int dialog_checklist(const char *title, const char *prompt, int height,
case 'H':
case 'h':
case '?':
fprintf(stderr, "%s", items[(scroll + choice) * 3]);
button = 1;
/* fall-through */
case 'S':
case 's':
case ' ':
case '\n':
item_foreach()
item_set_selected(0);
item_set(scroll + choice);
item_set_selected(1);
delwin(list);
delwin(dialog);
free(status);
return 1;
return button;
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
Expand All @@ -297,30 +296,6 @@ int dialog_checklist(const char *title, const char *prompt, int height,
print_buttons(dialog, height, width, button);
wrefresh(dialog);
break;
case 'S':
case 's':
case ' ':
case '\n':
if (!button) {
if (!status[scroll + choice]) {
for (i = 0; i < item_no; i++)
status[i] = 0;
status[scroll + choice] = 1;
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll + i) * 3 + 1],
status[scroll + i], i, i == choice);
}
wnoutrefresh(dialog);
wrefresh(list);

for (i = 0; i < item_no; i++)
if (status[i])
fprintf(stderr, "%s", items[i * 3]);
} else
fprintf(stderr, "%s", items[(scroll + choice) * 3]);
delwin(dialog);
free(status);
return button;
case 'X':
case 'x':
key = ESC;
Expand All @@ -331,8 +306,7 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Now, update everything... */
doupdate();
}

delwin(list);
delwin(dialog);
free(status);
return -1; /* ESC pressed */
return 255; /* ESC pressed */
}
52 changes: 47 additions & 5 deletions scripts/kconfig/lxdialog/dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,55 @@ struct dialog_info {
* Global variables
*/
extern struct dialog_info dlg;
extern char dialog_input_result[];

/*
* Function prototypes
*/
void init_dialog(void);

/* item list as used by checklist and menubox */
void item_reset(void);
void item_make(const char *fmt, ...);
void item_add_str(const char *fmt, ...);
void item_set_tag(char tag);
void item_set_data(void *p);
void item_set_selected(int val);
int item_activate_selected(void);
void *item_data(void);
char item_tag(void);

/* item list manipulation for lxdialog use */
#define MAXITEMSTR 200
struct dialog_item {
char str[MAXITEMSTR]; /* promtp displayed */
char tag;
void *data; /* pointer to menu item - used by menubox+checklist */
int selected; /* Set to 1 by dialog_*() function if selected. */
};

/* list of lialog_items */
struct dialog_list {
struct dialog_item node;
struct dialog_list *next;
};

extern struct dialog_list *item_cur;
extern struct dialog_list item_nil;
extern struct dialog_list *item_head;

int item_count(void);
void item_set(int n);
int item_n(void);
const char *item_str(void);
int item_is_selected(void);
int item_is_tag(char tag);
#define item_foreach() \
for (item_cur = item_head ? item_head: item_cur; \
item_cur && (item_cur != &item_nil); item_cur = item_cur->next)


void init_dialog(const char *backtitle);
void reset_dialog(void);
void end_dialog(void);
void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void);
Expand All @@ -154,11 +198,9 @@ int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
int dialog_textbox(const char *title, const char *file, int height, int width);
int dialog_menu(const char *title, const char *prompt, int height, int width,
int menu_height, const char *choice, int item_no,
const char *const *items);
int menu_height, const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height, int item_no,
const char *const *items);
int width, int list_height);
extern char dialog_input_result[];
int dialog_inputbox(const char *title, const char *prompt, int height,
int width, const char *init);
Expand Down
2 changes: 1 addition & 1 deletion scripts/kconfig/lxdialog/inputbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,5 +222,5 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
}

delwin(dialog);
return -1; /* ESC pressed */
return 255; /* ESC pressed */
}
Loading

0 comments on commit 2982de6

Please sign in to comment.