home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / a / hdsetup / dialog-0.4-1 / dialog-0 / dialog-0.4-slackware / src / textbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-09  |  22.2 KB  |  709 lines

  1. /*
  2.  *  textbox.c -- implements the text box
  3.  *
  4.  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  5.  *
  6.  *  This program is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU General Public License
  8.  *  as published by the Free Software Foundation; either version 2
  9.  *  of the License, or (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21.  
  22. #include "dialog.h"
  23.  
  24.  
  25. static void back_lines(int n);
  26. static void print_page(WINDOW *win, int height, int width);
  27. static void print_line(WINDOW *win, int row, int width);
  28. static unsigned char *get_line(void);
  29. static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width);
  30. static void print_position(WINDOW *win, int height, int width);
  31.  
  32.  
  33. static int hscroll = 0, fd, file_size, bytes_read, begin_reached = 1,
  34.            end_reached = 0, page_length;
  35. static unsigned char *buf, *page;
  36.  
  37.  
  38. /*
  39.  * Display text from a file in a dialog box.
  40.  */
  41. int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width)
  42. {
  43.   int i, x, y, cur_x, cur_y, fpos, key = 0, dir, temp, temp1;
  44. #ifdef HAVE_NCURSES
  45.   int passed_end;
  46. #endif
  47.   unsigned char search_term[MAX_LEN+1], *tempptr, *found;
  48.   WINDOW *dialog, *text;
  49.  
  50.   search_term[0] = '\0';    /* no search term entered yet */
  51.  
  52.   /* Open input file for reading */
  53.   if ((fd = open(file, O_RDONLY)) == -1) {
  54.     endwin();
  55.     fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
  56.     exit(-1);
  57.   }
  58.   /* Get file size. Actually, 'file_size' is the real file size - 1,
  59.      since it's only the last byte offset from the beginning */
  60.   if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
  61.     endwin();
  62.     fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
  63.     exit(-1);
  64.   }
  65.   /* Restore file pointer to beginning of file after getting file size */
  66.   if (lseek(fd, 0, SEEK_SET) == -1) {
  67.     endwin();
  68.     fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  69.     exit(-1);
  70.   }
  71.   /* Allocate space for read buffer */
  72.   if ((buf = malloc(BUF_SIZE+1)) == NULL) {
  73.     endwin();
  74.     fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
  75.     exit(-1);
  76.   }
  77.   if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  78.     endwin();
  79.     fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  80.     exit(-1);
  81.   }
  82.   buf[bytes_read] = '\0';    /* mark end of valid data */
  83.   page = buf;    /* page is pointer to start of page to be displayed */
  84.  
  85.   /* center dialog box on screen */
  86.   x = (COLS - width)/2;
  87.   y = (LINES - height)/2;
  88.  
  89. #ifdef HAVE_NCURSES
  90.   if (use_shadow)
  91.     draw_shadow(stdscr, y, x, height, width);
  92. #endif
  93.   dialog = newwin(height, width, y, x);
  94.   keypad(dialog, TRUE);
  95.  
  96.   /* Create window for text region, used for scrolling text */
  97. /*  text = newwin(height-4, width-2, y+1, x+1); */
  98.   text = subwin(dialog, height-4, width-2, y+1, x+1);
  99.   keypad(text, TRUE);
  100.  
  101.   draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
  102.  
  103.   wattrset(dialog, border_attr);
  104.   wmove(dialog, height-3, 0);
  105.   waddch(dialog, ACS_LTEE);
  106.   for (i = 0; i < width-2; i++)
  107.     waddch(dialog, ACS_HLINE);
  108.   waddch(dialog, ACS_RTEE);
  109.   wmove(dialog, height-2, 1);
  110.   for (i = 0; i < width-2; i++)
  111.     waddch(dialog, ' ');
  112.  
  113.   if (title != NULL) {
  114.     wattrset(dialog, title_attr);
  115.     wmove(dialog, 0, (width - strlen(title))/2 - 1);
  116.     waddch(dialog, ' ');
  117.     waddstr(dialog, title);
  118.     waddch(dialog, ' ');
  119.   }
  120.   print_button(dialog, " EXIT ", height-2, width/2-4, TRUE);
  121.   wnoutrefresh(dialog);
  122.   getyx(dialog, cur_y, cur_x);    /* Save cursor position */
  123.  
  124.   /* Print first page of text */
  125.   attr_clear(text, height-4, width-2, dialog_attr);
  126.   print_page(text, height-4, width-2);
  127.   print_position(dialog, height, width);
  128.   wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  129.   wrefresh(dialog);
  130.  
  131.   while ((key != ESC) && (key != '\n')) {
  132.     key = wgetch(dialog);
  133.     switch (key) {
  134.       case 'E':    /* Exit */
  135.       case 'e':
  136.         delwin(dialog);
  137.         free(buf);
  138.         close(fd);
  139.         return 0;
  140.       case 'g':    /* First page */
  141.       case KEY_HOME:
  142.         if (!begin_reached) {
  143.           begin_reached = 1;
  144.           /* First page not in buffer? */
  145.           if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  146.             endwin();
  147.             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  148.             exit(-1);
  149.           }
  150.           if (fpos > bytes_read) {    /* Yes, we have to read it in */
  151.             if (lseek(fd, 0, SEEK_SET) == -1) {
  152.               endwin();
  153.               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  154.               exit(-1);
  155.             }
  156.             if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  157.               endwin();
  158.               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  159.               exit(-1);
  160.             }
  161.             buf[bytes_read] = '\0';
  162.           }
  163.           page = buf;
  164.           print_page(text, height-4, width-2);
  165.           print_position(dialog, height, width);
  166.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  167.           wrefresh(dialog);
  168.         }
  169.         break;
  170.       case 'G':    /* Last page */
  171. #ifdef HAVE_NCURSES
  172.       case KEY_END:
  173. #endif
  174.         end_reached = 1;
  175.         /* Last page not in buffer? */
  176.         if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  177.           endwin();
  178.           fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  179.           exit(-1);
  180.         }
  181.         if (fpos < file_size) {    /* Yes, we have to read it in */
  182.           if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
  183.             endwin();
  184.             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  185.             exit(-1);
  186.           }
  187.           if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  188.             endwin();
  189.             fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  190.             exit(-1);
  191.           }
  192.           buf[bytes_read] = '\0';
  193.         }
  194.         page = buf + bytes_read;
  195.         back_lines(height-4);
  196.         print_page(text, height-4, width-2);
  197.         print_position(dialog, height, width);
  198.         wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  199.         wrefresh(dialog);
  200.         break;
  201.       case 'K':    /* Previous line */
  202.       case 'k':
  203.       case KEY_UP:
  204.         if (!begin_reached) {
  205.           back_lines(page_length+1);
  206. #ifdef HAVE_NCURSES
  207.           /* We don't call print_page() here but use scrolling to ensure
  208.              faster screen update. However, 'end_reached' and 'page_length'
  209.              should still be updated, and 'page' should point to start of
  210.              next page. This is done by calling get_line() in the following
  211.              'for' loop. */
  212.           scrollok(text, TRUE);
  213.           wscrl(text, -1);    /* Scroll text region down one line */
  214.           scrollok(text, FALSE);
  215.           page_length = 0;
  216.           passed_end = 0;
  217.           for (i = 0; i < height-4; i++) {
  218.             if (!i) {
  219.               print_line(text, 0, width-2);    /* print first line of page */
  220.               wnoutrefresh(text);
  221.             }
  222.             else
  223.               get_line();    /* Called to update 'end_reached' and 'page' */
  224.             if (!passed_end)
  225.               page_length++;
  226.             if (end_reached && !passed_end)
  227.               passed_end = 1;
  228.           }
  229. #else
  230.           print_page(text, height-4, width-2);
  231. #endif
  232.           print_position(dialog, height, width);
  233.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  234.           wrefresh(dialog);
  235.         }
  236.         break;
  237.       case 'B':    /* Previous page */
  238.       case 'b':
  239.       case KEY_PPAGE:
  240.         if (!begin_reached) {
  241.           back_lines(page_length + height-4);
  242.           print_page(text, height-4, width-2);
  243.           print_position(dialog, height, width);
  244.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  245.           wrefresh(dialog);
  246.         }
  247.         break;
  248.       case 'J':    /* Next line */
  249.       case 'j':
  250.       case KEY_DOWN:
  251.         if (!end_reached) {
  252.           begin_reached = 0;
  253.           scrollok(text, TRUE);
  254.           scroll(text);    /* Scroll text region up one line */
  255.           scrollok(text, FALSE);
  256.           print_line(text, height-5, width-2);
  257. #ifndef HAVE_NCURSES
  258.           wmove(text, height-5, 0);
  259.           waddch(text, ' ');
  260.           wmove(text, height-5, width-3);
  261.           waddch(text, ' ');
  262. #endif
  263.           wnoutrefresh(text);
  264.           print_position(dialog, height, width);
  265.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  266.           wrefresh(dialog);
  267.         }
  268.         break;
  269.       case ' ':    /* Next page */
  270.       case KEY_NPAGE:
  271.         if (!end_reached) {
  272.           begin_reached = 0;
  273.           print_page(text, height-4, width-2);
  274.           print_position(dialog, height, width);
  275.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  276.           wrefresh(dialog);
  277.         }
  278.         break;
  279.       case '0':    /* Beginning of line */
  280.       case 'H':    /* Scroll left */
  281.       case 'h':
  282.       case KEY_LEFT:
  283.         if (hscroll > 0) {
  284.           if (key == '0')
  285.             hscroll = 0;
  286.           else
  287.             hscroll--;
  288.           /* Reprint current page to scroll horizontally */
  289.           back_lines(page_length);
  290.           print_page(text, height-4, width-2);
  291.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  292.           wrefresh(dialog);
  293.         }
  294.         break;
  295.       case 'L':    /* Scroll right */
  296.       case 'l':
  297.       case KEY_RIGHT:
  298.         if (hscroll < MAX_LEN) {
  299.           hscroll++;
  300.           /* Reprint current page to scroll horizontally */
  301.           back_lines(page_length);
  302.           print_page(text, height-4, width-2);
  303.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  304.           wrefresh(dialog);
  305.         }
  306.         break;
  307.       case '/':    /* Forward search */
  308.       case 'n':    /* Repeat forward search */
  309.       case '?':    /* Backward search */
  310.       case 'N':    /* Repeat backward search */
  311.         /* set search direction */
  312.         dir = (key == '/' || key == 'n') ? 1 : 0;
  313.         if (dir ? !end_reached : !begin_reached) {
  314.           if (key == 'n' || key == 'N') {
  315.             if (search_term[0] == '\0') {    /* No search term yet */
  316.               fprintf(stderr, "\a");    /* beep */
  317.               break;
  318.             }
  319.       }
  320.           else    /* Get search term from user */
  321.             if (get_search_term(text, search_term, height-4, width-2) == -1) {
  322.               /* ESC pressed in get_search_term(). Reprint page to clear box */
  323.               wattrset(text, dialog_attr);
  324.               back_lines(page_length);
  325.               print_page(text, height-4, width-2);
  326.               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  327.               wrefresh(dialog);
  328.               break;
  329.             }
  330.           /* Save variables for restoring in case search term can't be found */
  331.           tempptr = page;
  332.           temp = begin_reached;
  333.           temp1 = end_reached;
  334.           if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  335.             endwin();
  336.             fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  337.             exit(-1);
  338.           }
  339.           fpos -= bytes_read;
  340.           /* update 'page' to point to next (previous) line before
  341.              forward (backward) searching */
  342.           back_lines(dir ? page_length-1 : page_length+1);
  343.           found = NULL;
  344.           if (dir)    /* Forward search */
  345.             while((found = strstr(get_line(), search_term)) == NULL) {
  346.               if (end_reached)
  347.                 break;
  348.         }
  349.           else    /* Backward search */
  350.             while((found = strstr(get_line(), search_term)) == NULL) {
  351.               if (begin_reached)
  352.                 break;
  353.               back_lines(2);
  354.             }
  355.           if (found == NULL) {    /* not found */
  356.             fprintf(stderr, "\a");    /* beep */
  357.             /* Restore program state to that before searching */
  358.             if (lseek(fd, fpos, SEEK_SET) == -1) {
  359.               endwin();
  360.               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
  361.               exit(-1);
  362.             }
  363.             if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  364.               endwin();
  365.               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
  366.               exit(-1);
  367.             }
  368.             buf[bytes_read] = '\0';
  369.             page = tempptr;
  370.             begin_reached = temp;
  371.             end_reached = temp1;
  372.             /* move 'page' to point to start of current page in order to
  373.                re-print current page. Note that 'page' always points to
  374.                start of next page, so this is necessary */
  375.             back_lines(page_length);
  376.           }
  377.           else    /* Search term found */
  378.             back_lines(1);
  379.           /* Reprint page */
  380.           wattrset(text, dialog_attr);
  381.           print_page(text, height-4, width-2);
  382.           if (found != NULL)
  383.             print_position(dialog, height, width);
  384.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  385.           wrefresh(dialog);
  386.         }
  387.         else    /* no need to find */
  388.           fprintf(stderr, "\a");    /* beep */
  389.         break;
  390.       case ESC:
  391.         break;
  392.     }
  393.   }
  394.  
  395.   delwin(dialog);
  396.   free(buf);
  397.   close(fd);
  398.   return -1;    /* ESC pressed */
  399. }
  400. /* End of dialog_textbox() */
  401.  
  402.  
  403. /*
  404.  * Go back 'n' lines in text file. Called by dialog_textbox().
  405.  * 'page' will be updated to point to the desired line in 'buf'.
  406.  */
  407. static void back_lines(int n)
  408. {
  409.   int i, fpos;
  410.  
  411.   begin_reached = 0;
  412.   /* We have to distinguish between end_reached and !end_reached since at end
  413.      of file, the line is not ended by a '\n'. The code inside 'if' basically
  414.      does a '--page' to move one character backward so as to skip '\n' of the
  415.      previous line */
  416.   if (!end_reached) {
  417.     /* Either beginning of buffer or beginning of file reached? */
  418.     if (page == buf) {
  419.       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  420.         endwin();
  421.         fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  422.         exit(-1);
  423.       }
  424.       if (fpos > bytes_read) {    /* Not beginning of file yet */
  425.         /* We've reached beginning of buffer, but not beginning of file yet,
  426.            so read previous part of file into buffer. Note that we only
  427.            move backward for BUF_SIZE/2 bytes, but not BUF_SIZE bytes to
  428.            avoid re-reading again in print_page() later */
  429.         /* Really possible to move backward BUF_SIZE/2 bytes? */
  430.         if (fpos < BUF_SIZE/2 + bytes_read) {
  431.           /* No, move less then */
  432.           if (lseek(fd, 0, SEEK_SET) == -1) {
  433.             endwin();
  434.             fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  435.             exit(-1);
  436.           }
  437.           page = buf + fpos - bytes_read;
  438.         }
  439.         else {    /* Move backward BUF_SIZE/2 bytes */
  440.           if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
  441.             endwin();
  442.             fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  443.             exit(-1);
  444.           }
  445.           page = buf + BUF_SIZE/2;
  446.         }
  447.         if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  448.           endwin();
  449.           fprintf(stderr, "\nError reading file in back_lines().\n");
  450.           exit(-1);
  451.         }
  452.         buf[bytes_read] = '\0';
  453.       }
  454.       else {    /* Beginning of file reached */
  455.         begin_reached = 1;
  456.         return;
  457.       }
  458.     }
  459.     if (*(--page) != '\n') {    /* '--page' here */
  460.       /* Something's wrong... */
  461.       endwin();
  462.       fprintf(stderr, "\nInternal error in back_lines().\n");
  463.       exit(-1);
  464.     }
  465.   }
  466.  
  467.   /* Go back 'n' lines */
  468.   for (i = 0; i < n; i++)
  469.     do {
  470.       if (page == buf) {
  471.         if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  472.           endwin();
  473.           fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  474.           exit(-1);
  475.         }
  476.         if (fpos > bytes_read) {
  477.           /* Really possible to move backward BUF_SIZE/2 bytes? */
  478.           if (fpos < BUF_SIZE/2 + bytes_read) {
  479.             /* No, move less then */
  480.             if (lseek(fd, 0, SEEK_SET) == -1) {
  481.               endwin();
  482.               fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  483.               exit(-1);
  484.             }
  485.             page = buf + fpos - bytes_read;
  486.           }
  487.           else {    /* Move backward BUF_SIZE/2 bytes */
  488.             if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
  489.               endwin();
  490.               fprintf(stderr, "\nError moving file pointer in back_lines().\n");
  491.               exit(-1);
  492.             }
  493.             page = buf + BUF_SIZE/2;
  494.           }
  495.           if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  496.             endwin();
  497.             fprintf(stderr, "\nError reading file in back_lines().\n");
  498.             exit(-1);
  499.           }
  500.           buf[bytes_read] = '\0';
  501.         }
  502.         else {    /* Beginning of file reached */
  503.           begin_reached = 1;
  504.           return;
  505.         }
  506.       }
  507.     } while (*(--page) != '\n');
  508.   page++;
  509. }
  510. /* End of back_lines() */
  511.  
  512.  
  513. /*
  514.  * Print a new page of text. Called by dialog_textbox().
  515.  */
  516. static void print_page(WINDOW *win, int height, int width)
  517. {
  518.   int i, passed_end = 0;
  519.  
  520.   page_length = 0;
  521.   for (i = 0; i < height; i++) {
  522.     print_line(win, i, width);
  523.     if (!passed_end)
  524.       page_length++;
  525.     if (end_reached && !passed_end)
  526.       passed_end = 1;
  527.   }
  528.   wnoutrefresh(win);
  529. }
  530. /* End of print_page() */
  531.  
  532.  
  533. /*
  534.  * Print a new line of text. Called by dialog_textbox() and print_page().
  535.  */
  536. static void print_line(WINDOW *win, int row, int width)
  537. {
  538.   int i, y, x;
  539.   unsigned char *line;
  540.  
  541.   line = get_line();
  542.   line += MIN(strlen(line),hscroll);    /* Scroll horizontally */
  543.   wmove(win, row, 0);    /* move cursor to correct line */
  544.   waddch(win,' ');
  545. #ifdef HAVE_NCURSES
  546.   waddnstr(win, line, MIN(strlen(line),width-2));
  547. #else
  548.   line[MIN(strlen(line),width-2)] = '\0';
  549.   waddstr(win, line);
  550. #endif
  551.  
  552.   getyx(win, y, x);
  553.   /* Clear 'residue' of previous line */
  554.   for (i = 0; i < width-x; i++)
  555.     waddch(win, ' ');
  556. }
  557. /* End of print_line() */
  558.  
  559.  
  560. /*
  561.  * Return current line of text. Called by dialog_textbox() and print_line().
  562.  * 'page' should point to start of current line before calling, and will be
  563.  * updated to point to start of next line.
  564.  */
  565. static unsigned char *get_line(void)
  566. {
  567.   int i = 0, fpos;
  568.   static unsigned char line[MAX_LEN+1];
  569.  
  570.   end_reached = 0;
  571.   while (*page != '\n') {
  572.     if (*page == '\0') {    /* Either end of file or end of buffer reached */
  573.       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  574.         endwin();
  575.         fprintf(stderr, "\nError moving file pointer in get_line().\n");
  576.         exit(-1);
  577.       }
  578.       if (fpos < file_size) {    /* Not end of file yet */
  579.         /* We've reached end of buffer, but not end of file yet, so read next
  580.            part of file into buffer */
  581.         if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
  582.           endwin();
  583.           fprintf(stderr, "\nError reading file in get_line().\n");
  584.           exit(-1);
  585.         }
  586.         buf[bytes_read] = '\0';
  587.         page = buf;
  588.       }
  589.       else {
  590.         if (!end_reached)
  591.           end_reached = 1;
  592.         break;
  593.       }
  594.     }
  595.     else
  596.       if (i < MAX_LEN)
  597.         line[i++] = *(page++);
  598.       else {
  599.         if (i == MAX_LEN)  /* Truncate lines longer than MAX_LEN characters */
  600.           line[i++] = '\0';
  601.         page++;
  602.       }
  603.   }
  604.   if (i <= MAX_LEN)
  605.     line[i] = '\0';
  606.   if (!end_reached)
  607.     page++;    /* move pass '\n' */
  608.  
  609.   return line;
  610. }
  611. /* End of get_line() */
  612.  
  613.  
  614. /*
  615.  * Display a dialog box and get the search term from user
  616.  */
  617. static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width)
  618. {
  619.   int i, x, y, input_x = 0, scroll = 0, key = 0,
  620.       box_height = 3, box_width = 30;
  621.  
  622.   x = (width - box_width)/2;
  623.   y = (height - box_height)/2;
  624. #ifdef HAVE_NCURSES
  625.   if (use_shadow)
  626.     draw_shadow(win, y, x, box_height, box_width);
  627. #endif
  628.   draw_box(win, y, x, box_height, box_width, dialog_attr, searchbox_border_attr);
  629.   wattrset(win, searchbox_title_attr);
  630.   wmove(win, y, x+box_width/2-4);
  631.   waddstr(win, " Search ");
  632.  
  633.   box_width -= 2;
  634.   wmove(win, y+1, x+1);
  635.   wrefresh(win);
  636.   search_term[0] = '\0';
  637.   wattrset(win, searchbox_attr);
  638.   while (key != ESC) {
  639.     key = wgetch(win);
  640.     switch (key) {
  641.       case '\n':
  642.         if (search_term[0] != '\0')
  643.           return 0;
  644.         break;
  645.       case KEY_BACKSPACE:
  646.         if (input_x || scroll) {
  647.           if (!input_x) {
  648.             scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
  649.             wmove(win, y+1, x+1);
  650.             for (i = 0; i < box_width; i++)
  651.               waddch(win, search_term[scroll+input_x+i] ?
  652.                             search_term[scroll+input_x+i] : ' ');
  653.             input_x = strlen(search_term) - scroll;
  654.           }
  655.           else
  656.             input_x--;
  657.           search_term[scroll+input_x] = '\0';
  658.           wmove(win, y+1, input_x + x+1);
  659.           waddch(win, ' ');
  660.           wmove(win, y+1, input_x + x+1);
  661.           wrefresh(win);
  662.         }
  663.         break;
  664.       case ESC:
  665.         break;
  666.       default:
  667.         if (isprint(key))
  668.           if (scroll+input_x < MAX_LEN) {
  669.             search_term[scroll+input_x] = key;
  670.             search_term[scroll+input_x+1] = '\0';
  671.             if (input_x == box_width-1) {
  672.               scroll++;
  673.               wmove(win, y+1, x+1);
  674.               for (i = 0; i < box_width-1; i++)
  675.                 waddch(win, search_term[scroll+i]);
  676.             }
  677.             else {
  678.               wmove(win, y+1, input_x++ + x+1);
  679.               waddch(win, key);
  680.             }
  681.             wrefresh(win);
  682.           }
  683.     }
  684.   }
  685.  
  686.   return -1;    /* ESC pressed */
  687. }
  688. /* End of get_search_term() */
  689.  
  690.  
  691. /*
  692.  * Print current position
  693.  */
  694. static void print_position(WINDOW *win, int height, int width)
  695. {
  696.   int fpos, percent;
  697.  
  698.   if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
  699.     endwin();
  700.     fprintf(stderr, "\nError moving file pointer in print_position().\n");
  701.     exit(-1);
  702.   }
  703.   wattrset(win, position_indicator_attr);
  704.   percent = !file_size ? 100 : ((fpos-bytes_read+page-buf)*100)/file_size;
  705.   wmove(win, height-3, width-9);
  706.   wprintw(win, "(%3d%%)", percent);
  707. }
  708. /* End of print_position() */
  709.