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