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