textbox.c revision 224014
1217309Snwhitehorn/* 2224014Snwhitehorn * $Id: textbox.c,v 1.101 2011/06/29 09:53:03 tom Exp $ 3217309Snwhitehorn * 4220749Snwhitehorn * textbox.c -- implements the text box 5217309Snwhitehorn * 6220749Snwhitehorn * Copyright 2000-2010,2011 Thomas E. Dickey 7217309Snwhitehorn * 8217309Snwhitehorn * This program is free software; you can redistribute it and/or modify 9217309Snwhitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 10217309Snwhitehorn * as published by the Free Software Foundation. 11217309Snwhitehorn * 12217309Snwhitehorn * This program is distributed in the hope that it will be useful, but 13217309Snwhitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 14217309Snwhitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15217309Snwhitehorn * Lesser General Public License for more details. 16217309Snwhitehorn * 17217309Snwhitehorn * You should have received a copy of the GNU Lesser General Public 18217309Snwhitehorn * License along with this program; if not, write to 19217309Snwhitehorn * Free Software Foundation, Inc. 20217309Snwhitehorn * 51 Franklin St., Fifth Floor 21217309Snwhitehorn * Boston, MA 02110, USA. 22217309Snwhitehorn * 23217309Snwhitehorn * An earlier version of this program lists as authors: 24217309Snwhitehorn * Savio Lam (lam836@cs.cuhk.hk) 25217309Snwhitehorn */ 26217309Snwhitehorn 27217309Snwhitehorn#include <dialog.h> 28217309Snwhitehorn#include <dlg_keys.h> 29217309Snwhitehorn 30217309Snwhitehorn#define PAGE_LENGTH (height - 4) 31217309Snwhitehorn#define PAGE_WIDTH (width - 2) 32217309Snwhitehorn 33217309Snwhitehorntypedef struct { 34217309Snwhitehorn DIALOG_CALLBACK obj; 35217309Snwhitehorn WINDOW *text; 36217309Snwhitehorn const char **buttons; 37217309Snwhitehorn int hscroll; 38217309Snwhitehorn char line[MAX_LEN + 1]; 39217309Snwhitehorn int fd; 40217309Snwhitehorn long file_size; 41217309Snwhitehorn long fd_bytes_read; 42217309Snwhitehorn long bytes_read; 43217309Snwhitehorn long buffer_len; 44217309Snwhitehorn bool begin_reached; 45217309Snwhitehorn bool buffer_first; 46217309Snwhitehorn bool end_reached; 47217309Snwhitehorn long page_length; /* lines on the page which is shown */ 48217309Snwhitehorn long in_buf; /* ending index into buf[] for page */ 49217309Snwhitehorn char *buf; 50217309Snwhitehorn} MY_OBJ; 51217309Snwhitehorn 52217309Snwhitehornstatic long 53217309Snwhitehornlseek_obj(MY_OBJ * obj, long offset, int mode) 54217309Snwhitehorn{ 55217309Snwhitehorn long fpos; 56217309Snwhitehorn if ((fpos = (long) lseek(obj->fd, (off_t) offset, mode)) == -1) { 57217309Snwhitehorn switch (mode) { 58217309Snwhitehorn case SEEK_CUR: 59217309Snwhitehorn dlg_exiterr("Cannot get file position"); 60217309Snwhitehorn break; 61217309Snwhitehorn case SEEK_END: 62217309Snwhitehorn dlg_exiterr("Cannot seek to end of file"); 63217309Snwhitehorn break; 64217309Snwhitehorn case SEEK_SET: 65217309Snwhitehorn dlg_exiterr("Cannot set file position to %ld", offset); 66217309Snwhitehorn break; 67217309Snwhitehorn } 68217309Snwhitehorn } 69217309Snwhitehorn return fpos; 70217309Snwhitehorn} 71217309Snwhitehorn 72217309Snwhitehornstatic long 73217309Snwhitehornftell_obj(MY_OBJ * obj) 74217309Snwhitehorn{ 75220749Snwhitehorn return lseek_obj(obj, 0L, SEEK_CUR); 76217309Snwhitehorn} 77217309Snwhitehorn 78217309Snwhitehornstatic char * 79217309Snwhitehornxalloc(size_t size) 80217309Snwhitehorn{ 81217309Snwhitehorn char *result = dlg_malloc(char, size); 82217309Snwhitehorn assert_ptr(result, "xalloc"); 83217309Snwhitehorn return result; 84217309Snwhitehorn} 85217309Snwhitehorn 86217309Snwhitehorn/* 87217309Snwhitehorn * read_high() substitutes read() for tab->spaces conversion 88217309Snwhitehorn * 89217309Snwhitehorn * buffer_len, fd_bytes_read, bytes_read are modified 90217309Snwhitehorn * buf is allocated 91217309Snwhitehorn * 92217309Snwhitehorn * fd_bytes_read is the effective number of bytes read from file 93217309Snwhitehorn * bytes_read is the length of buf, that can be different if tab_correct 94217309Snwhitehorn */ 95217309Snwhitehornstatic void 96217309Snwhitehornread_high(MY_OBJ * obj, size_t size_read) 97217309Snwhitehorn{ 98217309Snwhitehorn char *buftab, ch; 99217309Snwhitehorn int i = 0, j, n, tmpint; 100217309Snwhitehorn long begin_line; 101217309Snwhitehorn 102217309Snwhitehorn /* Allocate space for read buffer */ 103217309Snwhitehorn buftab = xalloc(size_read + 1); 104217309Snwhitehorn 105217309Snwhitehorn if ((obj->fd_bytes_read = read(obj->fd, buftab, size_read)) != -1) { 106217309Snwhitehorn 107217309Snwhitehorn buftab[obj->fd_bytes_read] = '\0'; /* mark end of valid data */ 108217309Snwhitehorn 109217309Snwhitehorn if (dialog_vars.tab_correct) { 110217309Snwhitehorn 111217309Snwhitehorn /* calculate bytes_read by buftab and fd_bytes_read */ 112217309Snwhitehorn obj->bytes_read = begin_line = 0; 113217309Snwhitehorn for (j = 0; j < obj->fd_bytes_read; j++) 114217309Snwhitehorn if (buftab[j] == TAB) 115217309Snwhitehorn obj->bytes_read += dialog_state.tab_len 116217309Snwhitehorn - ((obj->bytes_read - begin_line) 117217309Snwhitehorn % dialog_state.tab_len); 118217309Snwhitehorn else if (buftab[j] == '\n') { 119217309Snwhitehorn obj->bytes_read++; 120217309Snwhitehorn begin_line = obj->bytes_read; 121217309Snwhitehorn } else 122217309Snwhitehorn obj->bytes_read++; 123217309Snwhitehorn 124217309Snwhitehorn if (obj->bytes_read > obj->buffer_len) { 125217309Snwhitehorn if (obj->buffer_first) 126217309Snwhitehorn obj->buffer_first = FALSE; /* disp = 0 */ 127217309Snwhitehorn else { 128217309Snwhitehorn free(obj->buf); 129217309Snwhitehorn } 130217309Snwhitehorn 131217309Snwhitehorn obj->buffer_len = obj->bytes_read; 132217309Snwhitehorn 133217309Snwhitehorn /* Allocate space for read buffer */ 134217309Snwhitehorn obj->buf = xalloc((size_t) obj->buffer_len + 1); 135217309Snwhitehorn } 136217309Snwhitehorn 137217309Snwhitehorn } else { 138217309Snwhitehorn if (obj->buffer_first) { 139217309Snwhitehorn obj->buffer_first = FALSE; 140217309Snwhitehorn 141217309Snwhitehorn /* Allocate space for read buffer */ 142217309Snwhitehorn obj->buf = xalloc(size_read + 1); 143217309Snwhitehorn } 144217309Snwhitehorn 145217309Snwhitehorn obj->bytes_read = obj->fd_bytes_read; 146217309Snwhitehorn } 147217309Snwhitehorn 148217309Snwhitehorn j = 0; 149217309Snwhitehorn begin_line = 0; 150217309Snwhitehorn while (j < obj->fd_bytes_read) 151217309Snwhitehorn if (((ch = buftab[j++]) == TAB) && (dialog_vars.tab_correct != 0)) { 152217309Snwhitehorn tmpint = (dialog_state.tab_len 153217309Snwhitehorn - ((int) ((long) i - begin_line) % dialog_state.tab_len)); 154217309Snwhitehorn for (n = 0; n < tmpint; n++) 155217309Snwhitehorn obj->buf[i++] = ' '; 156217309Snwhitehorn } else { 157217309Snwhitehorn if (ch == '\n') 158217309Snwhitehorn begin_line = i + 1; 159217309Snwhitehorn obj->buf[i++] = ch; 160217309Snwhitehorn } 161217309Snwhitehorn 162217309Snwhitehorn obj->buf[i] = '\0'; /* mark end of valid data */ 163217309Snwhitehorn 164217309Snwhitehorn } 165217309Snwhitehorn if (obj->bytes_read == -1) 166217309Snwhitehorn dlg_exiterr("Error reading file"); 167217309Snwhitehorn free(buftab); 168217309Snwhitehorn} 169217309Snwhitehorn 170217309Snwhitehornstatic long 171217309Snwhitehornfind_first(MY_OBJ * obj, char *buffer, long length) 172217309Snwhitehorn{ 173217309Snwhitehorn long recount = obj->page_length; 174217309Snwhitehorn long result = 0; 175217309Snwhitehorn 176217309Snwhitehorn while (length > 0) { 177217309Snwhitehorn if (buffer[length] == '\n') { 178217309Snwhitehorn if (--recount < 0) { 179217309Snwhitehorn result = length; 180217309Snwhitehorn break; 181217309Snwhitehorn } 182217309Snwhitehorn } 183217309Snwhitehorn --length; 184217309Snwhitehorn } 185217309Snwhitehorn return result; 186217309Snwhitehorn} 187217309Snwhitehorn 188217309Snwhitehornstatic long 189217309Snwhitehorntabize(MY_OBJ * obj, long val, long *first_pos) 190217309Snwhitehorn{ 191217309Snwhitehorn long fpos; 192217309Snwhitehorn long i, count, begin_line; 193217309Snwhitehorn char *buftab; 194217309Snwhitehorn 195217309Snwhitehorn if (!dialog_vars.tab_correct) 196217309Snwhitehorn return val; 197217309Snwhitehorn 198217309Snwhitehorn fpos = ftell_obj(obj); 199217309Snwhitehorn 200217309Snwhitehorn lseek_obj(obj, fpos - obj->fd_bytes_read, SEEK_SET); 201217309Snwhitehorn 202217309Snwhitehorn /* Allocate space for read buffer */ 203217309Snwhitehorn buftab = xalloc((size_t) val + 1); 204217309Snwhitehorn 205217309Snwhitehorn if ((read(obj->fd, buftab, (size_t) val)) == -1) 206217309Snwhitehorn dlg_exiterr("Error reading file in tabize()."); 207217309Snwhitehorn 208217309Snwhitehorn begin_line = count = 0; 209217309Snwhitehorn if (first_pos != 0) 210217309Snwhitehorn *first_pos = 0; 211217309Snwhitehorn 212217309Snwhitehorn for (i = 0; i < val; i++) { 213217309Snwhitehorn if ((first_pos != 0) && (count >= val)) { 214217309Snwhitehorn *first_pos = find_first(obj, buftab, i); 215217309Snwhitehorn break; 216217309Snwhitehorn } 217217309Snwhitehorn if (buftab[i] == TAB) 218217309Snwhitehorn count += dialog_state.tab_len 219217309Snwhitehorn - ((count - begin_line) % dialog_state.tab_len); 220217309Snwhitehorn else if (buftab[i] == '\n') { 221217309Snwhitehorn count++; 222217309Snwhitehorn begin_line = count; 223217309Snwhitehorn } else 224217309Snwhitehorn count++; 225217309Snwhitehorn } 226217309Snwhitehorn 227217309Snwhitehorn lseek_obj(obj, fpos, SEEK_SET); 228217309Snwhitehorn free(buftab); 229217309Snwhitehorn return count; 230217309Snwhitehorn} 231217309Snwhitehorn/* 232217309Snwhitehorn * Return current line of text. 233217309Snwhitehorn * 'page' should point to start of current line before calling, and will be 234217309Snwhitehorn * updated to point to start of next line. 235217309Snwhitehorn */ 236217309Snwhitehornstatic char * 237217309Snwhitehornget_line(MY_OBJ * obj) 238217309Snwhitehorn{ 239217309Snwhitehorn int i = 0; 240217309Snwhitehorn long fpos; 241217309Snwhitehorn 242217309Snwhitehorn obj->end_reached = FALSE; 243217309Snwhitehorn while (obj->buf[obj->in_buf] != '\n') { 244217309Snwhitehorn if (obj->buf[obj->in_buf] == '\0') { /* Either end of file or end of buffer reached */ 245217309Snwhitehorn fpos = ftell_obj(obj); 246217309Snwhitehorn 247217309Snwhitehorn if (fpos < obj->file_size) { /* Not end of file yet */ 248217309Snwhitehorn /* We've reached end of buffer, but not end of file yet, so 249217309Snwhitehorn * read next part of file into buffer 250217309Snwhitehorn */ 251217309Snwhitehorn read_high(obj, BUF_SIZE); 252217309Snwhitehorn obj->in_buf = 0; 253217309Snwhitehorn } else { 254217309Snwhitehorn if (!obj->end_reached) 255217309Snwhitehorn obj->end_reached = TRUE; 256217309Snwhitehorn break; 257217309Snwhitehorn } 258217309Snwhitehorn } else if (i < MAX_LEN) 259217309Snwhitehorn obj->line[i++] = obj->buf[obj->in_buf++]; 260217309Snwhitehorn else { 261217309Snwhitehorn if (i == MAX_LEN) /* Truncate lines longer than MAX_LEN characters */ 262217309Snwhitehorn obj->line[i++] = '\0'; 263217309Snwhitehorn obj->in_buf++; 264217309Snwhitehorn } 265217309Snwhitehorn } 266217309Snwhitehorn if (i <= MAX_LEN) 267217309Snwhitehorn obj->line[i] = '\0'; 268217309Snwhitehorn if (!obj->end_reached) 269217309Snwhitehorn obj->in_buf++; /* move past '\n' */ 270217309Snwhitehorn 271217309Snwhitehorn return obj->line; 272217309Snwhitehorn} 273217309Snwhitehorn 274217309Snwhitehornstatic bool 275217309Snwhitehornmatch_string(MY_OBJ * obj, char *string) 276217309Snwhitehorn{ 277217309Snwhitehorn char *match = get_line(obj); 278217309Snwhitehorn return strstr(match, string) != 0; 279217309Snwhitehorn} 280217309Snwhitehorn 281217309Snwhitehorn/* 282217309Snwhitehorn * Go back 'n' lines in text file. Called by dialog_textbox(). 283217309Snwhitehorn * 'in_buf' will be updated to point to the desired line in 'buf'. 284217309Snwhitehorn */ 285217309Snwhitehornstatic void 286217309Snwhitehornback_lines(MY_OBJ * obj, long n) 287217309Snwhitehorn{ 288217309Snwhitehorn int i; 289217309Snwhitehorn long fpos; 290217309Snwhitehorn long val_to_tabize; 291217309Snwhitehorn 292217309Snwhitehorn obj->begin_reached = FALSE; 293217309Snwhitehorn /* We have to distinguish between end_reached and !end_reached since at end 294217309Snwhitehorn * of file, the line is not ended by a '\n'. The code inside 'if' 295217309Snwhitehorn * basically does a '--in_buf' to move one character backward so as to 296217309Snwhitehorn * skip '\n' of the previous line */ 297217309Snwhitehorn if (!obj->end_reached) { 298217309Snwhitehorn /* Either beginning of buffer or beginning of file reached? */ 299217309Snwhitehorn 300217309Snwhitehorn if (obj->in_buf == 0) { 301217309Snwhitehorn fpos = ftell_obj(obj); 302217309Snwhitehorn 303217309Snwhitehorn if (fpos > obj->fd_bytes_read) { /* Not beginning of file yet */ 304217309Snwhitehorn /* We've reached beginning of buffer, but not beginning of file 305217309Snwhitehorn * yet, so read previous part of file into buffer. Note that 306217309Snwhitehorn * we only move backward for BUF_SIZE/2 bytes, but not BUF_SIZE 307217309Snwhitehorn * bytes to avoid re-reading again in print_page() later 308217309Snwhitehorn */ 309217309Snwhitehorn /* Really possible to move backward BUF_SIZE/2 bytes? */ 310217309Snwhitehorn if (fpos < BUF_SIZE / 2 + obj->fd_bytes_read) { 311217309Snwhitehorn /* No, move less than */ 312220749Snwhitehorn lseek_obj(obj, 0L, SEEK_SET); 313217309Snwhitehorn val_to_tabize = fpos - obj->fd_bytes_read; 314217309Snwhitehorn } else { /* Move backward BUF_SIZE/2 bytes */ 315217309Snwhitehorn lseek_obj(obj, -(BUF_SIZE / 2 + obj->fd_bytes_read), SEEK_CUR); 316217309Snwhitehorn val_to_tabize = BUF_SIZE / 2; 317217309Snwhitehorn } 318217309Snwhitehorn read_high(obj, BUF_SIZE); 319217309Snwhitehorn 320217309Snwhitehorn obj->in_buf = tabize(obj, val_to_tabize, (long *) 0); 321217309Snwhitehorn 322217309Snwhitehorn } else { /* Beginning of file reached */ 323217309Snwhitehorn obj->begin_reached = TRUE; 324217309Snwhitehorn return; 325217309Snwhitehorn } 326217309Snwhitehorn } 327217309Snwhitehorn obj->in_buf--; 328217309Snwhitehorn if (obj->buf[obj->in_buf] != '\n') 329217309Snwhitehorn /* Something's wrong... */ 330217309Snwhitehorn dlg_exiterr("Internal error in back_lines()."); 331217309Snwhitehorn } 332217309Snwhitehorn 333217309Snwhitehorn /* Go back 'n' lines */ 334217309Snwhitehorn for (i = 0; i < n; i++) { 335217309Snwhitehorn do { 336217309Snwhitehorn if (obj->in_buf == 0) { 337217309Snwhitehorn fpos = ftell_obj(obj); 338217309Snwhitehorn 339217309Snwhitehorn if (fpos > obj->fd_bytes_read) { 340217309Snwhitehorn /* Really possible to move backward BUF_SIZE/2 bytes? */ 341217309Snwhitehorn if (fpos < BUF_SIZE / 2 + obj->fd_bytes_read) { 342217309Snwhitehorn /* No, move less than */ 343220749Snwhitehorn lseek_obj(obj, 0L, SEEK_SET); 344217309Snwhitehorn val_to_tabize = fpos - obj->fd_bytes_read; 345217309Snwhitehorn } else { /* Move backward BUF_SIZE/2 bytes */ 346217309Snwhitehorn lseek_obj(obj, -(BUF_SIZE / 2 + obj->fd_bytes_read), SEEK_CUR); 347217309Snwhitehorn val_to_tabize = BUF_SIZE / 2; 348217309Snwhitehorn } 349217309Snwhitehorn read_high(obj, BUF_SIZE); 350217309Snwhitehorn 351217309Snwhitehorn obj->in_buf = tabize(obj, val_to_tabize, (long *) 0); 352217309Snwhitehorn 353217309Snwhitehorn } else { /* Beginning of file reached */ 354217309Snwhitehorn obj->begin_reached = TRUE; 355217309Snwhitehorn return; 356217309Snwhitehorn } 357217309Snwhitehorn } 358217309Snwhitehorn } while (obj->buf[--(obj->in_buf)] != '\n'); 359217309Snwhitehorn } 360217309Snwhitehorn obj->in_buf++; 361217309Snwhitehorn} 362217309Snwhitehorn 363217309Snwhitehorn/* 364217309Snwhitehorn * Print a new line of text. 365217309Snwhitehorn */ 366217309Snwhitehornstatic void 367217309Snwhitehornprint_line(MY_OBJ * obj, int row, int width) 368217309Snwhitehorn{ 369217309Snwhitehorn if (wmove(obj->text, row, 0) != ERR) { 370217309Snwhitehorn int i, y, x; 371217309Snwhitehorn char *line = get_line(obj); 372217309Snwhitehorn const int *cols = dlg_index_columns(line); 373217309Snwhitehorn const int *indx = dlg_index_wchars(line); 374217309Snwhitehorn int limit = dlg_count_wchars(line); 375217309Snwhitehorn int first = 0; 376217309Snwhitehorn int last = limit; 377217309Snwhitehorn 378217309Snwhitehorn if (width > getmaxx(obj->text)) 379217309Snwhitehorn width = getmaxx(obj->text); 380217309Snwhitehorn --width; /* for the leading ' ' */ 381217309Snwhitehorn 382217309Snwhitehorn for (i = 0; i <= limit && cols[i] < obj->hscroll; ++i) 383217309Snwhitehorn first = i; 384217309Snwhitehorn 385217309Snwhitehorn for (i = first; (i <= limit) && ((cols[i] - cols[first]) < width); ++i) 386217309Snwhitehorn last = i; 387217309Snwhitehorn 388217309Snwhitehorn (void) waddch(obj->text, ' '); 389217309Snwhitehorn (void) waddnstr(obj->text, line + indx[first], indx[last] - indx[first]); 390217309Snwhitehorn 391217309Snwhitehorn getyx(obj->text, y, x); 392217309Snwhitehorn if (y == row) { /* Clear 'residue' of previous line */ 393217309Snwhitehorn for (i = 0; i <= width - x; i++) { 394217309Snwhitehorn (void) waddch(obj->text, ' '); 395217309Snwhitehorn } 396217309Snwhitehorn } 397217309Snwhitehorn } 398217309Snwhitehorn} 399217309Snwhitehorn 400217309Snwhitehorn/* 401217309Snwhitehorn * Print a new page of text. 402217309Snwhitehorn */ 403217309Snwhitehornstatic void 404217309Snwhitehornprint_page(MY_OBJ * obj, int height, int width) 405217309Snwhitehorn{ 406217309Snwhitehorn int i, passed_end = 0; 407217309Snwhitehorn 408217309Snwhitehorn obj->page_length = 0; 409217309Snwhitehorn for (i = 0; i < height; i++) { 410217309Snwhitehorn print_line(obj, i, width); 411217309Snwhitehorn if (!passed_end) 412217309Snwhitehorn obj->page_length++; 413217309Snwhitehorn if (obj->end_reached && !passed_end) 414217309Snwhitehorn passed_end = 1; 415217309Snwhitehorn } 416217309Snwhitehorn (void) wnoutrefresh(obj->text); 417217309Snwhitehorn} 418217309Snwhitehorn 419217309Snwhitehorn/* 420217309Snwhitehorn * Print current position 421217309Snwhitehorn */ 422217309Snwhitehornstatic void 423217309Snwhitehornprint_position(MY_OBJ * obj, WINDOW *win, int height, int width) 424217309Snwhitehorn{ 425217309Snwhitehorn long fpos; 426217309Snwhitehorn long size; 427217309Snwhitehorn long first = -1; 428217309Snwhitehorn 429217309Snwhitehorn fpos = ftell_obj(obj); 430217309Snwhitehorn if (dialog_vars.tab_correct) 431217309Snwhitehorn size = tabize(obj, obj->in_buf, &first); 432217309Snwhitehorn else 433217309Snwhitehorn first = find_first(obj, obj->buf, size = obj->in_buf); 434217309Snwhitehorn 435217309Snwhitehorn dlg_draw_scrollbar(win, 436217309Snwhitehorn first, 437217309Snwhitehorn fpos - obj->fd_bytes_read + size, 438217309Snwhitehorn fpos - obj->fd_bytes_read + size, 439217309Snwhitehorn obj->file_size, 440217309Snwhitehorn 0, PAGE_WIDTH, 441217309Snwhitehorn 0, PAGE_LENGTH + 1, 442217309Snwhitehorn border_attr, 443217309Snwhitehorn border_attr); 444217309Snwhitehorn} 445217309Snwhitehorn 446217309Snwhitehorn/* 447217309Snwhitehorn * Display a dialog box and get the search term from user. 448217309Snwhitehorn */ 449217309Snwhitehornstatic int 450217309Snwhitehornget_search_term(WINDOW *dialog, char *input, int height, int width) 451217309Snwhitehorn{ 452217309Snwhitehorn /* *INDENT-OFF* */ 453217309Snwhitehorn static DLG_KEYS_BINDING binding[] = { 454217309Snwhitehorn INPUTSTR_BINDINGS, 455224014Snwhitehorn HELPKEY_BINDINGS, 456217309Snwhitehorn ENTERKEY_BINDINGS, 457217309Snwhitehorn END_KEYS_BINDING 458217309Snwhitehorn }; 459217309Snwhitehorn /* *INDENT-ON* */ 460217309Snwhitehorn 461217309Snwhitehorn int old_x, old_y; 462217309Snwhitehorn int box_x, box_y; 463217309Snwhitehorn int box_height, box_width; 464217309Snwhitehorn int offset = 0; 465217309Snwhitehorn int key = 0; 466217309Snwhitehorn int fkey = 0; 467217309Snwhitehorn bool first = TRUE; 468217309Snwhitehorn int result = DLG_EXIT_UNKNOWN; 469220749Snwhitehorn const char *caption = _("Search"); 470217309Snwhitehorn int len_caption = dlg_count_columns(caption); 471217309Snwhitehorn const int *indx; 472217309Snwhitehorn int limit; 473217309Snwhitehorn WINDOW *widget; 474217309Snwhitehorn 475217309Snwhitehorn getbegyx(dialog, old_y, old_x); 476217309Snwhitehorn 477217309Snwhitehorn box_height = 1 + (2 * MARGIN); 478217309Snwhitehorn box_width = len_caption + (2 * (MARGIN + 2)); 479217309Snwhitehorn box_width = MAX(box_width, 30); 480217309Snwhitehorn box_width = MIN(box_width, getmaxx(dialog) - 2 * MARGIN); 481217309Snwhitehorn len_caption = MIN(len_caption, box_width - (2 * (MARGIN + 1))); 482217309Snwhitehorn 483217309Snwhitehorn box_x = (width - box_width) / 2; 484217309Snwhitehorn box_y = (height - box_height) / 2; 485217309Snwhitehorn widget = dlg_new_modal_window(dialog, 486217309Snwhitehorn box_height, box_width, 487217309Snwhitehorn old_y + box_y, old_x + box_x); 488217309Snwhitehorn keypad(widget, TRUE); 489217309Snwhitehorn dlg_register_window(widget, "searchbox", binding); 490217309Snwhitehorn 491217309Snwhitehorn dlg_draw_box(widget, 0, 0, box_height, box_width, 492217309Snwhitehorn searchbox_attr, 493217309Snwhitehorn searchbox_border_attr); 494217309Snwhitehorn wattrset(widget, searchbox_title_attr); 495217309Snwhitehorn (void) wmove(widget, 0, (box_width - len_caption) / 2); 496217309Snwhitehorn 497217309Snwhitehorn indx = dlg_index_wchars(caption); 498217309Snwhitehorn limit = dlg_limit_columns(caption, len_caption, 0); 499217309Snwhitehorn (void) waddnstr(widget, caption + indx[0], indx[limit] - indx[0]); 500217309Snwhitehorn 501217309Snwhitehorn box_y++; 502217309Snwhitehorn box_x++; 503217309Snwhitehorn box_width -= 2; 504217309Snwhitehorn offset = dlg_count_columns(input); 505217309Snwhitehorn 506217309Snwhitehorn while (result == DLG_EXIT_UNKNOWN) { 507217309Snwhitehorn if (!first) { 508217309Snwhitehorn key = dlg_getc(widget, &fkey); 509217309Snwhitehorn if (fkey) { 510217309Snwhitehorn switch (fkey) { 511217309Snwhitehorn#ifdef KEY_RESIZE 512217309Snwhitehorn case KEY_RESIZE: 513217309Snwhitehorn result = DLG_EXIT_CANCEL; 514217309Snwhitehorn continue; 515217309Snwhitehorn#endif 516217309Snwhitehorn case DLGK_ENTER: 517217309Snwhitehorn result = DLG_EXIT_OK; 518217309Snwhitehorn continue; 519217309Snwhitehorn } 520217309Snwhitehorn } else if (key == ESC) { 521217309Snwhitehorn result = DLG_EXIT_ESC; 522217309Snwhitehorn continue; 523217309Snwhitehorn } else if (key == ERR) { 524217309Snwhitehorn napms(50); 525217309Snwhitehorn continue; 526217309Snwhitehorn } 527217309Snwhitehorn } 528217309Snwhitehorn if (dlg_edit_string(input, &offset, key, fkey, first)) { 529217309Snwhitehorn dlg_show_string(widget, input, offset, searchbox_attr, 530217309Snwhitehorn 1, 1, box_width, FALSE, first); 531217309Snwhitehorn first = FALSE; 532217309Snwhitehorn } 533217309Snwhitehorn } 534217309Snwhitehorn dlg_del_window(widget); 535217309Snwhitehorn return result; 536217309Snwhitehorn} 537217309Snwhitehorn 538217309Snwhitehornstatic bool 539217309Snwhitehornperform_search(MY_OBJ * obj, int height, int width, int key, char *search_term) 540217309Snwhitehorn{ 541217309Snwhitehorn int dir; 542217309Snwhitehorn long tempinx; 543217309Snwhitehorn long fpos; 544217309Snwhitehorn int result; 545217309Snwhitehorn bool found; 546217309Snwhitehorn bool temp, temp1; 547217309Snwhitehorn bool moved = FALSE; 548217309Snwhitehorn 549217309Snwhitehorn /* set search direction */ 550217309Snwhitehorn dir = (key == '/' || key == 'n') ? 1 : 0; 551217309Snwhitehorn if (dir ? !obj->end_reached : !obj->begin_reached) { 552217309Snwhitehorn if (key == 'n' || key == 'N') { 553217309Snwhitehorn if (search_term[0] == '\0') { /* No search term yet */ 554217309Snwhitehorn (void) beep(); 555217309Snwhitehorn return FALSE; 556217309Snwhitehorn } 557217309Snwhitehorn /* Get search term from user */ 558217309Snwhitehorn } else if ((result = get_search_term(obj->text, search_term, 559217309Snwhitehorn PAGE_LENGTH, 560217309Snwhitehorn PAGE_WIDTH)) != DLG_EXIT_OK 561217309Snwhitehorn || search_term[0] == '\0') { 562217309Snwhitehorn#ifdef KEY_RESIZE 563217309Snwhitehorn if (result == DLG_EXIT_CANCEL) { 564217309Snwhitehorn ungetch(key); 565217309Snwhitehorn ungetch(KEY_RESIZE); 566217309Snwhitehorn /* FALLTHRU */ 567217309Snwhitehorn } 568217309Snwhitehorn#endif 569217309Snwhitehorn /* ESC pressed, or no search term, reprint page to clear box */ 570217309Snwhitehorn wattrset(obj->text, dialog_attr); 571217309Snwhitehorn back_lines(obj, obj->page_length); 572217309Snwhitehorn return TRUE; 573217309Snwhitehorn } 574217309Snwhitehorn /* Save variables for restoring in case search term can't be found */ 575217309Snwhitehorn tempinx = obj->in_buf; 576217309Snwhitehorn temp = obj->begin_reached; 577217309Snwhitehorn temp1 = obj->end_reached; 578217309Snwhitehorn fpos = ftell_obj(obj) - obj->fd_bytes_read; 579217309Snwhitehorn /* update 'in_buf' to point to next (previous) line before 580217309Snwhitehorn forward (backward) searching */ 581217309Snwhitehorn back_lines(obj, (dir 582217309Snwhitehorn ? obj->page_length - 1 583217309Snwhitehorn : obj->page_length + 1)); 584217309Snwhitehorn found = FALSE; 585217309Snwhitehorn if (dir) { /* Forward search */ 586217309Snwhitehorn while ((found = match_string(obj, search_term)) == FALSE) { 587217309Snwhitehorn if (obj->end_reached) 588217309Snwhitehorn break; 589217309Snwhitehorn } 590217309Snwhitehorn } else { /* Backward search */ 591217309Snwhitehorn while ((found = match_string(obj, search_term)) == FALSE) { 592217309Snwhitehorn if (obj->begin_reached) 593217309Snwhitehorn break; 594220749Snwhitehorn back_lines(obj, 2L); 595217309Snwhitehorn } 596217309Snwhitehorn } 597217309Snwhitehorn if (found == FALSE) { /* not found */ 598217309Snwhitehorn (void) beep(); 599217309Snwhitehorn /* Restore program state to that before searching */ 600217309Snwhitehorn lseek_obj(obj, fpos, SEEK_SET); 601217309Snwhitehorn 602217309Snwhitehorn read_high(obj, BUF_SIZE); 603217309Snwhitehorn 604217309Snwhitehorn obj->in_buf = tempinx; 605217309Snwhitehorn obj->begin_reached = temp; 606217309Snwhitehorn obj->end_reached = temp1; 607217309Snwhitehorn /* move 'in_buf' to point to start of current page to 608217309Snwhitehorn * re-print current page. Note that 'in_buf' always points 609217309Snwhitehorn * to start of next page, so this is necessary 610217309Snwhitehorn */ 611217309Snwhitehorn back_lines(obj, obj->page_length); 612217309Snwhitehorn } else { /* Search term found */ 613220749Snwhitehorn back_lines(obj, 1L); 614217309Snwhitehorn } 615217309Snwhitehorn /* Reprint page */ 616217309Snwhitehorn wattrset(obj->text, dialog_attr); 617217309Snwhitehorn moved = TRUE; 618217309Snwhitehorn } else { /* no need to find */ 619217309Snwhitehorn (void) beep(); 620217309Snwhitehorn } 621217309Snwhitehorn return moved; 622217309Snwhitehorn} 623217309Snwhitehorn 624217309Snwhitehorn/* 625217309Snwhitehorn * Display text from a file in a dialog box. 626217309Snwhitehorn */ 627217309Snwhitehornint 628217309Snwhitehorndialog_textbox(const char *title, const char *file, int height, int width) 629217309Snwhitehorn{ 630217309Snwhitehorn /* *INDENT-OFF* */ 631217309Snwhitehorn static DLG_KEYS_BINDING binding[] = { 632224014Snwhitehorn HELPKEY_BINDINGS, 633217309Snwhitehorn ENTERKEY_BINDINGS, 634217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_DOWN, 'J' ), 635217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_DOWN, 'j' ), 636217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_DOWN ), 637217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_LEFT, 'H' ), 638217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_LEFT, 'h' ), 639217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFT ), 640217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'L' ), 641217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'l' ), 642217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ), 643217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_UP, 'K' ), 644217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_UP, 'k' ), 645217309Snwhitehorn DLG_KEYS_DATA( DLGK_GRID_UP, KEY_UP ), 646217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_FIRST, 'g' ), 647217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ), 648217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_LAST, 'G' ), 649217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ), 650217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ), 651217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_NEXT, ' ' ), 652217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), 653217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_PREV, 'B' ), 654217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_PREV, 'b' ), 655217309Snwhitehorn DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), 656217309Snwhitehorn DLG_KEYS_DATA( DLGK_BEGIN, '0' ), 657217309Snwhitehorn DLG_KEYS_DATA( DLGK_BEGIN, KEY_BEG ), 658217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), 659217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), 660217309Snwhitehorn END_KEYS_BINDING 661217309Snwhitehorn }; 662217309Snwhitehorn /* *INDENT-ON* */ 663217309Snwhitehorn 664217309Snwhitehorn#ifdef KEY_RESIZE 665217309Snwhitehorn int old_height = height; 666217309Snwhitehorn int old_width = width; 667217309Snwhitehorn#endif 668217309Snwhitehorn long fpos; 669217309Snwhitehorn int x, y, cur_x, cur_y; 670217309Snwhitehorn int key = 0, fkey; 671217309Snwhitehorn int next = 0; 672217309Snwhitehorn int i, code, passed_end; 673217309Snwhitehorn char search_term[MAX_LEN + 1]; 674217309Snwhitehorn MY_OBJ obj; 675217309Snwhitehorn WINDOW *dialog; 676217309Snwhitehorn bool moved; 677217309Snwhitehorn int result = DLG_EXIT_UNKNOWN; 678217309Snwhitehorn int button = dialog_vars.extra_button ? dlg_defaultno_button() : 0; 679217309Snwhitehorn int min_width = 12; 680217309Snwhitehorn 681217309Snwhitehorn search_term[0] = '\0'; /* no search term entered yet */ 682217309Snwhitehorn 683217309Snwhitehorn memset(&obj, 0, sizeof(obj)); 684217309Snwhitehorn 685217309Snwhitehorn obj.begin_reached = TRUE; 686217309Snwhitehorn obj.buffer_first = TRUE; 687217309Snwhitehorn obj.end_reached = FALSE; 688217309Snwhitehorn obj.buttons = dlg_exit_label(); 689217309Snwhitehorn 690217309Snwhitehorn /* Open input file for reading */ 691217309Snwhitehorn if ((obj.fd = open(file, O_RDONLY)) == -1) 692217309Snwhitehorn dlg_exiterr("Can't open input file %s", file); 693217309Snwhitehorn 694217309Snwhitehorn /* Get file size. Actually, 'file_size' is the real file size - 1, 695217309Snwhitehorn since it's only the last byte offset from the beginning */ 696220749Snwhitehorn obj.file_size = lseek_obj(&obj, 0L, SEEK_END); 697217309Snwhitehorn 698217309Snwhitehorn /* Restore file pointer to beginning of file after getting file size */ 699220749Snwhitehorn lseek_obj(&obj, 0L, SEEK_SET); 700217309Snwhitehorn 701217309Snwhitehorn read_high(&obj, BUF_SIZE); 702217309Snwhitehorn 703217309Snwhitehorn dlg_button_layout(obj.buttons, &min_width); 704217309Snwhitehorn 705217309Snwhitehorn#ifdef KEY_RESIZE 706217309Snwhitehorn retry: 707217309Snwhitehorn#endif 708217309Snwhitehorn moved = TRUE; 709217309Snwhitehorn 710217309Snwhitehorn dlg_auto_sizefile(title, file, &height, &width, 2, min_width); 711217309Snwhitehorn dlg_print_size(height, width); 712217309Snwhitehorn dlg_ctl_size(height, width); 713217309Snwhitehorn 714217309Snwhitehorn x = dlg_box_x_ordinate(width); 715217309Snwhitehorn y = dlg_box_y_ordinate(height); 716217309Snwhitehorn 717217309Snwhitehorn dialog = dlg_new_window(height, width, y, x); 718217309Snwhitehorn dlg_register_window(dialog, "textbox", binding); 719217309Snwhitehorn dlg_register_buttons(dialog, "textbox", obj.buttons); 720217309Snwhitehorn 721217309Snwhitehorn dlg_mouse_setbase(x, y); 722217309Snwhitehorn 723217309Snwhitehorn /* Create window for text region, used for scrolling text */ 724217309Snwhitehorn obj.text = dlg_sub_window(dialog, PAGE_LENGTH, PAGE_WIDTH, y + 1, x + 1); 725217309Snwhitehorn 726217309Snwhitehorn /* register the new window, along with its borders */ 727217309Snwhitehorn dlg_mouse_mkbigregion(0, 0, PAGE_LENGTH + 2, width, KEY_MAX, 1, 1, 1 /* lines */ ); 728217309Snwhitehorn dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 729217309Snwhitehorn dlg_draw_bottom_box(dialog); 730217309Snwhitehorn dlg_draw_title(dialog, title); 731217309Snwhitehorn 732217309Snwhitehorn dlg_draw_buttons(dialog, PAGE_LENGTH + 2, 0, obj.buttons, button, FALSE, width); 733217309Snwhitehorn (void) wnoutrefresh(dialog); 734217309Snwhitehorn getyx(dialog, cur_y, cur_x); /* Save cursor position */ 735217309Snwhitehorn 736217309Snwhitehorn dlg_attr_clear(obj.text, PAGE_LENGTH, PAGE_WIDTH, dialog_attr); 737217309Snwhitehorn 738217309Snwhitehorn while (result == DLG_EXIT_UNKNOWN) { 739217309Snwhitehorn 740217309Snwhitehorn /* 741217309Snwhitehorn * Update the screen according to whether we shifted up/down by a line 742217309Snwhitehorn * or not. 743217309Snwhitehorn */ 744217309Snwhitehorn if (moved) { 745217309Snwhitehorn if (next < 0) { 746217309Snwhitehorn (void) scrollok(obj.text, TRUE); 747217309Snwhitehorn (void) scroll(obj.text); /* Scroll text region up one line */ 748217309Snwhitehorn (void) scrollok(obj.text, FALSE); 749217309Snwhitehorn print_line(&obj, PAGE_LENGTH - 1, PAGE_WIDTH); 750217309Snwhitehorn (void) wnoutrefresh(obj.text); 751217309Snwhitehorn } else if (next > 0) { 752217309Snwhitehorn /* 753217309Snwhitehorn * We don't call print_page() here but use scrolling to ensure 754217309Snwhitehorn * faster screen update. However, 'end_reached' and 755217309Snwhitehorn * 'page_length' should still be updated, and 'in_buf' should 756217309Snwhitehorn * point to start of next page. This is done by calling 757217309Snwhitehorn * get_line() in the following 'for' loop. 758217309Snwhitehorn */ 759217309Snwhitehorn (void) scrollok(obj.text, TRUE); 760217309Snwhitehorn (void) wscrl(obj.text, -1); /* Scroll text region down one line */ 761217309Snwhitehorn (void) scrollok(obj.text, FALSE); 762217309Snwhitehorn obj.page_length = 0; 763217309Snwhitehorn passed_end = 0; 764217309Snwhitehorn for (i = 0; i < PAGE_LENGTH; i++) { 765217309Snwhitehorn if (!i) { 766217309Snwhitehorn print_line(&obj, 0, PAGE_WIDTH); /* print first line of page */ 767217309Snwhitehorn (void) wnoutrefresh(obj.text); 768217309Snwhitehorn } else 769217309Snwhitehorn (void) get_line(&obj); /* Called to update 'end_reached' and 'in_buf' */ 770217309Snwhitehorn if (!passed_end) 771217309Snwhitehorn obj.page_length++; 772217309Snwhitehorn if (obj.end_reached && !passed_end) 773217309Snwhitehorn passed_end = 1; 774217309Snwhitehorn } 775217309Snwhitehorn } else { 776217309Snwhitehorn print_page(&obj, PAGE_LENGTH, PAGE_WIDTH); 777217309Snwhitehorn } 778217309Snwhitehorn print_position(&obj, dialog, height, width); 779217309Snwhitehorn (void) wmove(dialog, cur_y, cur_x); /* Restore cursor position */ 780217309Snwhitehorn wrefresh(dialog); 781217309Snwhitehorn } 782217309Snwhitehorn moved = FALSE; /* assume we'll not move */ 783217309Snwhitehorn next = 0; /* ...but not scroll by a line */ 784217309Snwhitehorn 785217309Snwhitehorn key = dlg_mouse_wgetch(dialog, &fkey); 786217309Snwhitehorn if (dlg_result_key(key, fkey, &result)) 787217309Snwhitehorn break; 788217309Snwhitehorn 789217309Snwhitehorn if (!fkey && (code = dlg_char_to_button(key, obj.buttons)) >= 0) { 790217309Snwhitehorn result = dlg_ok_buttoncode(code); 791217309Snwhitehorn break; 792217309Snwhitehorn } 793217309Snwhitehorn 794217309Snwhitehorn if (fkey) { 795217309Snwhitehorn switch (key) { 796217309Snwhitehorn default: 797217309Snwhitehorn if (is_DLGK_MOUSE(key)) { 798217309Snwhitehorn result = dlg_exit_buttoncode(key - M_EVENT); 799217309Snwhitehorn if (result < 0) 800217309Snwhitehorn result = DLG_EXIT_OK; 801217309Snwhitehorn } else { 802217309Snwhitehorn beep(); 803217309Snwhitehorn } 804217309Snwhitehorn break; 805217309Snwhitehorn case DLGK_FIELD_NEXT: 806217309Snwhitehorn button = dlg_next_button(obj.buttons, button); 807217309Snwhitehorn if (button < 0) 808217309Snwhitehorn button = 0; 809217309Snwhitehorn dlg_draw_buttons(dialog, 810217309Snwhitehorn height - 2, 0, 811217309Snwhitehorn obj.buttons, button, 812217309Snwhitehorn FALSE, width); 813217309Snwhitehorn break; 814217309Snwhitehorn case DLGK_FIELD_PREV: 815217309Snwhitehorn button = dlg_prev_button(obj.buttons, button); 816217309Snwhitehorn if (button < 0) 817217309Snwhitehorn button = 0; 818217309Snwhitehorn dlg_draw_buttons(dialog, 819217309Snwhitehorn height - 2, 0, 820217309Snwhitehorn obj.buttons, button, 821217309Snwhitehorn FALSE, width); 822217309Snwhitehorn break; 823217309Snwhitehorn case DLGK_ENTER: 824224014Snwhitehorn if (dialog_vars.nook) 825224014Snwhitehorn result = DLG_EXIT_OK; 826224014Snwhitehorn else 827224014Snwhitehorn result = dlg_exit_buttoncode(button); 828217309Snwhitehorn break; 829217309Snwhitehorn case DLGK_PAGE_FIRST: 830217309Snwhitehorn if (!obj.begin_reached) { 831217309Snwhitehorn obj.begin_reached = 1; 832217309Snwhitehorn /* First page not in buffer? */ 833217309Snwhitehorn fpos = ftell_obj(&obj); 834217309Snwhitehorn 835217309Snwhitehorn if (fpos > obj.fd_bytes_read) { 836217309Snwhitehorn /* Yes, we have to read it in */ 837220749Snwhitehorn lseek_obj(&obj, 0L, SEEK_SET); 838217309Snwhitehorn 839217309Snwhitehorn read_high(&obj, BUF_SIZE); 840217309Snwhitehorn } 841217309Snwhitehorn obj.in_buf = 0; 842217309Snwhitehorn moved = TRUE; 843217309Snwhitehorn } 844217309Snwhitehorn break; 845217309Snwhitehorn case DLGK_PAGE_LAST: 846217309Snwhitehorn obj.end_reached = TRUE; 847217309Snwhitehorn /* Last page not in buffer? */ 848217309Snwhitehorn fpos = ftell_obj(&obj); 849217309Snwhitehorn 850217309Snwhitehorn if (fpos < obj.file_size) { 851217309Snwhitehorn /* Yes, we have to read it in */ 852217309Snwhitehorn lseek_obj(&obj, -BUF_SIZE, SEEK_END); 853217309Snwhitehorn 854217309Snwhitehorn read_high(&obj, BUF_SIZE); 855217309Snwhitehorn } 856217309Snwhitehorn obj.in_buf = obj.bytes_read; 857220749Snwhitehorn back_lines(&obj, (long) PAGE_LENGTH); 858217309Snwhitehorn moved = TRUE; 859217309Snwhitehorn break; 860217309Snwhitehorn case DLGK_GRID_UP: /* Previous line */ 861217309Snwhitehorn if (!obj.begin_reached) { 862217309Snwhitehorn back_lines(&obj, obj.page_length + 1); 863217309Snwhitehorn next = 1; 864217309Snwhitehorn moved = TRUE; 865217309Snwhitehorn } 866217309Snwhitehorn break; 867217309Snwhitehorn case DLGK_PAGE_PREV: /* Previous page */ 868217309Snwhitehorn case DLGK_MOUSE(KEY_PPAGE): 869217309Snwhitehorn if (!obj.begin_reached) { 870217309Snwhitehorn back_lines(&obj, obj.page_length + PAGE_LENGTH); 871217309Snwhitehorn moved = TRUE; 872217309Snwhitehorn } 873217309Snwhitehorn break; 874217309Snwhitehorn case DLGK_GRID_DOWN: /* Next line */ 875217309Snwhitehorn if (!obj.end_reached) { 876217309Snwhitehorn obj.begin_reached = 0; 877217309Snwhitehorn next = -1; 878217309Snwhitehorn moved = TRUE; 879217309Snwhitehorn } 880217309Snwhitehorn break; 881217309Snwhitehorn case DLGK_PAGE_NEXT: /* Next page */ 882217309Snwhitehorn case DLGK_MOUSE(KEY_NPAGE): 883217309Snwhitehorn if (!obj.end_reached) { 884217309Snwhitehorn obj.begin_reached = 0; 885217309Snwhitehorn moved = TRUE; 886217309Snwhitehorn } 887217309Snwhitehorn break; 888217309Snwhitehorn case DLGK_BEGIN: /* Beginning of line */ 889217309Snwhitehorn if (obj.hscroll > 0) { 890217309Snwhitehorn obj.hscroll = 0; 891217309Snwhitehorn /* Reprint current page to scroll horizontally */ 892217309Snwhitehorn back_lines(&obj, obj.page_length); 893217309Snwhitehorn moved = TRUE; 894217309Snwhitehorn } 895217309Snwhitehorn break; 896217309Snwhitehorn case DLGK_GRID_LEFT: /* Scroll left */ 897217309Snwhitehorn if (obj.hscroll > 0) { 898217309Snwhitehorn obj.hscroll--; 899217309Snwhitehorn /* Reprint current page to scroll horizontally */ 900217309Snwhitehorn back_lines(&obj, obj.page_length); 901217309Snwhitehorn moved = TRUE; 902217309Snwhitehorn } 903217309Snwhitehorn break; 904217309Snwhitehorn case DLGK_GRID_RIGHT: /* Scroll right */ 905217309Snwhitehorn if (obj.hscroll < MAX_LEN) { 906217309Snwhitehorn obj.hscroll++; 907217309Snwhitehorn /* Reprint current page to scroll horizontally */ 908217309Snwhitehorn back_lines(&obj, obj.page_length); 909217309Snwhitehorn moved = TRUE; 910217309Snwhitehorn } 911217309Snwhitehorn break; 912217309Snwhitehorn#ifdef KEY_RESIZE 913217309Snwhitehorn case KEY_RESIZE: 914217309Snwhitehorn /* reset data */ 915217309Snwhitehorn height = old_height; 916217309Snwhitehorn width = old_width; 917217309Snwhitehorn back_lines(&obj, obj.page_length); 918217309Snwhitehorn moved = TRUE; 919217309Snwhitehorn /* repaint */ 920217309Snwhitehorn dlg_clear(); 921217309Snwhitehorn dlg_del_window(dialog); 922217309Snwhitehorn refresh(); 923217309Snwhitehorn dlg_mouse_free_regions(); 924217309Snwhitehorn goto retry; 925217309Snwhitehorn#endif 926217309Snwhitehorn } 927217309Snwhitehorn } else { 928217309Snwhitehorn switch (key) { 929217309Snwhitehorn case '/': /* Forward search */ 930217309Snwhitehorn case 'n': /* Repeat forward search */ 931217309Snwhitehorn case '?': /* Backward search */ 932217309Snwhitehorn case 'N': /* Repeat backward search */ 933217309Snwhitehorn moved = perform_search(&obj, height, width, key, search_term); 934217309Snwhitehorn fkey = FALSE; 935217309Snwhitehorn break; 936217309Snwhitehorn default: 937217309Snwhitehorn beep(); 938217309Snwhitehorn break; 939217309Snwhitehorn } 940217309Snwhitehorn } 941217309Snwhitehorn } 942217309Snwhitehorn 943217309Snwhitehorn dlg_del_window(dialog); 944217309Snwhitehorn free(obj.buf); 945217309Snwhitehorn (void) close(obj.fd); 946217309Snwhitehorn dlg_mouse_free_regions(); 947217309Snwhitehorn return result; 948217309Snwhitehorn} 949