diff options
Diffstat (limited to 'scripts/kconfig/lxdialog/textbox.c')
| -rw-r--r-- | scripts/kconfig/lxdialog/textbox.c | 183 | 
1 files changed, 100 insertions, 83 deletions
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;  }  | 
