10c874100SMasahiro Yamada // SPDX-License-Identifier: GPL-2.0+
26f6046cfSSam Ravnborg /*
36f6046cfSSam Ravnborg  *  textbox.c -- implements the text box
46f6046cfSSam Ravnborg  *
56f6046cfSSam Ravnborg  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
66f6046cfSSam Ravnborg  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
76f6046cfSSam Ravnborg  */
86f6046cfSSam Ravnborg 
96f6046cfSSam Ravnborg #include "dialog.h"
106f6046cfSSam Ravnborg 
116f6046cfSSam Ravnborg static void back_lines(int n);
1295ac9b3bSBenjamin Poirier static void print_page(WINDOW *win, int height, int width, update_text_fn
1395ac9b3bSBenjamin Poirier 		       update_text, void *data);
146f6046cfSSam Ravnborg static void print_line(WINDOW *win, int row, int width);
156f6046cfSSam Ravnborg static char *get_line(void);
16c8dc68adSSam Ravnborg static void print_position(WINDOW * win);
176f6046cfSSam Ravnborg 
182982de69SSam Ravnborg static int hscroll;
192982de69SSam Ravnborg static int begin_reached, end_reached, page_length;
2095ac9b3bSBenjamin Poirier static char *buf;
2195ac9b3bSBenjamin Poirier static char *page;
226f6046cfSSam Ravnborg 
236f6046cfSSam Ravnborg /*
24c8dc68adSSam Ravnborg  * refresh window content
25c8dc68adSSam Ravnborg  */
26c8dc68adSSam Ravnborg static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
2795ac9b3bSBenjamin Poirier 			     int cur_y, int cur_x, update_text_fn update_text,
2895ac9b3bSBenjamin Poirier 			     void *data)
29c8dc68adSSam Ravnborg {
3095ac9b3bSBenjamin Poirier 	print_page(box, boxh, boxw, update_text, data);
31c8dc68adSSam Ravnborg 	print_position(dialog);
32c8dc68adSSam Ravnborg 	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
33c8dc68adSSam Ravnborg 	wrefresh(dialog);
34c8dc68adSSam Ravnborg }
35c8dc68adSSam Ravnborg 
36c8dc68adSSam Ravnborg 
37c8dc68adSSam Ravnborg /*
386f6046cfSSam Ravnborg  * Display text from a file in a dialog box.
39537ddae7SBenjamin Poirier  *
40537ddae7SBenjamin Poirier  * keys is a null-terminated array
4195ac9b3bSBenjamin Poirier  * update_text() may not add or remove any '\n' or '\0' in tbuf
426f6046cfSSam Ravnborg  */
4395ac9b3bSBenjamin Poirier int dialog_textbox(const char *title, char *tbuf, int initial_height,
4495ac9b3bSBenjamin Poirier 		   int initial_width, int *keys, int *_vscroll, int *_hscroll,
4595ac9b3bSBenjamin Poirier 		   update_text_fn update_text, void *data)
466f6046cfSSam Ravnborg {
472982de69SSam Ravnborg 	int i, x, y, cur_x, cur_y, key = 0;
48c8dc68adSSam Ravnborg 	int height, width, boxh, boxw;
49c8dc68adSSam Ravnborg 	WINDOW *dialog, *box;
50537ddae7SBenjamin Poirier 	bool done = false;
516f6046cfSSam Ravnborg 
522982de69SSam Ravnborg 	begin_reached = 1;
532982de69SSam Ravnborg 	end_reached = 0;
542982de69SSam Ravnborg 	page_length = 0;
552982de69SSam Ravnborg 	hscroll = 0;
562982de69SSam Ravnborg 	buf = tbuf;
576f6046cfSSam Ravnborg 	page = buf;	/* page is pointer to start of page to be displayed */
586f6046cfSSam Ravnborg 
591d1e2caeSBenjamin Poirier 	if (_vscroll && *_vscroll) {
601d1e2caeSBenjamin Poirier 		begin_reached = 0;
611d1e2caeSBenjamin Poirier 
621d1e2caeSBenjamin Poirier 		for (i = 0; i < *_vscroll; i++)
631d1e2caeSBenjamin Poirier 			get_line();
641d1e2caeSBenjamin Poirier 	}
651d1e2caeSBenjamin Poirier 	if (_hscroll)
661d1e2caeSBenjamin Poirier 		hscroll = *_hscroll;
671d1e2caeSBenjamin Poirier 
68c8dc68adSSam Ravnborg do_resize:
69c8dc68adSSam Ravnborg 	getmaxyx(stdscr, height, width);
70851f6657SSedat Dilek 	if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)
71c8dc68adSSam Ravnborg 		return -ERRDISPLAYTOOSMALL;
72c8dc68adSSam Ravnborg 	if (initial_height != 0)
73c8dc68adSSam Ravnborg 		height = initial_height;
74c8dc68adSSam Ravnborg 	else
75c8dc68adSSam Ravnborg 		if (height > 4)
76c8dc68adSSam Ravnborg 			height -= 4;
77c8dc68adSSam Ravnborg 		else
78c8dc68adSSam Ravnborg 			height = 0;
79c8dc68adSSam Ravnborg 	if (initial_width != 0)
80c8dc68adSSam Ravnborg 		width = initial_width;
81c8dc68adSSam Ravnborg 	else
82c8dc68adSSam Ravnborg 		if (width > 5)
83c8dc68adSSam Ravnborg 			width -= 5;
84c8dc68adSSam Ravnborg 		else
85c8dc68adSSam Ravnborg 			width = 0;
86c8dc68adSSam Ravnborg 
876f6046cfSSam Ravnborg 	/* center dialog box on screen */
884f2de3e1SDirk Gouders 	x = (getmaxx(stdscr) - width) / 2;
894f2de3e1SDirk Gouders 	y = (getmaxy(stdscr) - height) / 2;
906f6046cfSSam Ravnborg 
916f6046cfSSam Ravnborg 	draw_shadow(stdscr, y, x, height, width);
926f6046cfSSam Ravnborg 
936f6046cfSSam Ravnborg 	dialog = newwin(height, width, y, x);
946f6046cfSSam Ravnborg 	keypad(dialog, TRUE);
956f6046cfSSam Ravnborg 
96c8dc68adSSam Ravnborg 	/* Create window for box region, used for scrolling text */
97c8dc68adSSam Ravnborg 	boxh = height - 4;
98c8dc68adSSam Ravnborg 	boxw = width - 2;
99c8dc68adSSam Ravnborg 	box = subwin(dialog, boxh, boxw, y + 1, x + 1);
100c8dc68adSSam Ravnborg 	wattrset(box, dlg.dialog.atr);
101c8dc68adSSam Ravnborg 	wbkgdset(box, dlg.dialog.atr & A_COLOR);
1026f6046cfSSam Ravnborg 
103c8dc68adSSam Ravnborg 	keypad(box, TRUE);
1046f6046cfSSam Ravnborg 
1056f6046cfSSam Ravnborg 	/* register the new window, along with its borders */
10698e5a157SSam Ravnborg 	draw_box(dialog, 0, 0, height, width,
10798e5a157SSam Ravnborg 		 dlg.dialog.atr, dlg.border.atr);
1086f6046cfSSam Ravnborg 
10998e5a157SSam Ravnborg 	wattrset(dialog, dlg.border.atr);
1106f6046cfSSam Ravnborg 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
1116f6046cfSSam Ravnborg 	for (i = 0; i < width - 2; i++)
1126f6046cfSSam Ravnborg 		waddch(dialog, ACS_HLINE);
11398e5a157SSam Ravnborg 	wattrset(dialog, dlg.dialog.atr);
11498e5a157SSam Ravnborg 	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
1156f6046cfSSam Ravnborg 	waddch(dialog, ACS_RTEE);
1166f6046cfSSam Ravnborg 
1176f6046cfSSam Ravnborg 	print_title(dialog, title, width);
1186f6046cfSSam Ravnborg 
119694c49a7SSam Ravnborg 	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
1206f6046cfSSam Ravnborg 	wnoutrefresh(dialog);
1216f6046cfSSam Ravnborg 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
1226f6046cfSSam Ravnborg 
1236f6046cfSSam Ravnborg 	/* Print first page of text */
124c8dc68adSSam Ravnborg 	attr_clear(box, boxh, boxw, dlg.dialog.atr);
12595ac9b3bSBenjamin Poirier 	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
12695ac9b3bSBenjamin Poirier 			 data);
1276f6046cfSSam Ravnborg 
128537ddae7SBenjamin Poirier 	while (!done) {
1296f6046cfSSam Ravnborg 		key = wgetch(dialog);
1306f6046cfSSam Ravnborg 		switch (key) {
1316f6046cfSSam Ravnborg 		case 'E':	/* Exit */
1326f6046cfSSam Ravnborg 		case 'e':
1336f6046cfSSam Ravnborg 		case 'X':
1346f6046cfSSam Ravnborg 		case 'x':
1359d4792c9SBenjamin Poirier 		case 'q':
136537ddae7SBenjamin Poirier 		case '\n':
137537ddae7SBenjamin Poirier 			done = true;
138537ddae7SBenjamin Poirier 			break;
1396f6046cfSSam Ravnborg 		case 'g':	/* First page */
1406f6046cfSSam Ravnborg 		case KEY_HOME:
1416f6046cfSSam Ravnborg 			if (!begin_reached) {
1426f6046cfSSam Ravnborg 				begin_reached = 1;
1436f6046cfSSam Ravnborg 				page = buf;
144c8dc68adSSam Ravnborg 				refresh_text_box(dialog, box, boxh, boxw,
14595ac9b3bSBenjamin Poirier 						 cur_y, cur_x, update_text,
14695ac9b3bSBenjamin Poirier 						 data);
1476f6046cfSSam Ravnborg 			}
1486f6046cfSSam Ravnborg 			break;
1496f6046cfSSam Ravnborg 		case 'G':	/* Last page */
1506f6046cfSSam Ravnborg 		case KEY_END:
1516f6046cfSSam Ravnborg 
1526f6046cfSSam Ravnborg 			end_reached = 1;
1532982de69SSam Ravnborg 			/* point to last char in buf */
1542982de69SSam Ravnborg 			page = buf + strlen(buf);
155c8dc68adSSam Ravnborg 			back_lines(boxh);
15695ac9b3bSBenjamin Poirier 			refresh_text_box(dialog, box, boxh, boxw, cur_y,
15795ac9b3bSBenjamin Poirier 					 cur_x, update_text, data);
1586f6046cfSSam Ravnborg 			break;
1596f6046cfSSam Ravnborg 		case 'K':	/* Previous line */
1606f6046cfSSam Ravnborg 		case 'k':
1616f6046cfSSam Ravnborg 		case KEY_UP:
1621a374ae6SBenjamin Poirier 			if (begin_reached)
1631a374ae6SBenjamin Poirier 				break;
164537ddae7SBenjamin Poirier 
1656f6046cfSSam Ravnborg 			back_lines(page_length + 1);
1661a374ae6SBenjamin Poirier 			refresh_text_box(dialog, box, boxh, boxw, cur_y,
16795ac9b3bSBenjamin Poirier 					 cur_x, update_text, data);
1686f6046cfSSam Ravnborg 			break;
1696f6046cfSSam Ravnborg 		case 'B':	/* Previous page */
1706f6046cfSSam Ravnborg 		case 'b':
1719d4792c9SBenjamin Poirier 		case 'u':
1726f6046cfSSam Ravnborg 		case KEY_PPAGE:
1736f6046cfSSam Ravnborg 			if (begin_reached)
1746f6046cfSSam Ravnborg 				break;
175c8dc68adSSam Ravnborg 			back_lines(page_length + boxh);
17695ac9b3bSBenjamin Poirier 			refresh_text_box(dialog, box, boxh, boxw, cur_y,
17795ac9b3bSBenjamin Poirier 					 cur_x, update_text, data);
1786f6046cfSSam Ravnborg 			break;
1796f6046cfSSam Ravnborg 		case 'J':	/* Next line */
1806f6046cfSSam Ravnborg 		case 'j':
1816f6046cfSSam Ravnborg 		case KEY_DOWN:
1821a374ae6SBenjamin Poirier 			if (end_reached)
1831a374ae6SBenjamin Poirier 				break;
1841a374ae6SBenjamin Poirier 
1851a374ae6SBenjamin Poirier 			back_lines(page_length - 1);
1861a374ae6SBenjamin Poirier 			refresh_text_box(dialog, box, boxh, boxw, cur_y,
18795ac9b3bSBenjamin Poirier 					 cur_x, update_text, data);
1886f6046cfSSam Ravnborg 			break;
1896f6046cfSSam Ravnborg 		case KEY_NPAGE:	/* Next page */
1906f6046cfSSam Ravnborg 		case ' ':
1919d4792c9SBenjamin Poirier 		case 'd':
1926f6046cfSSam Ravnborg 			if (end_reached)
1936f6046cfSSam Ravnborg 				break;
1946f6046cfSSam Ravnborg 
1956f6046cfSSam Ravnborg 			begin_reached = 0;
19695ac9b3bSBenjamin Poirier 			refresh_text_box(dialog, box, boxh, boxw, cur_y,
19795ac9b3bSBenjamin Poirier 					 cur_x, update_text, data);
1986f6046cfSSam Ravnborg 			break;
1996f6046cfSSam Ravnborg 		case '0':	/* Beginning of line */
2006f6046cfSSam Ravnborg 		case 'H':	/* Scroll left */
2016f6046cfSSam Ravnborg 		case 'h':
2026f6046cfSSam Ravnborg 		case KEY_LEFT:
2036f6046cfSSam Ravnborg 			if (hscroll <= 0)
2046f6046cfSSam Ravnborg 				break;
2056f6046cfSSam Ravnborg 
2066f6046cfSSam Ravnborg 			if (key == '0')
2076f6046cfSSam Ravnborg 				hscroll = 0;
2086f6046cfSSam Ravnborg 			else
2096f6046cfSSam Ravnborg 				hscroll--;
2106f6046cfSSam Ravnborg 			/* Reprint current page to scroll horizontally */
2116f6046cfSSam Ravnborg 			back_lines(page_length);
21295ac9b3bSBenjamin Poirier 			refresh_text_box(dialog, box, boxh, boxw, cur_y,
21395ac9b3bSBenjamin Poirier 					 cur_x, update_text, data);
2146f6046cfSSam Ravnborg 			break;
2156f6046cfSSam Ravnborg 		case 'L':	/* Scroll right */
2166f6046cfSSam Ravnborg 		case 'l':
2176f6046cfSSam Ravnborg 		case KEY_RIGHT:
2186f6046cfSSam Ravnborg 			if (hscroll >= MAX_LEN)
2196f6046cfSSam Ravnborg 				break;
2206f6046cfSSam Ravnborg 			hscroll++;
2216f6046cfSSam Ravnborg 			/* Reprint current page to scroll horizontally */
2226f6046cfSSam Ravnborg 			back_lines(page_length);
22395ac9b3bSBenjamin Poirier 			refresh_text_box(dialog, box, boxh, boxw, cur_y,
22495ac9b3bSBenjamin Poirier 					 cur_x, update_text, data);
2256f6046cfSSam Ravnborg 			break;
226f3cbcdc9SSam Ravnborg 		case KEY_ESC:
227537ddae7SBenjamin Poirier 			if (on_key_esc(dialog) == KEY_ESC)
228537ddae7SBenjamin Poirier 				done = true;
2296f6046cfSSam Ravnborg 			break;
230c8dc68adSSam Ravnborg 		case KEY_RESIZE:
231c8dc68adSSam Ravnborg 			back_lines(height);
232c8dc68adSSam Ravnborg 			delwin(box);
233c8dc68adSSam Ravnborg 			delwin(dialog);
234c8dc68adSSam Ravnborg 			on_key_resize();
235c8dc68adSSam Ravnborg 			goto do_resize;
236537ddae7SBenjamin Poirier 		default:
237537ddae7SBenjamin Poirier 			for (i = 0; keys[i]; i++) {
238537ddae7SBenjamin Poirier 				if (key == keys[i]) {
239537ddae7SBenjamin Poirier 					done = true;
240537ddae7SBenjamin Poirier 					break;
241537ddae7SBenjamin Poirier 				}
242537ddae7SBenjamin Poirier 			}
2436f6046cfSSam Ravnborg 		}
2446f6046cfSSam Ravnborg 	}
245c8dc68adSSam Ravnborg 	delwin(box);
2466f6046cfSSam Ravnborg 	delwin(dialog);
2471d1e2caeSBenjamin Poirier 	if (_vscroll) {
2481d1e2caeSBenjamin Poirier 		const char *s;
2491d1e2caeSBenjamin Poirier 
2501d1e2caeSBenjamin Poirier 		s = buf;
2511d1e2caeSBenjamin Poirier 		*_vscroll = 0;
2521d1e2caeSBenjamin Poirier 		back_lines(page_length);
2531d1e2caeSBenjamin Poirier 		while (s < page && (s = strchr(s, '\n'))) {
2541d1e2caeSBenjamin Poirier 			(*_vscroll)++;
2551d1e2caeSBenjamin Poirier 			s++;
2561d1e2caeSBenjamin Poirier 		}
2571d1e2caeSBenjamin Poirier 	}
2581d1e2caeSBenjamin Poirier 	if (_hscroll)
2591d1e2caeSBenjamin Poirier 		*_hscroll = hscroll;
260537ddae7SBenjamin Poirier 	return key;
2616f6046cfSSam Ravnborg }
2626f6046cfSSam Ravnborg 
2636f6046cfSSam Ravnborg /*
2642982de69SSam Ravnborg  * Go back 'n' lines in text. Called by dialog_textbox().
2656f6046cfSSam Ravnborg  * 'page' will be updated to point to the desired line in 'buf'.
2666f6046cfSSam Ravnborg  */
2676f6046cfSSam Ravnborg static void back_lines(int n)
2686f6046cfSSam Ravnborg {
2692982de69SSam Ravnborg 	int i;
2706f6046cfSSam Ravnborg 
2716f6046cfSSam Ravnborg 	begin_reached = 0;
2722982de69SSam Ravnborg 	/* Go back 'n' lines */
2732982de69SSam Ravnborg 	for (i = 0; i < n; i++) {
2742982de69SSam Ravnborg 		if (*page == '\0') {
2752982de69SSam Ravnborg 			if (end_reached) {
2762982de69SSam Ravnborg 				end_reached = 0;
2772982de69SSam Ravnborg 				continue;
2782982de69SSam Ravnborg 			}
2792982de69SSam Ravnborg 		}
2806f6046cfSSam Ravnborg 		if (page == buf) {
2816f6046cfSSam Ravnborg 			begin_reached = 1;
2826f6046cfSSam Ravnborg 			return;
2836f6046cfSSam Ravnborg 		}
2842982de69SSam Ravnborg 		page--;
2856f6046cfSSam Ravnborg 		do {
2866f6046cfSSam Ravnborg 			if (page == buf) {
2876f6046cfSSam Ravnborg 				begin_reached = 1;
2886f6046cfSSam Ravnborg 				return;
2896f6046cfSSam Ravnborg 			}
2902982de69SSam Ravnborg 			page--;
2912982de69SSam Ravnborg 		} while (*page != '\n');
2926f6046cfSSam Ravnborg 		page++;
2936f6046cfSSam Ravnborg 	}
2942982de69SSam Ravnborg }
2956f6046cfSSam Ravnborg 
2966f6046cfSSam Ravnborg /*
29795ac9b3bSBenjamin Poirier  * Print a new page of text.
2986f6046cfSSam Ravnborg  */
29995ac9b3bSBenjamin Poirier static void print_page(WINDOW *win, int height, int width, update_text_fn
30095ac9b3bSBenjamin Poirier 		       update_text, void *data)
3016f6046cfSSam Ravnborg {
3026f6046cfSSam Ravnborg 	int i, passed_end = 0;
3036f6046cfSSam Ravnborg 
30495ac9b3bSBenjamin Poirier 	if (update_text) {
30595ac9b3bSBenjamin Poirier 		char *end;
30695ac9b3bSBenjamin Poirier 
30795ac9b3bSBenjamin Poirier 		for (i = 0; i < height; i++)
30895ac9b3bSBenjamin Poirier 			get_line();
30995ac9b3bSBenjamin Poirier 		end = page;
31095ac9b3bSBenjamin Poirier 		back_lines(height);
31195ac9b3bSBenjamin Poirier 		update_text(buf, page - buf, end - buf, data);
31295ac9b3bSBenjamin Poirier 	}
31395ac9b3bSBenjamin Poirier 
3146f6046cfSSam Ravnborg 	page_length = 0;
3156f6046cfSSam Ravnborg 	for (i = 0; i < height; i++) {
3166f6046cfSSam Ravnborg 		print_line(win, i, width);
3176f6046cfSSam Ravnborg 		if (!passed_end)
3186f6046cfSSam Ravnborg 			page_length++;
3196f6046cfSSam Ravnborg 		if (end_reached && !passed_end)
3206f6046cfSSam Ravnborg 			passed_end = 1;
3216f6046cfSSam Ravnborg 	}
3226f6046cfSSam Ravnborg 	wnoutrefresh(win);
3236f6046cfSSam Ravnborg }
3246f6046cfSSam Ravnborg 
3256f6046cfSSam Ravnborg /*
32695ac9b3bSBenjamin Poirier  * Print a new line of text.
3276f6046cfSSam Ravnborg  */
3286f6046cfSSam Ravnborg static void print_line(WINDOW * win, int row, int width)
3296f6046cfSSam Ravnborg {
3306f6046cfSSam Ravnborg 	char *line;
3316f6046cfSSam Ravnborg 
3326f6046cfSSam Ravnborg 	line = get_line();
3336f6046cfSSam Ravnborg 	line += MIN(strlen(line), hscroll);	/* Scroll horizontally */
3346f6046cfSSam Ravnborg 	wmove(win, row, 0);	/* move cursor to correct line */
3356f6046cfSSam Ravnborg 	waddch(win, ' ');
3366f6046cfSSam Ravnborg 	waddnstr(win, line, MIN(strlen(line), width - 2));
3376f6046cfSSam Ravnborg 
3386f6046cfSSam Ravnborg 	/* Clear 'residue' of previous line */
3396f6046cfSSam Ravnborg #if OLD_NCURSES
3406f6046cfSSam Ravnborg 	{
341702a9450SLucas De Marchi 		int x = getcurx(win);
3426f6046cfSSam Ravnborg 		int i;
3436f6046cfSSam Ravnborg 		for (i = 0; i < width - x; i++)
3446f6046cfSSam Ravnborg 			waddch(win, ' ');
3456f6046cfSSam Ravnborg 	}
3466f6046cfSSam Ravnborg #else
3476f6046cfSSam Ravnborg 	wclrtoeol(win);
3486f6046cfSSam Ravnborg #endif
3496f6046cfSSam Ravnborg }
3506f6046cfSSam Ravnborg 
3516f6046cfSSam Ravnborg /*
3526f6046cfSSam Ravnborg  * Return current line of text. Called by dialog_textbox() and print_line().
3536f6046cfSSam Ravnborg  * 'page' should point to start of current line before calling, and will be
3546f6046cfSSam Ravnborg  * updated to point to start of next line.
3556f6046cfSSam Ravnborg  */
3566f6046cfSSam Ravnborg static char *get_line(void)
3576f6046cfSSam Ravnborg {
3582982de69SSam Ravnborg 	int i = 0;
3596f6046cfSSam Ravnborg 	static char line[MAX_LEN + 1];
3606f6046cfSSam Ravnborg 
3616f6046cfSSam Ravnborg 	end_reached = 0;
3626f6046cfSSam Ravnborg 	while (*page != '\n') {
3636f6046cfSSam Ravnborg 		if (*page == '\0') {
3646f6046cfSSam Ravnborg 			end_reached = 1;
3656f6046cfSSam Ravnborg 			break;
3666f6046cfSSam Ravnborg 		} else if (i < MAX_LEN)
3676f6046cfSSam Ravnborg 			line[i++] = *(page++);
3686f6046cfSSam Ravnborg 		else {
3696f6046cfSSam Ravnborg 			/* Truncate lines longer than MAX_LEN characters */
3706f6046cfSSam Ravnborg 			if (i == MAX_LEN)
3716f6046cfSSam Ravnborg 				line[i++] = '\0';
3726f6046cfSSam Ravnborg 			page++;
3736f6046cfSSam Ravnborg 		}
3746f6046cfSSam Ravnborg 	}
3756f6046cfSSam Ravnborg 	if (i <= MAX_LEN)
3766f6046cfSSam Ravnborg 		line[i] = '\0';
3776f6046cfSSam Ravnborg 	if (!end_reached)
378b9d29abdSBenjamin Poirier 		page++;		/* move past '\n' */
3796f6046cfSSam Ravnborg 
3806f6046cfSSam Ravnborg 	return line;
3816f6046cfSSam Ravnborg }
3826f6046cfSSam Ravnborg 
3836f6046cfSSam Ravnborg /*
3846f6046cfSSam Ravnborg  * Print current position
3856f6046cfSSam Ravnborg  */
386c8dc68adSSam Ravnborg static void print_position(WINDOW * win)
3876f6046cfSSam Ravnborg {
3882982de69SSam Ravnborg 	int percent;
3896f6046cfSSam Ravnborg 
39098e5a157SSam Ravnborg 	wattrset(win, dlg.position_indicator.atr);
39198e5a157SSam Ravnborg 	wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
3922982de69SSam Ravnborg 	percent = (page - buf) * 100 / strlen(buf);
393c8dc68adSSam Ravnborg 	wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
3946f6046cfSSam Ravnborg 	wprintw(win, "(%3d%%)", percent);
3956f6046cfSSam Ravnborg }
396