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