home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / less373.zip / position.c < prev    next >
C/C++ Source or Header  |  2002-01-14  |  5KB  |  233 lines

  1. /*
  2.  * Copyright (C) 1984-2000  Mark Nudelman
  3.  *
  4.  * You may distribute under the terms of either the GNU General Public
  5.  * License or the Less License, as specified in the README file.
  6.  *
  7.  * For more information about less, or for information on how to 
  8.  * contact the author, see the README file.
  9.  */
  10.  
  11.  
  12. /*
  13.  * Routines dealing with the "position" table.
  14.  * This is a table which tells the position (in the input file) of the
  15.  * first char on each currently displayed line.
  16.  *
  17.  * {{ The position table is scrolled by moving all the entries.
  18.  *    Would be better to have a circular table 
  19.  *    and just change a couple of pointers. }}
  20.  */
  21.  
  22. #include "less.h"
  23. #include "position.h"
  24.  
  25. static POSITION *table = NULL;    /* The position table */
  26. static int table_size;
  27.  
  28. extern int sc_width, sc_height;
  29.  
  30. /*
  31.  * Return the starting file position of a line displayed on the screen.
  32.  * The line may be specified as a line number relative to the top
  33.  * of the screen, but is usually one of these special cases:
  34.  *    the top (first) line on the screen
  35.  *    the second line on the screen
  36.  *    the bottom line on the screen
  37.  *    the line after the bottom line on the screen
  38.  */
  39.     public POSITION
  40. position(where)
  41.     int where;
  42. {
  43.     switch (where)
  44.     {
  45.     case BOTTOM:
  46.         where = sc_height - 2;
  47.         break;
  48.     case BOTTOM_PLUS_ONE:
  49.         where = sc_height - 1;
  50.         break;
  51.     case MIDDLE:
  52.         where = (sc_height - 1) / 2;
  53.     }
  54.     return (table[where]);
  55. }
  56.  
  57. /*
  58.  * Add a new file position to the bottom of the position table.
  59.  */
  60.     public void
  61. add_forw_pos(pos)
  62.     POSITION pos;
  63. {
  64.     register int i;
  65.  
  66.     /*
  67.      * Scroll the position table up.
  68.      */
  69.     for (i = 1;  i < sc_height;  i++)
  70.         table[i-1] = table[i];
  71.     table[sc_height - 1] = pos;
  72. }
  73.  
  74. /*
  75.  * Add a new file position to the top of the position table.
  76.  */
  77.     public void
  78. add_back_pos(pos)
  79.     POSITION pos;
  80. {
  81.     register int i;
  82.  
  83.     /*
  84.      * Scroll the position table down.
  85.      */
  86.     for (i = sc_height - 1;  i > 0;  i--)
  87.         table[i] = table[i-1];
  88.     table[0] = pos;
  89. }
  90.  
  91. /*
  92.  * Initialize the position table, done whenever we clear the screen.
  93.  */
  94.     public void
  95. pos_clear()
  96. {
  97.     register int i;
  98.  
  99.     for (i = 0;  i < sc_height;  i++)
  100.         table[i] = NULL_POSITION;
  101. }
  102.  
  103. /*
  104.  * Allocate or reallocate the position table.
  105.  */
  106.     public void
  107. pos_init()
  108. {
  109.     struct scrpos scrpos;
  110.  
  111.     if (sc_height <= table_size)
  112.         return;
  113.     /*
  114.      * If we already have a table, remember the first line in it
  115.      * before we free it, so we can copy that line to the new table.
  116.      */
  117.     if (table != NULL)
  118.     {
  119.         get_scrpos(&scrpos);
  120.         free((char*)table);
  121.     } else
  122.         scrpos.pos = NULL_POSITION;
  123.     table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
  124.     table_size = sc_height;
  125.     pos_clear();
  126.     if (scrpos.pos != NULL_POSITION)
  127.         table[scrpos.ln-1] = scrpos.pos;
  128. }
  129.  
  130. /*
  131.  * See if the byte at a specified position is currently on the screen.
  132.  * Check the position table to see if the position falls within its range.
  133.  * Return the position table entry if found, -1 if not.
  134.  */
  135.     public int
  136. onscreen(pos)
  137.     POSITION pos;
  138. {
  139.     register int i;
  140.  
  141.     if (pos < table[0])
  142.         return (-1);
  143.     for (i = 1;  i < sc_height;  i++)
  144.         if (pos < table[i])
  145.             return (i-1);
  146.     return (-1);
  147. }
  148.  
  149. /*
  150.  * See if the entire screen is empty.
  151.  */
  152.     public int
  153. empty_screen()
  154. {
  155.     return (empty_lines(0, sc_height-1));
  156. }
  157.  
  158.     public int
  159. empty_lines(s, e)
  160.     int s;
  161.     int e;
  162. {
  163.     register int i;
  164.  
  165.     for (i = s;  i <= e;  i++)
  166.         if (table[i] != NULL_POSITION)
  167.             return (0);
  168.     return (1);
  169. }
  170.  
  171. /*
  172.  * Get the current screen position.
  173.  * The screen position consists of both a file position and
  174.  * a screen line number where the file position is placed on the screen.
  175.  * Normally the screen line number is 0, but if we are positioned
  176.  * such that the top few lines are empty, we may have to set
  177.  * the screen line to a number > 0.
  178.  */
  179.     public void
  180. get_scrpos(scrpos)
  181.     struct scrpos *scrpos;
  182. {
  183.     register int i;
  184.  
  185.     /*
  186.      * Find the first line on the screen which has something on it,
  187.      * and return the screen line number and the file position.
  188.      */
  189.     for (i = 0; i < sc_height;  i++)
  190.         if (table[i] != NULL_POSITION)
  191.         {
  192.             scrpos->ln = i+1;
  193.             scrpos->pos = table[i];
  194.             return;
  195.         }
  196.     /*
  197.      * The screen is empty.
  198.      */
  199.     scrpos->pos = NULL_POSITION;
  200. }
  201.  
  202. /*
  203.  * Adjust a screen line number to be a simple positive integer
  204.  * in the range { 0 .. sc_height-2 }.
  205.  * (The bottom line, sc_height-1, is reserved for prompts, etc.)
  206.  * The given "sline" may be in the range { 1 .. sc_height-1 }
  207.  * to refer to lines relative to the top of the screen (starting from 1),
  208.  * or it may be in { -1 .. -(sc_height-1) } to refer to lines
  209.  * relative to the bottom of the screen.
  210.  */
  211.     public int
  212. adjsline(sline)
  213.     int sline;
  214. {
  215.     /*
  216.      * Negative screen line number means
  217.      * relative to the bottom of the screen.
  218.      */
  219.     if (sline < 0)
  220.         sline += sc_height;
  221.     /*
  222.      * Can't be less than 1 or greater than sc_height-1.
  223.      */
  224.     if (sline <= 0)
  225.         sline = 1;
  226.     if (sline >= sc_height)
  227.         sline = sc_height - 1;
  228.     /*
  229.      * Return zero-based line number, not one-based.
  230.      */
  231.     return (sline-1);
  232. }
  233.