home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / GNU / LES177AS.ZIP / FORWBACK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-04  |  8.1 KB  |  388 lines

  1. /*
  2.  * Primitives for displaying the file on the screen,
  3.  * scrolling either forward or backward.
  4.  */
  5.  
  6. #include "less.h"
  7. #include "position.h"
  8.  
  9. public int hit_eof;    /* Keeps track of how many times we hit end of file */
  10. public int screen_trashed;
  11. public int squished;
  12.  
  13. extern int sigs;
  14. extern int top_scroll;
  15. extern int quiet;
  16. extern int sc_width, sc_height;
  17. extern int quit_at_eof;
  18. extern int plusoption;
  19. extern int forw_scroll;
  20. extern int back_scroll;
  21. extern int need_clr;
  22. extern int ignore_eoi;
  23. #if TAGS
  24. extern int tagoption;
  25. #endif
  26.  
  27. /*
  28.  * Sound the bell to indicate user is trying to move past end of file.
  29.  */
  30.     static void
  31. eof_bell()
  32. {
  33.     if (quiet == NOT_QUIET)
  34.         bell();
  35.     else
  36.         vbell();
  37. }
  38.  
  39. /*
  40.  * Check to see if the end of file is currently "displayed".
  41.  */
  42.     static void
  43. eof_check()
  44. {
  45.     POSITION pos;
  46.  
  47.     if (ignore_eoi)
  48.         return;
  49.     if (sigs)
  50.         return;
  51.     /*
  52.      * If the bottom line is empty, we are at EOF.
  53.      * If the bottom line ends at the file length,
  54.      * we must be just at EOF.
  55.      */
  56.     pos = position(BOTTOM_PLUS_ONE);
  57.     if (pos == NULL_POSITION || pos == ch_length())
  58.         hit_eof++;
  59. }
  60.  
  61. /*
  62.  * If the screen is "squished", repaint it.
  63.  * "Squished" means the first displayed line is not at the top
  64.  * of the screen; this can happen when we display a short file
  65.  * for the first time.
  66.  */
  67.     static void
  68. squish_check()
  69. {
  70.     if (!squished)
  71.         return;
  72.     squished = 0;
  73.     repaint();
  74. }
  75.  
  76. /*
  77.  * Display n lines, scrolling forward, 
  78.  * starting at position pos in the input file.
  79.  * "force" means display the n lines even if we hit end of file.
  80.  * "only_last" means display only the last screenful if n > screen size.
  81.  * "nblank" is the number of blank lines to draw before the first
  82.  *   real line.  If nblank > 0, the pos must be NULL_POSITION.
  83.  *   The first real line after the blanks will start at ch_zero().
  84.  */
  85.     public void
  86. forw(n, pos, force, only_last, nblank)
  87.     register int n;
  88.     POSITION pos;
  89.     int force;
  90.     int only_last;
  91.     int nblank;
  92. {
  93.     int eof = 0;
  94.     int nlines = 0;
  95.     int do_repaint;
  96.     static int first_time = 1;
  97.  
  98.     squish_check();
  99.  
  100.     /*
  101.      * do_repaint tells us not to display anything till the end, 
  102.      * then just repaint the entire screen.
  103.      * We repaint if we are supposed to display only the last 
  104.      * screenful and the request is for more than a screenful.
  105.      * Also if the request exceeds the forward scroll limit
  106.      * (but not if the request is for exactly a screenful, since
  107.      * repainting itself involves scrolling forward a screenful).
  108.      */
  109.     do_repaint = (only_last && n > sc_height-1) || 
  110.         (n > get_forw_scroll() && n != sc_height-1);
  111.  
  112.     if (!do_repaint)
  113.     {
  114.         if (top_scroll && n >= sc_height - 1 && pos != ch_length())
  115.         {
  116.             /*
  117.              * Start a new screen.
  118.              * {{ This is not really desirable if we happen
  119.              *    to hit eof in the middle of this screen,
  120.              *    but we don't yet know if that will happen. }}
  121.              */
  122.             if (top_scroll == 2 || first_time)
  123.                 clear();
  124.             home();
  125.             force = 1;
  126.         } else
  127.         {
  128.             lower_left();
  129.             clear_eol();
  130.         }
  131.  
  132.         if (pos != position(BOTTOM_PLUS_ONE) || empty_screen())
  133.         {
  134.             /*
  135.              * This is not contiguous with what is
  136.              * currently displayed.  Clear the screen image 
  137.              * (position table) and start a new screen.
  138.              */
  139.             pos_clear();
  140.             add_forw_pos(pos);
  141.             force = 1;
  142.             if (top_scroll)
  143.             {
  144.                 if (top_scroll == 2)
  145.                     clear();
  146.                 home();
  147.             } else if (!first_time)
  148.             {
  149.                 if (onscreen(pos) < 0)
  150.                     putstr("...skipping...\n");
  151.             }
  152.         }
  153.     }
  154.  
  155.     while (--n >= 0)
  156.     {
  157.         /*
  158.          * Read the next line of input.
  159.          */
  160.         if (nblank > 0)
  161.         {
  162.             /*
  163.              * Still drawing blanks; don't get a line 
  164.              * from the file yet.
  165.              * If this is the last blank line, get ready to
  166.              * read a line starting at ch_zero() next time.
  167.              */
  168.             if (--nblank == 0)
  169.                 pos = ch_zero();
  170.         } else
  171.         {
  172.             /* 
  173.              * Get the next line from the file.
  174.              */
  175.             pos = forw_line(pos);
  176.             if (pos == NULL_POSITION)
  177.             {
  178.                 /*
  179.                  * End of file: stop here unless the top line 
  180.                  * is still empty, or "force" is true.
  181.                  */
  182.                 eof = 1;
  183.                 if (!force && position(TOP) != NULL_POSITION)
  184.                     break;
  185.             }
  186.         }
  187.         /*
  188.          * Add the position of the next line to the position table.
  189.          * Display the current line on the screen.
  190.          */
  191.         add_forw_pos(pos);
  192.         nlines++;
  193.         if (do_repaint)
  194.             continue;
  195.         /*
  196.          * If this is the first screen displayed and
  197.          * we hit an early EOF (i.e. before the requested
  198.          * number of lines), we "squish" the display down
  199.          * at the bottom of the screen.
  200.          * But don't do this if a + option or a -t option
  201.          * was given.  These options can cause us to
  202.          * start the display after the beginning of the file,
  203.          * and it is not appropriate to squish in that case.
  204.          */
  205.         if (first_time && pos == NULL_POSITION && !top_scroll && 
  206. #if TAGS
  207.             !tagoption &&
  208. #endif
  209.             !plusoption)
  210.         {
  211.             squished = 1;
  212.             continue;
  213.         }
  214.         if (top_scroll == 1)
  215.             clear_eol();
  216.         put_line();
  217.     }
  218.  
  219.     if (ignore_eoi)
  220.         hit_eof = 0;
  221.     else if (eof && !sigs)
  222.         hit_eof++;
  223.     else
  224.         eof_check();
  225.     if (nlines == 0)
  226.         eof_bell();
  227.     else if (do_repaint)
  228.         repaint();
  229.     first_time = 0;
  230.     (void) currline(BOTTOM);
  231. }
  232.  
  233. /*
  234.  * Display n lines, scrolling backward.
  235.  */
  236.     public void
  237. back(n, pos, force, only_last)
  238.     register int n;
  239.     POSITION pos;
  240.     int force;
  241.     int only_last;
  242. {
  243.     int nlines = 0;
  244.     int do_repaint;
  245.  
  246.     squish_check();
  247.     do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1));
  248.     hit_eof = 0;
  249.     while (--n >= 0)
  250.     {
  251.         /*
  252.          * Get the previous line of input.
  253.          */
  254.         pos = back_line(pos);
  255.         if (pos == NULL_POSITION)
  256.         {
  257.             /*
  258.              * Beginning of file: stop here unless "force" is true.
  259.              */
  260.             if (!force)
  261.                 break;
  262.         }
  263.         /*
  264.          * Add the position of the previous line to the position table.
  265.          * Display the line on the screen.
  266.          */
  267.         add_back_pos(pos);
  268.         nlines++;
  269.         if (!do_repaint)
  270.         {
  271.             home();
  272.             add_line();
  273.             put_line();
  274.         }
  275.     }
  276.  
  277.     eof_check();
  278.     if (nlines == 0)
  279.         eof_bell();
  280.     else if (do_repaint)
  281.         repaint();
  282.     (void) currline(BOTTOM);
  283. }
  284.  
  285. /*
  286.  * Display n more lines, forward.
  287.  * Start just after the line currently displayed at the bottom of the screen.
  288.  */
  289.     public void
  290. forward(n, force, only_last)
  291.     int n;
  292.     int force;
  293.     int only_last;
  294. {
  295.     POSITION pos;
  296.  
  297.     if (quit_at_eof && hit_eof)
  298.     {
  299.         /*
  300.          * If the -e flag is set and we're trying to go
  301.          * forward from end-of-file, go on to the next file.
  302.          */
  303.         if (edit_next(1))
  304.             quit(0);
  305.         return;
  306.     }
  307.  
  308.     pos = position(BOTTOM_PLUS_ONE);
  309.     if (pos == NULL_POSITION && (!force || empty_lines(2, sc_height-1)))
  310.     {
  311.         if (ignore_eoi)
  312.         {
  313.             /*
  314.              * ignore_eoi is to support A_F_FOREVER.
  315.              * Back up until there is a line at the bottom
  316.              * of the screen.
  317.              */
  318.             if (empty_screen())
  319.                 pos = ch_zero();
  320.             else
  321.             {
  322.                 do
  323.                 {
  324.                     back(1, position(TOP), 1, 0);
  325.                     pos = position(BOTTOM_PLUS_ONE);
  326.                 } while (pos == NULL_POSITION);
  327.             }
  328.         } else
  329.         {
  330.             eof_bell();
  331.             hit_eof++;
  332.             return;
  333.         }
  334.     }
  335.     forw(n, pos, force, only_last, 0);
  336. }
  337.  
  338. /*
  339.  * Display n more lines, backward.
  340.  * Start just before the line currently displayed at the top of the screen.
  341.  */
  342.     public void
  343. backward(n, force, only_last)
  344.     int n;
  345.     int force;
  346.     int only_last;
  347. {
  348.     POSITION pos;
  349.  
  350.     pos = position(TOP);
  351.     if (pos == NULL_POSITION && (!force || position(BOTTOM) == 0))
  352.     {
  353.         eof_bell();
  354.         return;   
  355.     }
  356.     back(n, pos, force, only_last);
  357. }
  358.  
  359. /*
  360.  * Get the backwards scroll limit.
  361.  * Must call this function instead of just using the value of
  362.  * back_scroll, because the default case depends on sc_height and
  363.  * top_scroll, as well as back_scroll.
  364.  */
  365.     public int
  366. get_back_scroll()
  367. {
  368.     if (back_scroll >= 0)
  369.         return (back_scroll);
  370.     if (top_scroll)
  371.         return (sc_height - 3);
  372.     return (10000); /* infinity */
  373. }
  374.  
  375. /*
  376.  * Get the forwards scroll limit.
  377.  * Must call this function instead of just using the value of
  378.  * forw_scroll, because the default case depends on sc_height
  379.  * as well as forw_scroll.
  380.  */
  381.     public int
  382. get_forw_scroll()
  383. {
  384.     if (forw_scroll >= 0)
  385.         return (forw_scroll);
  386.     return (sc_height - 3);
  387. }
  388.