]> git.saurik.com Git - apple/shell_cmds.git/blob - window/wwupdate.c
shell_cmds-34.tar.gz
[apple/shell_cmds.git] / window / wwupdate.c
1 /* $NetBSD: wwupdate.c,v 1.4 1997/11/21 08:37:59 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Edward Wang at The University of California, Berkeley.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 #ifndef lint
41 #if 0
42 static char sccsid[] = "@(#)wwupdate.c 8.1 (Berkeley) 6/6/93";
43 #else
44 __RCSID("$NetBSD: wwupdate.c,v 1.4 1997/11/21 08:37:59 lukem Exp $");
45 #endif
46 #endif /* not lint */
47
48 #include "ww.h"
49 #include "tt.h"
50 #include "xx.h"
51
52 void
53 wwupdate1(top, bot)
54 int top, bot;
55 {
56 int i;
57 int j;
58 char *touched;
59 struct ww_update *upd;
60 char check_clreos = 0;
61 int scan_top, scan_bot;
62
63 wwnupdate++;
64 {
65 char *t1 = wwtouched + top, *t2 = wwtouched + bot;
66 int n;
67
68 while (!*t1++)
69 if (t1 == t2)
70 return;
71 while (!*--t2)
72 ;
73 scan_top = top = t1 - wwtouched - 1;
74 scan_bot = bot = t2 - wwtouched + 1;
75 if (scan_bot - scan_top > 1 &&
76 (tt.tt_clreos != 0 || tt.tt_clear != 0)) {
77 int st = tt.tt_clreos != 0 ? scan_top : 0;
78
79 /*
80 * t1 is one past the first touched row,
81 * t2 is on the last touched row.
82 */
83 for (t1--, n = 1; t1 < t2;)
84 if (*t1++)
85 n++;
86 /*
87 * If we can't clreos then we try for clearing
88 * the whole screen.
89 */
90 if ((check_clreos = n * 10 > (wwnrow - st) * 9)) {
91 scan_top = st;
92 scan_bot = wwnrow;
93 }
94 }
95 }
96 if (tt.tt_clreol == 0 && !check_clreos)
97 goto simple;
98 for (i = scan_top, touched = &wwtouched[i], upd = &wwupd[i];
99 i < scan_bot;
100 i++, touched++, upd++) {
101 int gain = 0;
102 int best_gain = 0;
103 int best_col = 0;
104 union ww_char *ns, *os;
105
106 if (wwinterrupt())
107 return;
108 if (!check_clreos && !*touched)
109 continue;
110 wwnupdscan++;
111 j = wwncol;
112 ns = &wwns[i][j];
113 os = &wwos[i][j];
114 while (--j >= 0) {
115 /*
116 * The cost of clearing is:
117 * ncol - nblank + X
118 * The cost of straight update is, more or less:
119 * ncol - nsame
120 * We clear if nblank - nsame > X
121 * X is the clreol overhead.
122 * So we make gain = nblank - nsame.
123 */
124 if ((--ns)->c_w == (--os)->c_w)
125 gain--;
126 else
127 best_gain--;
128 if (ns->c_w == ' ')
129 gain++;
130 if (gain > best_gain) {
131 best_col = j;
132 best_gain = gain;
133 }
134 }
135 upd->best_gain = best_gain;
136 upd->best_col = best_col;
137 upd->gain = gain;
138 }
139 if (check_clreos) {
140 struct ww_update *u;
141 int gain = 0;
142 int best_gain = 0;
143 int best_row = 0;
144 int simple_gain = 0;
145 char didit = 0;
146
147 /*
148 * gain is the advantage of clearing all the lines.
149 * best_gain is the advantage of clearing to eos
150 * at best_row and u->best_col.
151 * simple_gain is the advantage of using only clreol.
152 * We use g > best_gain because u->best_col can be
153 * undefined when u->best_gain is 0 so we can't use it.
154 */
155 for (j = scan_bot - 1, u = wwupd + j; j >= top; j--, u--) {
156 int g = gain + u->best_gain;
157
158 if (g > best_gain) {
159 best_gain = g;
160 best_row = j;
161 }
162 gain += u->gain;
163 if (tt.tt_clreol != 0 && u->best_gain > 4)
164 simple_gain += u->best_gain - 4;
165 }
166 if (tt.tt_clreos == 0) {
167 if (gain > simple_gain && gain > 4) {
168 xxclear();
169 i = top = scan_top;
170 bot = scan_bot;
171 j = 0;
172 didit = 1;
173 }
174 } else
175 if (best_gain > simple_gain && best_gain > 4) {
176 i = best_row;
177 xxclreos(i, j = wwupd[i].best_col);
178 bot = scan_bot;
179 didit = 1;
180 }
181 if (didit) {
182 wwnupdclreos++;
183 wwnupdclreosline += wwnrow - i;
184 u = wwupd + i;
185 while (i < scan_bot) {
186 union ww_char *os = &wwos[i][j];
187
188 for (j = wwncol - j; --j >= 0;)
189 os++->c_w = ' ';
190 wwtouched[i++] |= WWU_TOUCHED;
191 u++->best_gain = 0;
192 j = 0;
193 }
194 } else
195 wwnupdclreosmiss++;
196 }
197 simple:
198 for (i = top, touched = &wwtouched[i], upd = &wwupd[i]; i < bot;
199 i++, touched++, upd++) {
200 union ww_char *os, *ns;
201 char didit;
202
203 if (!*touched)
204 continue;
205 *touched = 0;
206 wwnupdline++;
207 didit = 0;
208 if (tt.tt_clreol != 0 && upd->best_gain > 4) {
209 wwnupdclreol++;
210 xxclreol(i, j = upd->best_col);
211 for (os = &wwos[i][j], j = wwncol - j; --j >= 0;)
212 os++->c_w = ' ';
213 didit = 1;
214 }
215 ns = wwns[i];
216 os = wwos[i];
217 for (j = 0; j < wwncol;) {
218 char *p, *q;
219 char m;
220 int c;
221 int n;
222 char buf[512]; /* > wwncol */
223 union ww_char lastc;
224
225 for (; j++ < wwncol && ns++->c_w == os++->c_w;)
226 ;
227 if (j > wwncol)
228 break;
229 p = buf;
230 m = ns[-1].c_m;
231 c = j - 1;
232 os[-1] = ns[-1];
233 *p++ = ns[-1].c_c;
234 n = 5;
235 q = p;
236 while (j < wwncol && ns->c_m == m) {
237 *p++ = ns->c_c;
238 if (ns->c_w == os->c_w) {
239 if (--n <= 0)
240 break;
241 os++;
242 ns++;
243 } else {
244 n = 5;
245 q = p;
246 lastc = *os;
247 *os++ = *ns++;
248 }
249 j++;
250 }
251 n = q - buf;
252 if (!wwwrap || i != wwnrow - 1 || c + n != wwncol)
253 xxwrite(i, c, buf, n, m);
254 else if (tt.tt_inschar || tt.tt_insspace) {
255 if (n > 1) {
256 q[-2] = q[-1];
257 n--;
258 } else
259 c--;
260 xxwrite(i, c, buf, n, m);
261 c += n - 1;
262 if (tt.tt_inschar)
263 xxinschar(i, c, ns[-2].c_c,
264 ns[-2].c_m);
265 else {
266 xxinsspace(i, c);
267 xxwrite(i, c, &ns[-2].c_c, 1,
268 ns[-2].c_m);
269 }
270 } else {
271 if (--n)
272 xxwrite(i, c, buf, n, m);
273 os[-1] = lastc;
274 *touched = WWU_TOUCHED;
275 }
276 didit = 1;
277 }
278 if (!didit)
279 wwnupdmiss++;
280 }
281 }