18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  textbox.c -- implements the text box
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
68c2ecf20Sopenharmony_ci *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include "dialog.h"
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_cistatic void back_lines(int n);
128c2ecf20Sopenharmony_cistatic void print_page(WINDOW *win, int height, int width, update_text_fn
138c2ecf20Sopenharmony_ci		       update_text, void *data);
148c2ecf20Sopenharmony_cistatic void print_line(WINDOW *win, int row, int width);
158c2ecf20Sopenharmony_cistatic char *get_line(void);
168c2ecf20Sopenharmony_cistatic void print_position(WINDOW * win);
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic int hscroll;
198c2ecf20Sopenharmony_cistatic int begin_reached, end_reached, page_length;
208c2ecf20Sopenharmony_cistatic char *buf;
218c2ecf20Sopenharmony_cistatic char *page;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * refresh window content
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_cistatic void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
278c2ecf20Sopenharmony_ci			     int cur_y, int cur_x, update_text_fn update_text,
288c2ecf20Sopenharmony_ci			     void *data)
298c2ecf20Sopenharmony_ci{
308c2ecf20Sopenharmony_ci	print_page(box, boxh, boxw, update_text, data);
318c2ecf20Sopenharmony_ci	print_position(dialog);
328c2ecf20Sopenharmony_ci	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
338c2ecf20Sopenharmony_ci	wrefresh(dialog);
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/*
388c2ecf20Sopenharmony_ci * Display text from a file in a dialog box.
398c2ecf20Sopenharmony_ci *
408c2ecf20Sopenharmony_ci * keys is a null-terminated array
418c2ecf20Sopenharmony_ci * update_text() may not add or remove any '\n' or '\0' in tbuf
428c2ecf20Sopenharmony_ci */
438c2ecf20Sopenharmony_ciint dialog_textbox(const char *title, char *tbuf, int initial_height,
448c2ecf20Sopenharmony_ci		   int initial_width, int *keys, int *_vscroll, int *_hscroll,
458c2ecf20Sopenharmony_ci		   update_text_fn update_text, void *data)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	int i, x, y, cur_x, cur_y, key = 0;
488c2ecf20Sopenharmony_ci	int height, width, boxh, boxw;
498c2ecf20Sopenharmony_ci	WINDOW *dialog, *box;
508c2ecf20Sopenharmony_ci	bool done = false;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	begin_reached = 1;
538c2ecf20Sopenharmony_ci	end_reached = 0;
548c2ecf20Sopenharmony_ci	page_length = 0;
558c2ecf20Sopenharmony_ci	hscroll = 0;
568c2ecf20Sopenharmony_ci	buf = tbuf;
578c2ecf20Sopenharmony_ci	page = buf;	/* page is pointer to start of page to be displayed */
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	if (_vscroll && *_vscroll) {
608c2ecf20Sopenharmony_ci		begin_reached = 0;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci		for (i = 0; i < *_vscroll; i++)
638c2ecf20Sopenharmony_ci			get_line();
648c2ecf20Sopenharmony_ci	}
658c2ecf20Sopenharmony_ci	if (_hscroll)
668c2ecf20Sopenharmony_ci		hscroll = *_hscroll;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cido_resize:
698c2ecf20Sopenharmony_ci	getmaxyx(stdscr, height, width);
708c2ecf20Sopenharmony_ci	if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)
718c2ecf20Sopenharmony_ci		return -ERRDISPLAYTOOSMALL;
728c2ecf20Sopenharmony_ci	if (initial_height != 0)
738c2ecf20Sopenharmony_ci		height = initial_height;
748c2ecf20Sopenharmony_ci	else
758c2ecf20Sopenharmony_ci		if (height > 4)
768c2ecf20Sopenharmony_ci			height -= 4;
778c2ecf20Sopenharmony_ci		else
788c2ecf20Sopenharmony_ci			height = 0;
798c2ecf20Sopenharmony_ci	if (initial_width != 0)
808c2ecf20Sopenharmony_ci		width = initial_width;
818c2ecf20Sopenharmony_ci	else
828c2ecf20Sopenharmony_ci		if (width > 5)
838c2ecf20Sopenharmony_ci			width -= 5;
848c2ecf20Sopenharmony_ci		else
858c2ecf20Sopenharmony_ci			width = 0;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	/* center dialog box on screen */
888c2ecf20Sopenharmony_ci	x = (getmaxx(stdscr) - width) / 2;
898c2ecf20Sopenharmony_ci	y = (getmaxy(stdscr) - height) / 2;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	draw_shadow(stdscr, y, x, height, width);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	dialog = newwin(height, width, y, x);
948c2ecf20Sopenharmony_ci	keypad(dialog, TRUE);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	/* Create window for box region, used for scrolling text */
978c2ecf20Sopenharmony_ci	boxh = height - 4;
988c2ecf20Sopenharmony_ci	boxw = width - 2;
998c2ecf20Sopenharmony_ci	box = subwin(dialog, boxh, boxw, y + 1, x + 1);
1008c2ecf20Sopenharmony_ci	wattrset(box, dlg.dialog.atr);
1018c2ecf20Sopenharmony_ci	wbkgdset(box, dlg.dialog.atr & A_COLOR);
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	keypad(box, TRUE);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	/* register the new window, along with its borders */
1068c2ecf20Sopenharmony_ci	draw_box(dialog, 0, 0, height, width,
1078c2ecf20Sopenharmony_ci		 dlg.dialog.atr, dlg.border.atr);
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	wattrset(dialog, dlg.border.atr);
1108c2ecf20Sopenharmony_ci	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
1118c2ecf20Sopenharmony_ci	for (i = 0; i < width - 2; i++)
1128c2ecf20Sopenharmony_ci		waddch(dialog, ACS_HLINE);
1138c2ecf20Sopenharmony_ci	wattrset(dialog, dlg.dialog.atr);
1148c2ecf20Sopenharmony_ci	wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
1158c2ecf20Sopenharmony_ci	waddch(dialog, ACS_RTEE);
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	print_title(dialog, title, width);
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
1208c2ecf20Sopenharmony_ci	wnoutrefresh(dialog);
1218c2ecf20Sopenharmony_ci	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	/* Print first page of text */
1248c2ecf20Sopenharmony_ci	attr_clear(box, boxh, boxw, dlg.dialog.atr);
1258c2ecf20Sopenharmony_ci	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
1268c2ecf20Sopenharmony_ci			 data);
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	while (!done) {
1298c2ecf20Sopenharmony_ci		key = wgetch(dialog);
1308c2ecf20Sopenharmony_ci		switch (key) {
1318c2ecf20Sopenharmony_ci		case 'E':	/* Exit */
1328c2ecf20Sopenharmony_ci		case 'e':
1338c2ecf20Sopenharmony_ci		case 'X':
1348c2ecf20Sopenharmony_ci		case 'x':
1358c2ecf20Sopenharmony_ci		case 'q':
1368c2ecf20Sopenharmony_ci		case '\n':
1378c2ecf20Sopenharmony_ci			done = true;
1388c2ecf20Sopenharmony_ci			break;
1398c2ecf20Sopenharmony_ci		case 'g':	/* First page */
1408c2ecf20Sopenharmony_ci		case KEY_HOME:
1418c2ecf20Sopenharmony_ci			if (!begin_reached) {
1428c2ecf20Sopenharmony_ci				begin_reached = 1;
1438c2ecf20Sopenharmony_ci				page = buf;
1448c2ecf20Sopenharmony_ci				refresh_text_box(dialog, box, boxh, boxw,
1458c2ecf20Sopenharmony_ci						 cur_y, cur_x, update_text,
1468c2ecf20Sopenharmony_ci						 data);
1478c2ecf20Sopenharmony_ci			}
1488c2ecf20Sopenharmony_ci			break;
1498c2ecf20Sopenharmony_ci		case 'G':	/* Last page */
1508c2ecf20Sopenharmony_ci		case KEY_END:
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci			end_reached = 1;
1538c2ecf20Sopenharmony_ci			/* point to last char in buf */
1548c2ecf20Sopenharmony_ci			page = buf + strlen(buf);
1558c2ecf20Sopenharmony_ci			back_lines(boxh);
1568c2ecf20Sopenharmony_ci			refresh_text_box(dialog, box, boxh, boxw, cur_y,
1578c2ecf20Sopenharmony_ci					 cur_x, update_text, data);
1588c2ecf20Sopenharmony_ci			break;
1598c2ecf20Sopenharmony_ci		case 'K':	/* Previous line */
1608c2ecf20Sopenharmony_ci		case 'k':
1618c2ecf20Sopenharmony_ci		case KEY_UP:
1628c2ecf20Sopenharmony_ci			if (begin_reached)
1638c2ecf20Sopenharmony_ci				break;
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci			back_lines(page_length + 1);
1668c2ecf20Sopenharmony_ci			refresh_text_box(dialog, box, boxh, boxw, cur_y,
1678c2ecf20Sopenharmony_ci					 cur_x, update_text, data);
1688c2ecf20Sopenharmony_ci			break;
1698c2ecf20Sopenharmony_ci		case 'B':	/* Previous page */
1708c2ecf20Sopenharmony_ci		case 'b':
1718c2ecf20Sopenharmony_ci		case 'u':
1728c2ecf20Sopenharmony_ci		case KEY_PPAGE:
1738c2ecf20Sopenharmony_ci			if (begin_reached)
1748c2ecf20Sopenharmony_ci				break;
1758c2ecf20Sopenharmony_ci			back_lines(page_length + boxh);
1768c2ecf20Sopenharmony_ci			refresh_text_box(dialog, box, boxh, boxw, cur_y,
1778c2ecf20Sopenharmony_ci					 cur_x, update_text, data);
1788c2ecf20Sopenharmony_ci			break;
1798c2ecf20Sopenharmony_ci		case 'J':	/* Next line */
1808c2ecf20Sopenharmony_ci		case 'j':
1818c2ecf20Sopenharmony_ci		case KEY_DOWN:
1828c2ecf20Sopenharmony_ci			if (end_reached)
1838c2ecf20Sopenharmony_ci				break;
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci			back_lines(page_length - 1);
1868c2ecf20Sopenharmony_ci			refresh_text_box(dialog, box, boxh, boxw, cur_y,
1878c2ecf20Sopenharmony_ci					 cur_x, update_text, data);
1888c2ecf20Sopenharmony_ci			break;
1898c2ecf20Sopenharmony_ci		case KEY_NPAGE:	/* Next page */
1908c2ecf20Sopenharmony_ci		case ' ':
1918c2ecf20Sopenharmony_ci		case 'd':
1928c2ecf20Sopenharmony_ci			if (end_reached)
1938c2ecf20Sopenharmony_ci				break;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci			begin_reached = 0;
1968c2ecf20Sopenharmony_ci			refresh_text_box(dialog, box, boxh, boxw, cur_y,
1978c2ecf20Sopenharmony_ci					 cur_x, update_text, data);
1988c2ecf20Sopenharmony_ci			break;
1998c2ecf20Sopenharmony_ci		case '0':	/* Beginning of line */
2008c2ecf20Sopenharmony_ci		case 'H':	/* Scroll left */
2018c2ecf20Sopenharmony_ci		case 'h':
2028c2ecf20Sopenharmony_ci		case KEY_LEFT:
2038c2ecf20Sopenharmony_ci			if (hscroll <= 0)
2048c2ecf20Sopenharmony_ci				break;
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci			if (key == '0')
2078c2ecf20Sopenharmony_ci				hscroll = 0;
2088c2ecf20Sopenharmony_ci			else
2098c2ecf20Sopenharmony_ci				hscroll--;
2108c2ecf20Sopenharmony_ci			/* Reprint current page to scroll horizontally */
2118c2ecf20Sopenharmony_ci			back_lines(page_length);
2128c2ecf20Sopenharmony_ci			refresh_text_box(dialog, box, boxh, boxw, cur_y,
2138c2ecf20Sopenharmony_ci					 cur_x, update_text, data);
2148c2ecf20Sopenharmony_ci			break;
2158c2ecf20Sopenharmony_ci		case 'L':	/* Scroll right */
2168c2ecf20Sopenharmony_ci		case 'l':
2178c2ecf20Sopenharmony_ci		case KEY_RIGHT:
2188c2ecf20Sopenharmony_ci			if (hscroll >= MAX_LEN)
2198c2ecf20Sopenharmony_ci				break;
2208c2ecf20Sopenharmony_ci			hscroll++;
2218c2ecf20Sopenharmony_ci			/* Reprint current page to scroll horizontally */
2228c2ecf20Sopenharmony_ci			back_lines(page_length);
2238c2ecf20Sopenharmony_ci			refresh_text_box(dialog, box, boxh, boxw, cur_y,
2248c2ecf20Sopenharmony_ci					 cur_x, update_text, data);
2258c2ecf20Sopenharmony_ci			break;
2268c2ecf20Sopenharmony_ci		case KEY_ESC:
2278c2ecf20Sopenharmony_ci			if (on_key_esc(dialog) == KEY_ESC)
2288c2ecf20Sopenharmony_ci				done = true;
2298c2ecf20Sopenharmony_ci			break;
2308c2ecf20Sopenharmony_ci		case KEY_RESIZE:
2318c2ecf20Sopenharmony_ci			back_lines(height);
2328c2ecf20Sopenharmony_ci			delwin(box);
2338c2ecf20Sopenharmony_ci			delwin(dialog);
2348c2ecf20Sopenharmony_ci			on_key_resize();
2358c2ecf20Sopenharmony_ci			goto do_resize;
2368c2ecf20Sopenharmony_ci		default:
2378c2ecf20Sopenharmony_ci			for (i = 0; keys[i]; i++) {
2388c2ecf20Sopenharmony_ci				if (key == keys[i]) {
2398c2ecf20Sopenharmony_ci					done = true;
2408c2ecf20Sopenharmony_ci					break;
2418c2ecf20Sopenharmony_ci				}
2428c2ecf20Sopenharmony_ci			}
2438c2ecf20Sopenharmony_ci		}
2448c2ecf20Sopenharmony_ci	}
2458c2ecf20Sopenharmony_ci	delwin(box);
2468c2ecf20Sopenharmony_ci	delwin(dialog);
2478c2ecf20Sopenharmony_ci	if (_vscroll) {
2488c2ecf20Sopenharmony_ci		const char *s;
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci		s = buf;
2518c2ecf20Sopenharmony_ci		*_vscroll = 0;
2528c2ecf20Sopenharmony_ci		back_lines(page_length);
2538c2ecf20Sopenharmony_ci		while (s < page && (s = strchr(s, '\n'))) {
2548c2ecf20Sopenharmony_ci			(*_vscroll)++;
2558c2ecf20Sopenharmony_ci			s++;
2568c2ecf20Sopenharmony_ci		}
2578c2ecf20Sopenharmony_ci	}
2588c2ecf20Sopenharmony_ci	if (_hscroll)
2598c2ecf20Sopenharmony_ci		*_hscroll = hscroll;
2608c2ecf20Sopenharmony_ci	return key;
2618c2ecf20Sopenharmony_ci}
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci/*
2648c2ecf20Sopenharmony_ci * Go back 'n' lines in text. Called by dialog_textbox().
2658c2ecf20Sopenharmony_ci * 'page' will be updated to point to the desired line in 'buf'.
2668c2ecf20Sopenharmony_ci */
2678c2ecf20Sopenharmony_cistatic void back_lines(int n)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	int i;
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	begin_reached = 0;
2728c2ecf20Sopenharmony_ci	/* Go back 'n' lines */
2738c2ecf20Sopenharmony_ci	for (i = 0; i < n; i++) {
2748c2ecf20Sopenharmony_ci		if (*page == '\0') {
2758c2ecf20Sopenharmony_ci			if (end_reached) {
2768c2ecf20Sopenharmony_ci				end_reached = 0;
2778c2ecf20Sopenharmony_ci				continue;
2788c2ecf20Sopenharmony_ci			}
2798c2ecf20Sopenharmony_ci		}
2808c2ecf20Sopenharmony_ci		if (page == buf) {
2818c2ecf20Sopenharmony_ci			begin_reached = 1;
2828c2ecf20Sopenharmony_ci			return;
2838c2ecf20Sopenharmony_ci		}
2848c2ecf20Sopenharmony_ci		page--;
2858c2ecf20Sopenharmony_ci		do {
2868c2ecf20Sopenharmony_ci			if (page == buf) {
2878c2ecf20Sopenharmony_ci				begin_reached = 1;
2888c2ecf20Sopenharmony_ci				return;
2898c2ecf20Sopenharmony_ci			}
2908c2ecf20Sopenharmony_ci			page--;
2918c2ecf20Sopenharmony_ci		} while (*page != '\n');
2928c2ecf20Sopenharmony_ci		page++;
2938c2ecf20Sopenharmony_ci	}
2948c2ecf20Sopenharmony_ci}
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci/*
2978c2ecf20Sopenharmony_ci * Print a new page of text.
2988c2ecf20Sopenharmony_ci */
2998c2ecf20Sopenharmony_cistatic void print_page(WINDOW *win, int height, int width, update_text_fn
3008c2ecf20Sopenharmony_ci		       update_text, void *data)
3018c2ecf20Sopenharmony_ci{
3028c2ecf20Sopenharmony_ci	int i, passed_end = 0;
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci	if (update_text) {
3058c2ecf20Sopenharmony_ci		char *end;
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci		for (i = 0; i < height; i++)
3088c2ecf20Sopenharmony_ci			get_line();
3098c2ecf20Sopenharmony_ci		end = page;
3108c2ecf20Sopenharmony_ci		back_lines(height);
3118c2ecf20Sopenharmony_ci		update_text(buf, page - buf, end - buf, data);
3128c2ecf20Sopenharmony_ci	}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	page_length = 0;
3158c2ecf20Sopenharmony_ci	for (i = 0; i < height; i++) {
3168c2ecf20Sopenharmony_ci		print_line(win, i, width);
3178c2ecf20Sopenharmony_ci		if (!passed_end)
3188c2ecf20Sopenharmony_ci			page_length++;
3198c2ecf20Sopenharmony_ci		if (end_reached && !passed_end)
3208c2ecf20Sopenharmony_ci			passed_end = 1;
3218c2ecf20Sopenharmony_ci	}
3228c2ecf20Sopenharmony_ci	wnoutrefresh(win);
3238c2ecf20Sopenharmony_ci}
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci/*
3268c2ecf20Sopenharmony_ci * Print a new line of text.
3278c2ecf20Sopenharmony_ci */
3288c2ecf20Sopenharmony_cistatic void print_line(WINDOW * win, int row, int width)
3298c2ecf20Sopenharmony_ci{
3308c2ecf20Sopenharmony_ci	char *line;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	line = get_line();
3338c2ecf20Sopenharmony_ci	line += MIN(strlen(line), hscroll);	/* Scroll horizontally */
3348c2ecf20Sopenharmony_ci	wmove(win, row, 0);	/* move cursor to correct line */
3358c2ecf20Sopenharmony_ci	waddch(win, ' ');
3368c2ecf20Sopenharmony_ci	waddnstr(win, line, MIN(strlen(line), width - 2));
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	/* Clear 'residue' of previous line */
3398c2ecf20Sopenharmony_ci#if OLD_NCURSES
3408c2ecf20Sopenharmony_ci	{
3418c2ecf20Sopenharmony_ci		int x = getcurx(win);
3428c2ecf20Sopenharmony_ci		int i;
3438c2ecf20Sopenharmony_ci		for (i = 0; i < width - x; i++)
3448c2ecf20Sopenharmony_ci			waddch(win, ' ');
3458c2ecf20Sopenharmony_ci	}
3468c2ecf20Sopenharmony_ci#else
3478c2ecf20Sopenharmony_ci	wclrtoeol(win);
3488c2ecf20Sopenharmony_ci#endif
3498c2ecf20Sopenharmony_ci}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci/*
3528c2ecf20Sopenharmony_ci * Return current line of text. Called by dialog_textbox() and print_line().
3538c2ecf20Sopenharmony_ci * 'page' should point to start of current line before calling, and will be
3548c2ecf20Sopenharmony_ci * updated to point to start of next line.
3558c2ecf20Sopenharmony_ci */
3568c2ecf20Sopenharmony_cistatic char *get_line(void)
3578c2ecf20Sopenharmony_ci{
3588c2ecf20Sopenharmony_ci	int i = 0;
3598c2ecf20Sopenharmony_ci	static char line[MAX_LEN + 1];
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	end_reached = 0;
3628c2ecf20Sopenharmony_ci	while (*page != '\n') {
3638c2ecf20Sopenharmony_ci		if (*page == '\0') {
3648c2ecf20Sopenharmony_ci			end_reached = 1;
3658c2ecf20Sopenharmony_ci			break;
3668c2ecf20Sopenharmony_ci		} else if (i < MAX_LEN)
3678c2ecf20Sopenharmony_ci			line[i++] = *(page++);
3688c2ecf20Sopenharmony_ci		else {
3698c2ecf20Sopenharmony_ci			/* Truncate lines longer than MAX_LEN characters */
3708c2ecf20Sopenharmony_ci			if (i == MAX_LEN)
3718c2ecf20Sopenharmony_ci				line[i++] = '\0';
3728c2ecf20Sopenharmony_ci			page++;
3738c2ecf20Sopenharmony_ci		}
3748c2ecf20Sopenharmony_ci	}
3758c2ecf20Sopenharmony_ci	if (i <= MAX_LEN)
3768c2ecf20Sopenharmony_ci		line[i] = '\0';
3778c2ecf20Sopenharmony_ci	if (!end_reached)
3788c2ecf20Sopenharmony_ci		page++;		/* move past '\n' */
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	return line;
3818c2ecf20Sopenharmony_ci}
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci/*
3848c2ecf20Sopenharmony_ci * Print current position
3858c2ecf20Sopenharmony_ci */
3868c2ecf20Sopenharmony_cistatic void print_position(WINDOW * win)
3878c2ecf20Sopenharmony_ci{
3888c2ecf20Sopenharmony_ci	int percent;
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci	wattrset(win, dlg.position_indicator.atr);
3918c2ecf20Sopenharmony_ci	wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
3928c2ecf20Sopenharmony_ci	percent = (page - buf) * 100 / strlen(buf);
3938c2ecf20Sopenharmony_ci	wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
3948c2ecf20Sopenharmony_ci	wprintw(win, "(%3d%%)", percent);
3958c2ecf20Sopenharmony_ci}
396