diff options
Diffstat (limited to 'scripts/kconfig/lxdialog')
| -rw-r--r-- | scripts/kconfig/lxdialog/check-lxdialog.sh | 15 | ||||
| -rw-r--r-- | scripts/kconfig/lxdialog/checklist.c | 12 | ||||
| -rw-r--r-- | scripts/kconfig/lxdialog/dialog.h | 31 | ||||
| -rw-r--r-- | scripts/kconfig/lxdialog/inputbox.c | 131 | ||||
| -rw-r--r-- | scripts/kconfig/lxdialog/menubox.c | 39 | ||||
| -rw-r--r-- | scripts/kconfig/lxdialog/textbox.c | 183 | ||||
| -rw-r--r-- | scripts/kconfig/lxdialog/util.c | 94 | ||||
| -rw-r--r-- | scripts/kconfig/lxdialog/yesno.c | 8 | 
8 files changed, 341 insertions, 172 deletions
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 82cc3a85e7f..9d2a4c585ee 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -4,7 +4,9 @@  # What library to link  ldflags()  { -	for ext in so a dylib ; do +	pkg-config --libs ncursesw 2>/dev/null && exit +	pkg-config --libs ncurses 2>/dev/null && exit +	for ext in so a dll.a dylib ; do  		for lib in ncursesw ncurses curses ; do  			$cc -print-file-name=lib${lib}.${ext} | grep -q /  			if [ $? -eq 0 ]; then @@ -19,12 +21,13 @@ ldflags()  # Where is ncurses.h?  ccflags()  { -	if [ -f /usr/include/ncurses/ncurses.h ]; then +	if [ -f /usr/include/ncursesw/curses.h ]; then +		echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"' +		echo ' -DNCURSES_WIDECHAR=1' +	elif [ -f /usr/include/ncurses/ncurses.h ]; then  		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'  	elif [ -f /usr/include/ncurses/curses.h ]; then -		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"' -	elif [ -f /usr/include/ncursesw/curses.h ]; then -		echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"' +		echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'  	elif [ -f /usr/include/ncurses.h ]; then  		echo '-DCURSES_LOC="<ncurses.h>"'  	else @@ -38,7 +41,7 @@ trap "rm -f $tmp" 0 1 2 3 15  # Check if we can link to ncurses  check() { -        $cc -xc - -o $tmp 2>/dev/null <<'EOF' +        $cc -x c - -o $tmp 2>/dev/null <<'EOF'  #include CURSES_LOC  main() {}  EOF diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index a2eb80fbc89..8d016faa28d 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -132,16 +132,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,  	}  do_resize: -	if (getmaxy(stdscr) < (height + 6)) +	if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN))  		return -ERRDISPLAYTOOSMALL; -	if (getmaxx(stdscr) < (width + 6)) +	if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN))  		return -ERRDISPLAYTOOSMALL;  	max_choice = MIN(list_height, item_count());  	/* center dialog box on screen */ -	x = (COLS - width) / 2; -	y = (LINES - height) / 2; +	x = (getmaxx(stdscr) - width) / 2; +	y = (getmaxy(stdscr) - height) / 2;  	draw_shadow(stdscr, y, x, height, width); @@ -168,13 +168,13 @@ do_resize:  	/* create new window for the list */  	list = subwin(dialog, list_height, list_width, y + box_y + 1, -	              x + box_x + 1); +		      x + box_x + 1);  	keypad(list, TRUE);  	/* draw a box around the list items */  	draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, -	         dlg.menubox_border.atr, dlg.menubox.atr); +		 dlg.menubox_border.atr, dlg.menubox.atr);  	/* Find length of longest item in order to center checklist */  	check_x = 0; diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index b5211fce0d9..b4343d38492 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h @@ -106,8 +106,14 @@ struct dialog_color {  	int hl;		/* highlight this item */  }; +struct subtitle_list { +	struct subtitle_list *next; +	const char *text; +}; +  struct dialog_info {  	const char *backtitle; +	struct subtitle_list *subtitles;  	struct dialog_color screen;  	struct dialog_color shadow;  	struct dialog_color dialog; @@ -144,6 +150,7 @@ struct dialog_info {   */  extern struct dialog_info dlg;  extern char dialog_input_result[]; +extern int saved_x, saved_y;		/* Needed in signal handler in mconf.c */  /*   * Function prototypes @@ -193,8 +200,23 @@ int item_is_tag(char tag);  int on_key_esc(WINDOW *win);  int on_key_resize(void); +/* minimum (re)size values */ +#define CHECKLIST_HEIGTH_MIN 6	/* For dialog_checklist() */ +#define CHECKLIST_WIDTH_MIN 6 +#define INPUTBOX_HEIGTH_MIN 2	/* For dialog_inputbox() */ +#define INPUTBOX_WIDTH_MIN 2 +#define MENUBOX_HEIGTH_MIN 15	/* For dialog_menu() */ +#define MENUBOX_WIDTH_MIN 65 +#define TEXTBOX_HEIGTH_MIN 8	/* For dialog_textbox() */ +#define TEXTBOX_WIDTH_MIN 8 +#define YESNO_HEIGTH_MIN 4	/* For dialog_yesno() */ +#define YESNO_WIDTH_MIN 4 +#define WINDOW_HEIGTH_MIN 19	/* For init_dialog() */ +#define WINDOW_WIDTH_MIN 80 +  int init_dialog(const char *backtitle);  void set_dialog_backtitle(const char *backtitle); +void set_dialog_subtitles(struct subtitle_list *subtitles);  void end_dialog(int x, int y);  void attr_clear(WINDOW * win, int height, int width, chtype attr);  void dialog_clear(void); @@ -209,12 +231,17 @@ int first_alpha(const char *string, const char *exempt);  int dialog_yesno(const char *title, const char *prompt, int height, int width);  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); + + +typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void +			       *_data); +int dialog_textbox(const char *title, char *tbuf, int initial_height, +		   int initial_width, int *keys, int *_vscroll, int *_hscroll, +		   update_text_fn update_text, void *data);  int dialog_menu(const char *title, const char *prompt,  		const void *selected, int *s_scroll);  int dialog_checklist(const char *title, const char *prompt, int height,  		     int width, int list_height); -extern char dialog_input_result[];  int dialog_inputbox(const char *title, const char *prompt, int height,  		    int width, const char *init); diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index dd8e587c50e..d58de1dc536 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -42,10 +42,11 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)   * Display a dialog box for inputing a string   */  int dialog_inputbox(const char *title, const char *prompt, int height, int width, -                    const char *init) +		    const char *init)  {  	int i, x, y, box_y, box_x, box_width; -	int input_x = 0, scroll = 0, key = 0, button = -1; +	int input_x = 0, key = 0, button = -1; +	int show_x, len, pos;  	char *instr = dialog_input_result;  	WINDOW *dialog; @@ -55,14 +56,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width  		strcpy(instr, init);  do_resize: -	if (getmaxy(stdscr) <= (height - 2)) +	if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN))  		return -ERRDISPLAYTOOSMALL; -	if (getmaxx(stdscr) <= (width - 2)) +	if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN))  		return -ERRDISPLAYTOOSMALL;  	/* center dialog box on screen */ -	x = (COLS - width) / 2; -	y = (LINES - height) / 2; +	x = (getmaxx(stdscr) - width) / 2; +	y = (getmaxy(stdscr) - height) / 2;  	draw_shadow(stdscr, y, x, height, width); @@ -97,14 +98,17 @@ do_resize:  	wmove(dialog, box_y, box_x);  	wattrset(dialog, dlg.inputbox.atr); -	input_x = strlen(instr); +	len = strlen(instr); +	pos = len; -	if (input_x >= box_width) { -		scroll = input_x - box_width + 1; +	if (len >= box_width) { +		show_x = len - box_width + 1;  		input_x = box_width - 1;  		for (i = 0; i < box_width - 1; i++) -			waddch(dialog, instr[scroll + i]); +			waddch(dialog, instr[show_x + i]);  	} else { +		show_x = 0; +		input_x = len;  		waddstr(dialog, instr);  	} @@ -121,45 +125,104 @@ do_resize:  			case KEY_UP:  			case KEY_DOWN:  				break; -			case KEY_LEFT: -				continue; -			case KEY_RIGHT: -				continue;  			case KEY_BACKSPACE:  			case 127: -				if (input_x || scroll) { +				if (pos) {  					wattrset(dialog, dlg.inputbox.atr); -					if (!input_x) { -						scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); -						wmove(dialog, box_y, box_x); -						for (i = 0; i < box_width; i++) -							waddch(dialog, -							       instr[scroll + input_x + i] ? -							       instr[scroll + input_x + i] : ' '); -						input_x = strlen(instr) - scroll; +					if (input_x == 0) { +						show_x--;  					} else  						input_x--; -					instr[scroll + input_x] = '\0'; -					mvwaddch(dialog, box_y, input_x + box_x, ' '); + +					if (pos < len) { +						for (i = pos - 1; i < len; i++) { +							instr[i] = instr[i+1]; +						} +					} + +					pos--; +					len--; +					instr[len] = '\0'; +					wmove(dialog, box_y, box_x); +					for (i = 0; i < box_width; i++) { +						if (!instr[show_x + i]) { +							waddch(dialog, ' '); +							break; +						} +						waddch(dialog, instr[show_x + i]); +					}  					wmove(dialog, box_y, input_x + box_x);  					wrefresh(dialog);  				}  				continue; +			case KEY_LEFT: +				if (pos > 0) { +					if (input_x > 0) { +						wmove(dialog, box_y, --input_x + box_x); +					} else if (input_x == 0) { +						show_x--; +						wmove(dialog, box_y, box_x); +						for (i = 0; i < box_width; i++) { +							if (!instr[show_x + i]) { +								waddch(dialog, ' '); +								break; +							} +							waddch(dialog, instr[show_x + i]); +						} +						wmove(dialog, box_y, box_x); +					} +					pos--; +				} +				continue; +			case KEY_RIGHT: +				if (pos < len) { +					if (input_x < box_width - 1) { +						wmove(dialog, box_y, ++input_x + box_x); +					} else if (input_x == box_width - 1) { +						show_x++; +						wmove(dialog, box_y, box_x); +						for (i = 0; i < box_width; i++) { +							if (!instr[show_x + i]) { +								waddch(dialog, ' '); +								break; +							} +							waddch(dialog, instr[show_x + i]); +						} +						wmove(dialog, box_y, input_x + box_x); +					} +					pos++; +				} +				continue;  			default:  				if (key < 0x100 && isprint(key)) { -					if (scroll + input_x < MAX_LEN) { +					if (len < MAX_LEN) {  						wattrset(dialog, dlg.inputbox.atr); -						instr[scroll + input_x] = key; -						instr[scroll + input_x + 1] = '\0'; +						if (pos < len) { +							for (i = len; i > pos; i--) +								instr[i] = instr[i-1]; +							instr[pos] = key; +						} else { +							instr[len] = key; +						} +						pos++; +						len++; +						instr[len] = '\0'; +  						if (input_x == box_width - 1) { -							scroll++; -							wmove(dialog, box_y, box_x); -							for (i = 0; i < box_width - 1; i++) -								waddch(dialog, instr [scroll + i]); +							show_x++;  						} else { -							wmove(dialog, box_y, input_x++ + box_x); -							waddch(dialog, key); +							input_x++; +						} + +						wmove(dialog, box_y, box_x); +						for (i = 0; i < box_width; i++) { +							if (!instr[show_x + i]) { +								waddch(dialog, ' '); +								break; +							} +							waddch(dialog, instr[show_x + i]);  						} +						wmove(dialog, box_y, input_x + box_x);  						wrefresh(dialog);  					} else  						flash();	/* Alarm user about overflow */ diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 1d604738fa1..11ae9ad7ac7 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -26,7 +26,7 @@   *   *    *)  A bugfix for the Page-Down problem   * - *    *)  Formerly when I used Page Down and Page Up, the cursor would be set  + *    *)  Formerly when I used Page Down and Page Up, the cursor would be set   *        to the first position in the menu box.  Now lxdialog is a bit   *        smarter and works more like other menu systems (just have a look at   *        it). @@ -64,7 +64,7 @@ static int menu_width, item_x;   * Print menu item   */  static void do_print_item(WINDOW * win, const char *item, int line_y, -                          int selected, int hotkey) +			  int selected, int hotkey)  {  	int j;  	char *menu_item = malloc(menu_width + 1); @@ -154,12 +154,14 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,   */  static void print_buttons(WINDOW * win, int height, int width, int selected)  { -	int x = width / 2 - 16; +	int x = width / 2 - 28;  	int y = height - 2;  	print_button(win, gettext("Select"), y, x, selected == 0);  	print_button(win, gettext(" Exit "), y, x + 12, selected == 1);  	print_button(win, gettext(" Help "), y, x + 24, selected == 2); +	print_button(win, gettext(" Save "), y, x + 36, selected == 3); +	print_button(win, gettext(" Load "), y, x + 48, selected == 4);  	wmove(win, y, x + 1 + 12 * selected);  	wrefresh(win); @@ -180,7 +182,7 @@ static void do_scroll(WINDOW *win, int *scroll, int n)   * Display a menu for choosing among a number of options   */  int dialog_menu(const char *title, const char *prompt, -                const void *selected, int *s_scroll) +		const void *selected, int *s_scroll)  {  	int i, j, x, y, box_x, box_y;  	int height, width, menu_height; @@ -191,7 +193,7 @@ int dialog_menu(const char *title, const char *prompt,  do_resize:  	height = getmaxy(stdscr);  	width = getmaxx(stdscr); -	if (height < 15 || width < 65) +	if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)  		return -ERRDISPLAYTOOSMALL;  	height -= 4; @@ -201,8 +203,8 @@ do_resize:  	max_choice = MIN(menu_height, item_count());  	/* center dialog box on screen */ -	x = (COLS - width) / 2; -	y = (LINES - height) / 2; +	x = (getmaxx(stdscr) - width) / 2; +	y = (getmaxy(stdscr) - height) / 2;  	draw_shadow(stdscr, y, x, height, width); @@ -301,10 +303,11 @@ do_resize:  				}  		} -		if (i < max_choice || -		    key == KEY_UP || key == KEY_DOWN || -		    key == '-' || key == '+' || -		    key == KEY_PPAGE || key == KEY_NPAGE) { +		if (item_count() != 0 && +		    (i < max_choice || +		     key == KEY_UP || key == KEY_DOWN || +		     key == '-' || key == '+' || +		     key == KEY_PPAGE || key == KEY_NPAGE)) {  			/* Remove highligt of current item */  			print_item(scroll + choice, choice, FALSE); @@ -372,7 +375,7 @@ do_resize:  		case TAB:  		case KEY_RIGHT:  			button = ((key == KEY_LEFT ? --button : ++button) < 0) -			    ? 2 : (button > 2 ? 0 : button); +			    ? 4 : (button > 4 ? 0 : button);  			print_buttons(dialog, height, width, button);  			wrefresh(menu); @@ -399,17 +402,17 @@ do_resize:  				return 2;  			case 's':  			case 'y': -				return 3; +				return 5;  			case 'n': -				return 4; +				return 6;  			case 'm': -				return 5; +				return 7;  			case ' ': -				return 6; +				return 8;  			case '/': -				return 7; +				return 9;  			case 'z': -				return 8; +				return 10;  			case '\n':  				return button;  			} diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index c704712d022..1773319b95e 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -22,23 +22,25 @@  #include "dialog.h"  static void back_lines(int n); -static void print_page(WINDOW * win, int height, int width); -static void print_line(WINDOW * win, int row, int width); +static void print_page(WINDOW *win, int height, int width, update_text_fn +		       update_text, void *data); +static void print_line(WINDOW *win, int row, int width);  static char *get_line(void);  static void print_position(WINDOW * win);  static int hscroll;  static int begin_reached, end_reached, page_length; -static const char *buf; -static const char *page; +static char *buf; +static char *page;  /*   * refresh window content   */  static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, -							  int cur_y, int cur_x) +			     int cur_y, int cur_x, update_text_fn update_text, +			     void *data)  { -	print_page(box, boxh, boxw); +	print_page(box, boxh, boxw, update_text, data);  	print_position(dialog);  	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */  	wrefresh(dialog); @@ -47,14 +49,18 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,  /*   * Display text from a file in a dialog box. + * + * keys is a null-terminated array + * update_text() may not add or remove any '\n' or '\0' in tbuf   */ -int dialog_textbox(const char *title, const char *tbuf, -		   int initial_height, int initial_width) +int dialog_textbox(const char *title, char *tbuf, int initial_height, +		   int initial_width, int *keys, int *_vscroll, int *_hscroll, +		   update_text_fn update_text, void *data)  {  	int i, x, y, cur_x, cur_y, key = 0;  	int height, width, boxh, boxw; -	int passed_end;  	WINDOW *dialog, *box; +	bool done = false;  	begin_reached = 1;  	end_reached = 0; @@ -63,9 +69,18 @@ int dialog_textbox(const char *title, const char *tbuf,  	buf = tbuf;  	page = buf;	/* page is pointer to start of page to be displayed */ +	if (_vscroll && *_vscroll) { +		begin_reached = 0; + +		for (i = 0; i < *_vscroll; i++) +			get_line(); +	} +	if (_hscroll) +		hscroll = *_hscroll; +  do_resize:  	getmaxyx(stdscr, height, width); -	if (height < 8 || width < 8) +	if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)  		return -ERRDISPLAYTOOSMALL;  	if (initial_height != 0)  		height = initial_height; @@ -83,8 +98,8 @@ do_resize:  			width = 0;  	/* center dialog box on screen */ -	x = (COLS - width) / 2; -	y = (LINES - height) / 2; +	x = (getmaxx(stdscr) - width) / 2; +	y = (getmaxy(stdscr) - height) / 2;  	draw_shadow(stdscr, y, x, height, width); @@ -120,25 +135,28 @@ do_resize:  	/* Print first page of text */  	attr_clear(box, boxh, boxw, dlg.dialog.atr); -	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); +	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text, +			 data); -	while ((key != KEY_ESC) && (key != '\n')) { +	while (!done) {  		key = wgetch(dialog);  		switch (key) {  		case 'E':	/* Exit */  		case 'e':  		case 'X':  		case 'x': -			delwin(box); -			delwin(dialog); -			return 0; +		case 'q': +		case '\n': +			done = true; +			break;  		case 'g':	/* First page */  		case KEY_HOME:  			if (!begin_reached) {  				begin_reached = 1;  				page = buf;  				refresh_text_box(dialog, box, boxh, boxw, -						 cur_y, cur_x); +						 cur_y, cur_x, update_text, +						 data);  			}  			break;  		case 'G':	/* Last page */ @@ -148,78 +166,48 @@ do_resize:  			/* point to last char in buf */  			page = buf + strlen(buf);  			back_lines(boxh); -			refresh_text_box(dialog, box, boxh, boxw, -					 cur_y, cur_x); +			refresh_text_box(dialog, box, boxh, boxw, cur_y, +					 cur_x, update_text, data);  			break;  		case 'K':	/* Previous line */  		case 'k':  		case KEY_UP: -			if (!begin_reached) { -				back_lines(page_length + 1); - -				/* We don't call print_page() here but use -				 * scrolling to ensure faster screen update. -				 * However, 'end_reached' and 'page_length' -				 * should still be updated, and 'page' should -				 * point to start of next page. This is done -				 * by calling get_line() in the following -				 * 'for' loop. */ -				scrollok(box, TRUE); -				wscrl(box, -1);	/* Scroll box region down one line */ -				scrollok(box, FALSE); -				page_length = 0; -				passed_end = 0; -				for (i = 0; i < boxh; i++) { -					if (!i) { -						/* print first line of page */ -						print_line(box, 0, boxw); -						wnoutrefresh(box); -					} else -						/* Called to update 'end_reached' and 'page' */ -						get_line(); -					if (!passed_end) -						page_length++; -					if (end_reached && !passed_end) -						passed_end = 1; -				} +			if (begin_reached) +				break; -				print_position(dialog); -				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */ -				wrefresh(dialog); -			} +			back_lines(page_length + 1); +			refresh_text_box(dialog, box, boxh, boxw, cur_y, +					 cur_x, update_text, data);  			break;  		case 'B':	/* Previous page */  		case 'b': +		case 'u':  		case KEY_PPAGE:  			if (begin_reached)  				break;  			back_lines(page_length + boxh); -			refresh_text_box(dialog, box, boxh, boxw, -					 cur_y, cur_x); +			refresh_text_box(dialog, box, boxh, boxw, cur_y, +					 cur_x, update_text, data);  			break;  		case 'J':	/* Next line */  		case 'j':  		case KEY_DOWN: -			if (!end_reached) { -				begin_reached = 0; -				scrollok(box, TRUE); -				scroll(box);	/* Scroll box region up one line */ -				scrollok(box, FALSE); -				print_line(box, boxh - 1, boxw); -				wnoutrefresh(box); -				print_position(dialog); -				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */ -				wrefresh(dialog); -			} +			if (end_reached) +				break; + +			back_lines(page_length - 1); +			refresh_text_box(dialog, box, boxh, boxw, cur_y, +					 cur_x, update_text, data);  			break;  		case KEY_NPAGE:	/* Next page */  		case ' ': +		case 'd':  			if (end_reached)  				break;  			begin_reached = 0; -			refresh_text_box(dialog, box, boxh, boxw, -					 cur_y, cur_x); +			refresh_text_box(dialog, box, boxh, boxw, cur_y, +					 cur_x, update_text, data);  			break;  		case '0':	/* Beginning of line */  		case 'H':	/* Scroll left */ @@ -234,8 +222,8 @@ do_resize:  				hscroll--;  			/* Reprint current page to scroll horizontally */  			back_lines(page_length); -			refresh_text_box(dialog, box, boxh, boxw, -					 cur_y, cur_x); +			refresh_text_box(dialog, box, boxh, boxw, cur_y, +					 cur_x, update_text, data);  			break;  		case 'L':	/* Scroll right */  		case 'l': @@ -245,11 +233,12 @@ do_resize:  			hscroll++;  			/* Reprint current page to scroll horizontally */  			back_lines(page_length); -			refresh_text_box(dialog, box, boxh, boxw, -					 cur_y, cur_x); +			refresh_text_box(dialog, box, boxh, boxw, cur_y, +					 cur_x, update_text, data);  			break;  		case KEY_ESC: -			key = on_key_esc(dialog); +			if (on_key_esc(dialog) == KEY_ESC) +				done = true;  			break;  		case KEY_RESIZE:  			back_lines(height); @@ -257,11 +246,31 @@ do_resize:  			delwin(dialog);  			on_key_resize();  			goto do_resize; +		default: +			for (i = 0; keys[i]; i++) { +				if (key == keys[i]) { +					done = true; +					break; +				} +			}  		}  	}  	delwin(box);  	delwin(dialog); -	return key;		/* ESC pressed */ +	if (_vscroll) { +		const char *s; + +		s = buf; +		*_vscroll = 0; +		back_lines(page_length); +		while (s < page && (s = strchr(s, '\n'))) { +			(*_vscroll)++; +			s++; +		} +	} +	if (_hscroll) +		*_hscroll = hscroll; +	return key;  }  /* @@ -298,12 +307,23 @@ static void back_lines(int n)  }  /* - * Print a new page of text. Called by dialog_textbox(). + * Print a new page of text.   */ -static void print_page(WINDOW * win, int height, int width) +static void print_page(WINDOW *win, int height, int width, update_text_fn +		       update_text, void *data)  {  	int i, passed_end = 0; +	if (update_text) { +		char *end; + +		for (i = 0; i < height; i++) +			get_line(); +		end = page; +		back_lines(height); +		update_text(buf, page - buf, end - buf, data); +	} +  	page_length = 0;  	for (i = 0; i < height; i++) {  		print_line(win, i, width); @@ -316,11 +336,10 @@ static void print_page(WINDOW * win, int height, int width)  }  /* - * Print a new line of text. Called by dialog_textbox() and print_page(). + * Print a new line of text.   */  static void print_line(WINDOW * win, int row, int width)  { -	int y, x;  	char *line;  	line = get_line(); @@ -329,10 +348,10 @@ static void print_line(WINDOW * win, int row, int width)  	waddch(win, ' ');  	waddnstr(win, line, MIN(strlen(line), width - 2)); -	getyx(win, y, x);  	/* Clear 'residue' of previous line */  #if OLD_NCURSES  	{ +		int x = getcurx(win);  		int i;  		for (i = 0; i < width - x; i++)  			waddch(win, ' '); @@ -355,10 +374,8 @@ static char *get_line(void)  	end_reached = 0;  	while (*page != '\n') {  		if (*page == '\0') { -			if (!end_reached) { -				end_reached = 1; -				break; -			} +			end_reached = 1; +			break;  		} else if (i < MAX_LEN)  			line[i++] = *(page++);  		else { @@ -371,7 +388,7 @@ static char *get_line(void)  	if (i <= MAX_LEN)  		line[i] = '\0';  	if (!end_reached) -		page++;		/* move pass '\n' */ +		page++;		/* move past '\n' */  	return line;  } diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index f2375ad7ebc..f7abdeb92af 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c @@ -23,6 +23,9 @@  #include "dialog.h" +/* Needed in signal handler in mconf.c */ +int saved_x, saved_y; +  struct dialog_info dlg;  static void set_mono_theme(void) @@ -251,15 +254,56 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr)  void dialog_clear(void)  { -	attr_clear(stdscr, LINES, COLS, dlg.screen.atr); +	int lines, columns; + +	lines = getmaxy(stdscr); +	columns = getmaxx(stdscr); + +	attr_clear(stdscr, lines, columns, dlg.screen.atr);  	/* Display background title if it exists ... - SLH */  	if (dlg.backtitle != NULL) { -		int i; +		int i, len = 0, skip = 0; +		struct subtitle_list *pos;  		wattrset(stdscr, dlg.screen.atr);  		mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); + +		for (pos = dlg.subtitles; pos != NULL; pos = pos->next) { +			/* 3 is for the arrow and spaces */ +			len += strlen(pos->text) + 3; +		} +  		wmove(stdscr, 1, 1); -		for (i = 1; i < COLS - 1; i++) +		if (len > columns - 2) { +			const char *ellipsis = "[...] "; +			waddstr(stdscr, ellipsis); +			skip = len - (columns - 2 - strlen(ellipsis)); +		} + +		for (pos = dlg.subtitles; pos != NULL; pos = pos->next) { +			if (skip == 0) +				waddch(stdscr, ACS_RARROW); +			else +				skip--; + +			if (skip == 0) +				waddch(stdscr, ' '); +			else +				skip--; + +			if (skip < strlen(pos->text)) { +				waddstr(stdscr, pos->text + skip); +				skip = 0; +			} else +				skip -= strlen(pos->text); + +			if (skip == 0) +				waddch(stdscr, ' '); +			else +				skip--; +		} + +		for (i = len + 1; i < columns - 1; i++)  			waddch(stdscr, ACS_HLINE);  	}  	wnoutrefresh(stdscr); @@ -273,8 +317,12 @@ int init_dialog(const char *backtitle)  	int height, width;  	initscr();		/* Init curses */ + +	/* Get current cursor position for signal handler in mconf.c */ +	getyx(stdscr, saved_y, saved_x); +  	getmaxyx(stdscr, height, width); -	if (height < 19 || width < 80) { +	if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) {  		endwin();  		return -ERRDISPLAYTOOSMALL;  	} @@ -295,6 +343,11 @@ void set_dialog_backtitle(const char *backtitle)  	dlg.backtitle = backtitle;  } +void set_dialog_subtitles(struct subtitle_list *subtitles) +{ +	dlg.subtitles = subtitles; +} +  /*   * End using dialog functions.   */ @@ -323,27 +376,19 @@ void print_title(WINDOW *dialog, const char *title, int width)  /*   * Print a string of text in a window, automatically wrap around to the   * next line if the string is too long to fit on one line. Newline - * characters '\n' are replaced by spaces.  We start on a new line + * characters '\n' are propperly processed.  We start on a new line   * if there is no room for at least 4 nonblanks following a double-space.   */  void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)  {  	int newl, cur_x, cur_y; -	int i, prompt_len, room, wlen; -	char tempstr[MAX_LEN + 1], *word, *sp, *sp2; +	int prompt_len, room, wlen; +	char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0;  	strcpy(tempstr, prompt);  	prompt_len = strlen(tempstr); -	/* -	 * Remove newlines -	 */ -	for (i = 0; i < prompt_len; i++) { -		if (tempstr[i] == '\n') -			tempstr[i] = ' '; -	} -  	if (prompt_len <= width - x * 2) {	/* If prompt is short */  		wmove(win, y, (width - prompt_len) / 2);  		waddstr(win, tempstr); @@ -353,7 +398,10 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)  		newl = 1;  		word = tempstr;  		while (word && *word) { -			sp = strchr(word, ' '); +			sp = strpbrk(word, "\n "); +			if (sp && *sp == '\n') +				newline_separator = sp; +  			if (sp)  				*sp++ = 0; @@ -365,7 +413,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)  			if (wlen > room ||  			    (newl && wlen < 4 && sp  			     && wlen + 1 + strlen(sp) > room -			     && (!(sp2 = strchr(sp, ' ')) +			     && (!(sp2 = strpbrk(sp, "\n "))  				 || wlen + 1 + (sp2 - sp) > room))) {  				cur_y++;  				cur_x = x; @@ -373,7 +421,15 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)  			wmove(win, cur_y, cur_x);  			waddstr(win, word);  			getyx(win, cur_y, cur_x); -			cur_x++; + +			/* Move to the next line if the word separator was a newline */ +			if (newline_separator) { +				cur_y++; +				cur_x = x; +				newline_separator = 0; +			} else +				cur_x++; +  			if (sp && *sp == ' ') {  				cur_x++;	/* double space */  				while (*++sp == ' ') ; @@ -567,7 +623,7 @@ void item_make(const char *fmt, ...)  void item_add_str(const char *fmt, ...)  {  	va_list ap; -        size_t avail; +	size_t avail;  	avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c index 4e6e8090c20..676fb2f824a 100644 --- a/scripts/kconfig/lxdialog/yesno.c +++ b/scripts/kconfig/lxdialog/yesno.c @@ -45,14 +45,14 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)  	WINDOW *dialog;  do_resize: -	if (getmaxy(stdscr) < (height + 4)) +	if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN))  		return -ERRDISPLAYTOOSMALL; -	if (getmaxx(stdscr) < (width + 4)) +	if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN))  		return -ERRDISPLAYTOOSMALL;  	/* center dialog box on screen */ -	x = (COLS - width) / 2; -	y = (LINES - height) / 2; +	x = (getmaxx(stdscr) - width) / 2; +	y = (getmaxy(stdscr) - height) / 2;  	draw_shadow(stdscr, y, x, height, width);  | 
