^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * textbox.c -- implements the text box
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "dialog.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static void back_lines(int n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static void print_page(WINDOW *win, int height, int width, update_text_fn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) update_text, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static void print_line(WINDOW *win, int row, int width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static char *get_line(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static void print_position(WINDOW * win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static int hscroll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static int begin_reached, end_reached, page_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static char *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * refresh window content
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int cur_y, int cur_x, update_text_fn update_text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) print_page(box, boxh, boxw, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) print_position(dialog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) wmove(dialog, cur_y, cur_x); /* Restore cursor position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) wrefresh(dialog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Display text from a file in a dialog box.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * keys is a null-terminated array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * update_text() may not add or remove any '\n' or '\0' in tbuf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int dialog_textbox(const char *title, char *tbuf, int initial_height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int initial_width, int *keys, int *_vscroll, int *_hscroll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) update_text_fn update_text, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int i, x, y, cur_x, cur_y, key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int height, width, boxh, boxw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) WINDOW *dialog, *box;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) bool done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) begin_reached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) end_reached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) page_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) hscroll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) buf = tbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) page = buf; /* page is pointer to start of page to be displayed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (_vscroll && *_vscroll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) begin_reached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) for (i = 0; i < *_vscroll; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) get_line();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (_hscroll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) hscroll = *_hscroll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) do_resize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) getmaxyx(stdscr, height, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return -ERRDISPLAYTOOSMALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (initial_height != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) height = initial_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (height > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) height -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) height = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (initial_width != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) width = initial_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (width > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) width -= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* center dialog box on screen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) x = (getmaxx(stdscr) - width) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) y = (getmaxy(stdscr) - height) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) draw_shadow(stdscr, y, x, height, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) dialog = newwin(height, width, y, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) keypad(dialog, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Create window for box region, used for scrolling text */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) boxh = height - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) boxw = width - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) box = subwin(dialog, boxh, boxw, y + 1, x + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) wattrset(box, dlg.dialog.atr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) wbkgdset(box, dlg.dialog.atr & A_COLOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) keypad(box, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* register the new window, along with its borders */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) draw_box(dialog, 0, 0, height, width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) dlg.dialog.atr, dlg.border.atr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) wattrset(dialog, dlg.border.atr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) mvwaddch(dialog, height - 3, 0, ACS_LTEE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) for (i = 0; i < width - 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) waddch(dialog, ACS_HLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) wattrset(dialog, dlg.dialog.atr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) waddch(dialog, ACS_RTEE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) print_title(dialog, title, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) wnoutrefresh(dialog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) getyx(dialog, cur_y, cur_x); /* Save cursor position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Print first page of text */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) attr_clear(box, boxh, boxw, dlg.dialog.atr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) while (!done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) key = wgetch(dialog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) switch (key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case 'E': /* Exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) case 'q':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case '\n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case 'g': /* First page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case KEY_HOME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!begin_reached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) begin_reached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) page = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) refresh_text_box(dialog, box, boxh, boxw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) cur_y, cur_x, update_text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case 'G': /* Last page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case KEY_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) end_reached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* point to last char in buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) page = buf + strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) back_lines(boxh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) refresh_text_box(dialog, box, boxh, boxw, cur_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) cur_x, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case 'K': /* Previous line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case 'k':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case KEY_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (begin_reached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) back_lines(page_length + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) refresh_text_box(dialog, box, boxh, boxw, cur_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cur_x, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case 'B': /* Previous page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case KEY_PPAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (begin_reached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) back_lines(page_length + boxh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) refresh_text_box(dialog, box, boxh, boxw, cur_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) cur_x, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case 'J': /* Next line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case 'j':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case KEY_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (end_reached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) back_lines(page_length - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) refresh_text_box(dialog, box, boxh, boxw, cur_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) cur_x, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case KEY_NPAGE: /* Next page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case ' ':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (end_reached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) begin_reached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) refresh_text_box(dialog, box, boxh, boxw, cur_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) cur_x, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case '0': /* Beginning of line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case 'H': /* Scroll left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case KEY_LEFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (hscroll <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (key == '0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) hscroll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) hscroll--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* Reprint current page to scroll horizontally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) back_lines(page_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) refresh_text_box(dialog, box, boxh, boxw, cur_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) cur_x, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case 'L': /* Scroll right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case KEY_RIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (hscroll >= MAX_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) hscroll++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* Reprint current page to scroll horizontally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) back_lines(page_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) refresh_text_box(dialog, box, boxh, boxw, cur_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) cur_x, update_text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case KEY_ESC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (on_key_esc(dialog) == KEY_ESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case KEY_RESIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) back_lines(height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) delwin(box);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) delwin(dialog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) on_key_resize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) goto do_resize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) for (i = 0; keys[i]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (key == keys[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) delwin(box);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) delwin(dialog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (_vscroll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) const char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) s = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *_vscroll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) back_lines(page_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) while (s < page && (s = strchr(s, '\n'))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) (*_vscroll)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (_hscroll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *_hscroll = hscroll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Go back 'n' lines in text. Called by dialog_textbox().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * 'page' will be updated to point to the desired line in 'buf'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void back_lines(int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) begin_reached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Go back 'n' lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (*page == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (end_reached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) end_reached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (page == buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) begin_reached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) page--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (page == buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) begin_reached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) page--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) } while (*page != '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) page++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * Print a new page of text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static void print_page(WINDOW *win, int height, int width, update_text_fn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) update_text, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int i, passed_end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (update_text) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) for (i = 0; i < height; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) get_line();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) end = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) back_lines(height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) update_text(buf, page - buf, end - buf, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) page_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) for (i = 0; i < height; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) print_line(win, i, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (!passed_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) page_length++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (end_reached && !passed_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) passed_end = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) wnoutrefresh(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * Print a new line of text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static void print_line(WINDOW * win, int row, int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) char *line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) line = get_line();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) line += MIN(strlen(line), hscroll); /* Scroll horizontally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) wmove(win, row, 0); /* move cursor to correct line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) waddch(win, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) waddnstr(win, line, MIN(strlen(line), width - 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* Clear 'residue' of previous line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #if OLD_NCURSES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int x = getcurx(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for (i = 0; i < width - x; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) waddch(win, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) wclrtoeol(win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * Return current line of text. Called by dialog_textbox() and print_line().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * 'page' should point to start of current line before calling, and will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * updated to point to start of next line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static char *get_line(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static char line[MAX_LEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) end_reached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) while (*page != '\n') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (*page == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) end_reached = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) } else if (i < MAX_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) line[i++] = *(page++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Truncate lines longer than MAX_LEN characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (i == MAX_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) line[i++] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) page++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (i <= MAX_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) line[i] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!end_reached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) page++; /* move past '\n' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * Print current position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static void print_position(WINDOW * win)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) int percent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) wattrset(win, dlg.position_indicator.atr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) percent = (page - buf) * 100 / strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) wprintw(win, "(%3d%%)", percent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }