Back to index

tetex-bin  3.0
textbox.c
Go to the documentation of this file.
00001 /*
00002  *  textbox.c -- implements the text box
00003  *
00004  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 
00022 #include "dialog.h"
00023 
00024 
00025 static void back_lines(int n);
00026 static void print_page(WINDOW *win, int height, int width);
00027 static void print_line(WINDOW *win, int row, int width);
00028 static char *get_line(void);
00029 static int get_search_term(WINDOW *win, char *search_term, int height, int width);
00030 static void print_position(WINDOW *win, int height, int width);
00031 
00032 
00033 static int hscroll = 0, fd, file_size, bytes_read, begin_reached = 1,
00034            end_reached = 0, page_length;
00035 static char *buf, *page;
00036 
00037 
00038 /*
00039  * Display text from a file in a dialog box.
00040  */
00041 int dialog_textbox(char *title, char *file, int height, int width)
00042 {
00043   int i, x, y, cur_x, cur_y, fpos, key = 0, dir, temp, temp1;
00044 #ifdef HAVE_NCURSES
00045   int passed_end;
00046 #endif
00047   char search_term[MAX_LEN+1], *tempptr, *found;
00048   WINDOW *dialog, *text;
00049 
00050   search_term[0] = '\0';    /* no search term entered yet */
00051 
00052   /* Open input file for reading */
00053   if ((fd = open(file, O_RDONLY)) == -1) {
00054     endwin();
00055     fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
00056     exit(-1);
00057   }
00058   /* Get file size. Actually, 'file_size' is the real file size - 1,
00059      since it's only the last byte offset from the beginning */
00060   if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
00061     endwin();
00062     fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
00063     exit(-1);
00064   }
00065   /* Restore file pointer to beginning of file after getting file size */
00066   if (lseek(fd, 0, SEEK_SET) == -1) {
00067     endwin();
00068     fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
00069     exit(-1);
00070   }
00071   /* Allocate space for read buffer */
00072   if ((buf = malloc(BUF_SIZE+1)) == NULL) {
00073     endwin();
00074     fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
00075     exit(-1);
00076   }
00077   if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
00078     endwin();
00079     fprintf(stderr, "\nError reading file in dialog_textbox().\n");
00080     exit(-1);
00081   }
00082   buf[bytes_read] = '\0';    /* mark end of valid data */
00083   page = buf;    /* page is pointer to start of page to be displayed */
00084 
00085   /* center dialog box on screen */
00086   x = (COLS - width)/2;
00087   y = (LINES - height)/2;
00088 
00089 #ifdef HAVE_NCURSES
00090   if (use_shadow)
00091     draw_shadow(stdscr, y, x, height, width);
00092 #endif
00093   dialog = newwin(height, width, y, x);
00094   keypad(dialog, TRUE);
00095 
00096   /* Create window for text region, used for scrolling text */
00097 /*  text = newwin(height-4, width-2, y+1, x+1); */
00098   text = subwin(dialog, height-4, width-2, y+1, x+1);
00099   keypad(text, TRUE);
00100 
00101   draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
00102 
00103   wattrset(dialog, border_attr);
00104   wmove(dialog, height-3, 0);
00105   waddch(dialog, ACS_LTEE);
00106   for (i = 0; i < width-2; i++)
00107     waddch(dialog, ACS_HLINE);
00108   wattrset(dialog, dialog_attr);
00109   waddch(dialog, ACS_RTEE);
00110   wmove(dialog, height-2, 1);
00111   for (i = 0; i < width-2; i++)
00112     waddch(dialog, ' ');
00113 
00114   if (title != NULL) {
00115     wattrset(dialog, title_attr);
00116     wmove(dialog, 0, (width - strlen(title))/2 - 1);
00117     waddch(dialog, ' ');
00118     waddstr(dialog, title);
00119     waddch(dialog, ' ');
00120   }
00121   print_button(dialog, " EXIT ", height-2, width/2-4, TRUE);
00122   wnoutrefresh(dialog);
00123   getyx(dialog, cur_y, cur_x);    /* Save cursor position */
00124 
00125   /* Print first page of text */
00126   attr_clear(text, height-4, width-2, dialog_attr);
00127   print_page(text, height-4, width-2);
00128   print_position(dialog, height, width);
00129   wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00130   wrefresh(dialog);
00131 
00132   while ((key != ESC) && (key != '\n')) {
00133     key = wgetch(dialog);
00134     switch (key) {
00135       case 'E':    /* Exit */
00136       case 'e':
00137         delwin(dialog);
00138         free(buf);
00139         close(fd);
00140         return 0;
00141       case 'g':    /* First page */
00142       case KEY_HOME:
00143         if (!begin_reached) {
00144           begin_reached = 1;
00145           /* First page not in buffer? */
00146           if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
00147             endwin();
00148             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
00149             exit(-1);
00150           }
00151           if (fpos > bytes_read) {    /* Yes, we have to read it in */
00152             if (lseek(fd, 0, SEEK_SET) == -1) {
00153               endwin();
00154               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
00155               exit(-1);
00156             }
00157             if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
00158               endwin();
00159               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
00160               exit(-1);
00161             }
00162             buf[bytes_read] = '\0';
00163           }
00164           page = buf;
00165           print_page(text, height-4, width-2);
00166           print_position(dialog, height, width);
00167           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00168           wrefresh(dialog);
00169         }
00170         break;
00171       case 'G':    /* Last page */
00172 #ifdef HAVE_NCURSES
00173       case KEY_END:
00174 #endif
00175         end_reached = 1;
00176         /* Last page not in buffer? */
00177         if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
00178           endwin();
00179           fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
00180           exit(-1);
00181         }
00182         if (fpos < file_size) {    /* Yes, we have to read it in */
00183           if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
00184             endwin();
00185             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
00186             exit(-1);
00187           }
00188           if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
00189             endwin();
00190             fprintf(stderr, "\nError reading file in dialog_textbox().\n");
00191             exit(-1);
00192           }
00193           buf[bytes_read] = '\0';
00194         }
00195         page = buf + bytes_read;
00196         back_lines(height-4);
00197         print_page(text, height-4, width-2);
00198         print_position(dialog, height, width);
00199         wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00200         wrefresh(dialog);
00201         break;
00202       case 'K':    /* Previous line */
00203       case 'k':
00204       case KEY_UP:
00205         if (!begin_reached) {
00206           back_lines(page_length+1);
00207 #ifdef HAVE_NCURSES
00208           /* We don't call print_page() here but use scrolling to ensure
00209              faster screen update. However, 'end_reached' and 'page_length'
00210              should still be updated, and 'page' should point to start of
00211              next page. This is done by calling get_line() in the following
00212              'for' loop. */
00213           scrollok(text, TRUE);
00214           wscrl(text, -1);    /* Scroll text region down one line */
00215           scrollok(text, FALSE);
00216           page_length = 0;
00217           passed_end = 0;
00218           for (i = 0; i < height-4; i++) {
00219             if (!i) {
00220               print_line(text, 0, width-2);    /* print first line of page */
00221               wnoutrefresh(text);
00222             }
00223             else
00224               get_line();    /* Called to update 'end_reached' and 'page' */
00225             if (!passed_end)
00226               page_length++;
00227             if (end_reached && !passed_end)
00228               passed_end = 1;
00229           }
00230 #else
00231           print_page(text, height-4, width-2);
00232 #endif
00233           print_position(dialog, height, width);
00234           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00235           wrefresh(dialog);
00236         }
00237         break;
00238       case 'B':    /* Previous page */
00239       case 'b':
00240       case KEY_PPAGE:
00241         if (!begin_reached) {
00242           back_lines(page_length + height-4);
00243           print_page(text, height-4, width-2);
00244           print_position(dialog, height, width);
00245           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00246           wrefresh(dialog);
00247         }
00248         break;
00249       case 'J':    /* Next line */
00250       case 'j':
00251       case KEY_DOWN:
00252         if (!end_reached) {
00253           begin_reached = 0;
00254           scrollok(text, TRUE);
00255           scroll(text);    /* Scroll text region up one line */
00256           scrollok(text, FALSE);
00257           print_line(text, height-5, width-2);
00258 #ifndef HAVE_NCURSES
00259           wmove(text, height-5, 0);
00260           waddch(text, ' ');
00261           wmove(text, height-5, width-3);
00262           waddch(text, ' ');
00263 #endif
00264           wnoutrefresh(text);
00265           print_position(dialog, height, width);
00266           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00267           wrefresh(dialog);
00268         }
00269         break;
00270       case ' ':    /* Next page */
00271       case KEY_NPAGE:
00272         if (!end_reached) {
00273           begin_reached = 0;
00274           print_page(text, height-4, width-2);
00275           print_position(dialog, height, width);
00276           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00277           wrefresh(dialog);
00278         }
00279         break;
00280       case '0':    /* Beginning of line */
00281       case 'H':    /* Scroll left */
00282       case 'h':
00283       case KEY_LEFT:
00284         if (hscroll > 0) {
00285           if (key == '0')
00286             hscroll = 0;
00287           else
00288             hscroll--;
00289           /* Reprint current page to scroll horizontally */
00290           back_lines(page_length);
00291           print_page(text, height-4, width-2);
00292           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00293           wrefresh(dialog);
00294         }
00295         break;
00296       case 'L':    /* Scroll right */
00297       case 'l':
00298       case KEY_RIGHT:
00299         if (hscroll < MAX_LEN) {
00300           hscroll++;
00301           /* Reprint current page to scroll horizontally */
00302           back_lines(page_length);
00303           print_page(text, height-4, width-2);
00304           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00305           wrefresh(dialog);
00306         }
00307         break;
00308       case '/':    /* Forward search */
00309       case 'n':    /* Repeat forward search */
00310       case '?':    /* Backward search */
00311       case 'N':    /* Repeat backward search */
00312         /* set search direction */
00313         dir = (key == '/' || key == 'n') ? 1 : 0;
00314         if (dir ? !end_reached : !begin_reached) {
00315           if (key == 'n' || key == 'N') {
00316             if (search_term[0] == '\0') {    /* No search term yet */
00317               fprintf(stderr, "\a");    /* beep */
00318               break;
00319             }
00320          }
00321           else    /* Get search term from user */
00322             if (get_search_term(text, search_term, height-4, width-2) == -1) {
00323               /* ESC pressed in get_search_term(). Reprint page to clear box */
00324               wattrset(text, dialog_attr);
00325               back_lines(page_length);
00326               print_page(text, height-4, width-2);
00327               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00328               wrefresh(dialog);
00329               break;
00330             }
00331           /* Save variables for restoring in case search term can't be found */
00332           tempptr = page;
00333           temp = begin_reached;
00334           temp1 = end_reached;
00335           if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
00336             endwin();
00337             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
00338             exit(-1);
00339           }
00340           fpos -= bytes_read;
00341           /* update 'page' to point to next (previous) line before
00342              forward (backward) searching */
00343           back_lines(dir ? page_length-1 : page_length+1);
00344           found = NULL;
00345           if (dir)    /* Forward search */
00346             while((found = strstr(get_line(), search_term)) == NULL) {
00347               if (end_reached)
00348                 break;
00349            }
00350           else    /* Backward search */
00351             while((found = strstr(get_line(), search_term)) == NULL) {
00352               if (begin_reached)
00353                 break;
00354               back_lines(2);
00355             }
00356           if (found == NULL) {    /* not found */
00357             fprintf(stderr, "\a");    /* beep */
00358             /* Restore program state to that before searching */
00359             if (lseek(fd, fpos, SEEK_SET) == -1) {
00360               endwin();
00361               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
00362               exit(-1);
00363             }
00364             if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
00365               endwin();
00366               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
00367               exit(-1);
00368             }
00369             buf[bytes_read] = '\0';
00370             page = tempptr;
00371             begin_reached = temp;
00372             end_reached = temp1;
00373             /* move 'page' to point to start of current page in order to
00374                re-print current page. Note that 'page' always points to
00375                start of next page, so this is necessary */
00376             back_lines(page_length);
00377           }
00378           else    /* Search term found */
00379             back_lines(1);
00380           /* Reprint page */
00381           wattrset(text, dialog_attr);
00382           print_page(text, height-4, width-2);
00383           if (found != NULL)
00384             print_position(dialog, height, width);
00385           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
00386           wrefresh(dialog);
00387         }
00388         else    /* no need to find */
00389           fprintf(stderr, "\a");    /* beep */
00390         break;
00391       case ESC:
00392         break;
00393     }
00394   }
00395 
00396   delwin(dialog);
00397   free(buf);
00398   close(fd);
00399   return -1;    /* ESC pressed */
00400 }
00401 /* End of dialog_textbox() */
00402 
00403 
00404 /*
00405  * Go back 'n' lines in text file. Called by dialog_textbox().
00406  * 'page' will be updated to point to the desired line in 'buf'.
00407  */
00408 static void back_lines(int n)
00409 {
00410   int i, fpos;
00411 
00412   begin_reached = 0;
00413   /* We have to distinguish between end_reached and !end_reached since at end
00414      of file, the line is not ended by a '\n'. The code inside 'if' basically
00415      does a '--page' to move one character backward so as to skip '\n' of the
00416      previous line */
00417   if (!end_reached) {
00418     /* Either beginning of buffer or beginning of file reached? */
00419     if (page == buf) {
00420       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
00421         endwin();
00422         fprintf(stderr, "\nError moving file pointer in back_lines().\n");
00423         exit(-1);
00424       }
00425       if (fpos > bytes_read) {    /* Not beginning of file yet */
00426         /* We've reached beginning of buffer, but not beginning of file yet,
00427            so read previous part of file into buffer. Note that we only
00428            move backward for BUF_SIZE/2 bytes, but not BUF_SIZE bytes to
00429            avoid re-reading again in print_page() later */
00430         /* Really possible to move backward BUF_SIZE/2 bytes? */
00431         if (fpos < BUF_SIZE/2 + bytes_read) {
00432           /* No, move less then */
00433           if (lseek(fd, 0, SEEK_SET) == -1) {
00434             endwin();
00435             fprintf(stderr, "\nError moving file pointer in back_lines().\n");
00436             exit(-1);
00437           }
00438           page = buf + fpos - bytes_read;
00439         }
00440         else {    /* Move backward BUF_SIZE/2 bytes */
00441           if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
00442             endwin();
00443             fprintf(stderr, "\nError moving file pointer in back_lines().\n");
00444             exit(-1);
00445           }
00446           page = buf + BUF_SIZE/2;
00447         }
00448         if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
00449           endwin();
00450           fprintf(stderr, "\nError reading file in back_lines().\n");
00451           exit(-1);
00452         }
00453         buf[bytes_read] = '\0';
00454       }
00455       else {    /* Beginning of file reached */
00456         begin_reached = 1;
00457         return;
00458       }
00459     }
00460     if (*(--page) != '\n') {    /* '--page' here */
00461       /* Something's wrong... */
00462       endwin();
00463       fprintf(stderr, "\nInternal error in back_lines().\n");
00464       exit(-1);
00465     }
00466   }
00467 
00468   /* Go back 'n' lines */
00469   for (i = 0; i < n; i++)
00470     do {
00471       if (page == buf) {
00472         if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
00473           endwin();
00474           fprintf(stderr, "\nError moving file pointer in back_lines().\n");
00475           exit(-1);
00476         }
00477         if (fpos > bytes_read) {
00478           /* Really possible to move backward BUF_SIZE/2 bytes? */
00479           if (fpos < BUF_SIZE/2 + bytes_read) {
00480             /* No, move less then */
00481             if (lseek(fd, 0, SEEK_SET) == -1) {
00482               endwin();
00483               fprintf(stderr, "\nError moving file pointer in back_lines().\n");
00484               exit(-1);
00485             }
00486             page = buf + fpos - bytes_read;
00487           }
00488           else {    /* Move backward BUF_SIZE/2 bytes */
00489             if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
00490               endwin();
00491               fprintf(stderr, "\nError moving file pointer in back_lines().\n");
00492               exit(-1);
00493             }
00494             page = buf + BUF_SIZE/2;
00495           }
00496           if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
00497             endwin();
00498             fprintf(stderr, "\nError reading file in back_lines().\n");
00499             exit(-1);
00500           }
00501           buf[bytes_read] = '\0';
00502         }
00503         else {    /* Beginning of file reached */
00504           begin_reached = 1;
00505           return;
00506         }
00507       }
00508     } while (*(--page) != '\n');
00509   page++;
00510 }
00511 /* End of back_lines() */
00512 
00513 
00514 /*
00515  * Print a new page of text. Called by dialog_textbox().
00516  */
00517 static void print_page(WINDOW *win, int height, int width)
00518 {
00519   int i, passed_end = 0;
00520 
00521   page_length = 0;
00522   for (i = 0; i < height; i++) {
00523     print_line(win, i, width);
00524     if (!passed_end)
00525       page_length++;
00526     if (end_reached && !passed_end)
00527       passed_end = 1;
00528   }
00529   wnoutrefresh(win);
00530 }
00531 /* End of print_page() */
00532 
00533 
00534 /*
00535  * Print a new line of text. Called by dialog_textbox() and print_page().
00536  */
00537 static void print_line(WINDOW *win, int row, int width)
00538 {
00539   int i, y, x;
00540   char *line;
00541 
00542   line = get_line();
00543   line += MIN(strlen(line),hscroll);    /* Scroll horizontally */
00544   wmove(win, row, 0);    /* move cursor to correct line */
00545   waddch(win,' ');
00546 #ifdef HAVE_NCURSES
00547   waddnstr(win, line, MIN(strlen(line),width-2));
00548 #else
00549   line[MIN(strlen(line),width-2)] = '\0';
00550   waddstr(win, line);
00551 #endif
00552 
00553   getyx(win, y, x);
00554   /* Clear 'residue' of previous line */
00555   for (i = 0; i < width-x; i++)
00556     waddch(win, ' ');
00557 }
00558 /* End of print_line() */
00559 
00560 
00561 /*
00562  * Return current line of text. Called by dialog_textbox() and print_line().
00563  * 'page' should point to start of current line before calling, and will be
00564  * updated to point to start of next line.
00565  */
00566 static char *get_line(void)
00567 {
00568   int i = 0, fpos;
00569   static char line[MAX_LEN+1];
00570 
00571   end_reached = 0;
00572   while (*page != '\n') {
00573     if (*page == '\0') {    /* Either end of file or end of buffer reached */
00574       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
00575         endwin();
00576         fprintf(stderr, "\nError moving file pointer in get_line().\n");
00577         exit(-1);
00578       }
00579       if (fpos < file_size) {    /* Not end of file yet */
00580         /* We've reached end of buffer, but not end of file yet, so read next
00581            part of file into buffer */
00582         if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
00583           endwin();
00584           fprintf(stderr, "\nError reading file in get_line().\n");
00585           exit(-1);
00586         }
00587         buf[bytes_read] = '\0';
00588         page = buf;
00589       }
00590       else {
00591         if (!end_reached)
00592           end_reached = 1;
00593         break;
00594       }
00595     }
00596     else
00597       if (i < MAX_LEN)
00598         line[i++] = *(page++);
00599       else {
00600         if (i == MAX_LEN)  /* Truncate lines longer than MAX_LEN characters */
00601           line[i++] = '\0';
00602         page++;
00603       }
00604   }
00605   if (i <= MAX_LEN)
00606     line[i] = '\0';
00607   if (!end_reached)
00608     page++;    /* move pass '\n' */
00609 
00610   return line;
00611 }
00612 /* End of get_line() */
00613 
00614 
00615 /*
00616  * Display a dialog box and get the search term from user
00617  */
00618 static int get_search_term(WINDOW *win, char *search_term, int height, int width)
00619 {
00620   int i, x, y, input_x = 0, scroll = 0, key = 0,
00621       box_height = 3, box_width = 30;
00622 
00623   x = (width - box_width)/2;
00624   y = (height - box_height)/2;
00625 #ifdef HAVE_NCURSES
00626   if (use_shadow)
00627     draw_shadow(win, y, x, box_height, box_width);
00628 #endif
00629   draw_box(win, y, x, box_height, box_width, dialog_attr, searchbox_border_attr);
00630   wattrset(win, searchbox_title_attr);
00631   wmove(win, y, x+box_width/2-4);
00632   waddstr(win, " Search ");
00633 
00634   box_width -= 2;
00635   wmove(win, y+1, x+1);
00636   wrefresh(win);
00637   search_term[0] = '\0';
00638   wattrset(win, searchbox_attr);
00639   while (key != ESC) {
00640     key = wgetch(win);
00641     switch (key) {
00642       case '\n':
00643         if (search_term[0] != '\0')
00644           return 0;
00645         break;
00646       case KEY_BACKSPACE:
00647         if (input_x || scroll) {
00648           if (!input_x) {
00649             scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
00650             wmove(win, y+1, x+1);
00651             for (i = 0; i < box_width; i++)
00652               waddch(win, search_term[scroll+input_x+i] ?
00653                             search_term[scroll+input_x+i] : ' ');
00654             input_x = strlen(search_term) - scroll;
00655           }
00656           else
00657             input_x--;
00658           search_term[scroll+input_x] = '\0';
00659           wmove(win, y+1, input_x + x+1);
00660           waddch(win, ' ');
00661           wmove(win, y+1, input_x + x+1);
00662           wrefresh(win);
00663         }
00664         break;
00665       case ESC:
00666         break;
00667       default:
00668         if (isprint(key))
00669           if (scroll+input_x < MAX_LEN) {
00670             search_term[scroll+input_x] = key;
00671             search_term[scroll+input_x+1] = '\0';
00672             if (input_x == box_width-1) {
00673               scroll++;
00674               wmove(win, y+1, x+1);
00675               for (i = 0; i < box_width-1; i++)
00676                 waddch(win, search_term[scroll+i]);
00677             }
00678             else {
00679               wmove(win, y+1, input_x++ + x+1);
00680               waddch(win, key);
00681             }
00682             wrefresh(win);
00683           }
00684     }
00685   }
00686 
00687   return -1;    /* ESC pressed */
00688 }
00689 /* End of get_search_term() */
00690 
00691 
00692 /*
00693  * Print current position
00694  */
00695 static void print_position(WINDOW *win, int height, int width)
00696 {
00697   int fpos, percent;
00698 
00699   if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
00700     endwin();
00701     fprintf(stderr, "\nError moving file pointer in print_position().\n");
00702     exit(-1);
00703   }
00704   wattrset(win, position_indicator_attr);
00705   percent = !file_size ? 100 : ((fpos-bytes_read+page-buf)*100)/file_size;
00706   wmove(win, height-3, width-9);
00707   wprintw(win, "(%3d%%)", percent);
00708 }
00709 /* End of print_position() */