home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / less3292.zip / position.c < prev    next >
C/C++ Source or Header  |  1996-04-09  |  6KB  |  249 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994,1995,1996  Mark Nudelman
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice in the documentation and/or other materials provided with 
  12.  *    the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
  15.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  17.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
  18.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  19.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
  20.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
  21.  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  22.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
  23.  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 
  24.  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * Routines dealing with the "position" table.
  30.  * This is a table which tells the position (in the input file) of the
  31.  * first char on each currently displayed line.
  32.  *
  33.  * {{ The position table is scrolled by moving all the entries.
  34.  *    Would be better to have a circular table 
  35.  *    and just change a couple of pointers. }}
  36.  */
  37.  
  38. #include "less.h"
  39. #include "position.h"
  40.  
  41. static POSITION *table = NULL;    /* The position table */
  42. static int table_size;
  43.  
  44. extern int sc_width, sc_height;
  45.  
  46. /*
  47.  * Return the starting file position of a line displayed on the screen.
  48.  * The line may be specified as a line number relative to the top
  49.  * of the screen, but is usually one of these special cases:
  50.  *    the top (first) line on the screen
  51.  *    the second line on the screen
  52.  *    the bottom line on the screen
  53.  *    the line after the bottom line on the screen
  54.  */
  55.     public POSITION
  56. position(where)
  57.     int where;
  58. {
  59.     switch (where)
  60.     {
  61.     case BOTTOM:
  62.         where = sc_height - 2;
  63.         break;
  64.     case BOTTOM_PLUS_ONE:
  65.         where = sc_height - 1;
  66.         break;
  67.     case MIDDLE:
  68.         where = (sc_height - 1) / 2;
  69.     }
  70.     return (table[where]);
  71. }
  72.  
  73. /*
  74.  * Add a new file position to the bottom of the position table.
  75.  */
  76.     public void
  77. add_forw_pos(pos)
  78.     POSITION pos;
  79. {
  80.     register int i;
  81.  
  82.     /*
  83.      * Scroll the position table up.
  84.      */
  85.     for (i = 1;  i < sc_height;  i++)
  86.         table[i-1] = table[i];
  87.     table[sc_height - 1] = pos;
  88. }
  89.  
  90. /*
  91.  * Add a new file position to the top of the position table.
  92.  */
  93.     public void
  94. add_back_pos(pos)
  95.     POSITION pos;
  96. {
  97.     register int i;
  98.  
  99.     /*
  100.      * Scroll the position table down.
  101.      */
  102.     for (i = sc_height - 1;  i > 0;  i--)
  103.         table[i] = table[i-1];
  104.     table[0] = pos;
  105. }
  106.  
  107. /*
  108.  * Initialize the position table, done whenever we clear the screen.
  109.  */
  110.     public void
  111. pos_clear()
  112. {
  113.     register int i;
  114.  
  115.     for (i = 0;  i < sc_height;  i++)
  116.         table[i] = NULL_POSITION;
  117. }
  118.  
  119. /*
  120.  * Allocate or reallocate the position table.
  121.  */
  122.     public void
  123. pos_init()
  124. {
  125.     struct scrpos scrpos;
  126.  
  127.     if (sc_height <= table_size)
  128.         return;
  129.     /*
  130.      * If we already have a table, remember the first line in it
  131.      * before we free it, so we can copy that line to the new table.
  132.      */
  133.     if (table != NULL)
  134.     {
  135.         get_scrpos(&scrpos);
  136.         free((char*)table);
  137.     } else
  138.         scrpos.pos = NULL_POSITION;
  139.     table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
  140.     table_size = sc_height;
  141.     pos_clear();
  142.     if (scrpos.pos != NULL_POSITION)
  143.         table[scrpos.ln-1] = scrpos.pos;
  144. }
  145.  
  146. /*
  147.  * See if the byte at a specified position is currently on the screen.
  148.  * Check the position table to see if the position falls within its range.
  149.  * Return the position table entry if found, -1 if not.
  150.  */
  151.     public int
  152. onscreen(pos)
  153.     POSITION pos;
  154. {
  155.     register int i;
  156.  
  157.     if (pos < table[0])
  158.         return (-1);
  159.     for (i = 1;  i < sc_height;  i++)
  160.         if (pos < table[i])
  161.             return (i-1);
  162.     return (-1);
  163. }
  164.  
  165. /*
  166.  * See if the entire screen is empty.
  167.  */
  168.     public int
  169. empty_screen()
  170. {
  171.     return (empty_lines(0, sc_height-1));
  172. }
  173.  
  174.     public int
  175. empty_lines(s, e)
  176.     int s;
  177.     int e;
  178. {
  179.     register int i;
  180.  
  181.     for (i = s;  i <= e;  i++)
  182.         if (table[i] != NULL_POSITION)
  183.             return (0);
  184.     return (1);
  185. }
  186.  
  187. /*
  188.  * Get the current screen position.
  189.  * The screen position consists of both a file position and
  190.  * a screen line number where the file position is placed on the screen.
  191.  * Normally the screen line number is 0, but if we are positioned
  192.  * such that the top few lines are empty, we may have to set
  193.  * the screen line to a number > 0.
  194.  */
  195.     public void
  196. get_scrpos(scrpos)
  197.     struct scrpos *scrpos;
  198. {
  199.     register int i;
  200.  
  201.     /*
  202.      * Find the first line on the screen which has something on it,
  203.      * and return the screen line number and the file position.
  204.      */
  205.     for (i = 0; i < sc_height;  i++)
  206.         if (table[i] != NULL_POSITION)
  207.         {
  208.             scrpos->ln = i+1;
  209.             scrpos->pos = table[i];
  210.             return;
  211.         }
  212.     /*
  213.      * The screen is empty.
  214.      */
  215.     scrpos->pos = NULL_POSITION;
  216. }
  217.  
  218. /*
  219.  * Adjust a screen line number to be a simple positive integer
  220.  * in the range { 0 .. sc_height-2 }.
  221.  * (The bottom line, sc_height-1, is reserved for prompts, etc.)
  222.  * The given "sline" may be in the range { 1 .. sc_height-1 }
  223.  * to refer to lines relative to the top of the screen (starting from 1),
  224.  * or it may be in { -1 .. -(sc_height-1) } to refer to lines
  225.  * relative to the bottom of the screen.
  226.  */
  227.     public int
  228. adjsline(sline)
  229.     int sline;
  230. {
  231.     /*
  232.      * Negative screen line number means
  233.      * relative to the bottom of the screen.
  234.      */
  235.     if (sline < 0)
  236.         sline += sc_height;
  237.     /*
  238.      * Can't be less than 1 or greater than sc_height-1.
  239.      */
  240.     if (sline <= 0)
  241.         sline = 1;
  242.     if (sline >= sc_height)
  243.         sline = sc_height - 1;
  244.     /*
  245.      * Return zero-based line number, not one-based.
  246.      */
  247.     return (sline-1);
  248. }
  249.