.Xr botch fix
[unix-history] / usr / src / usr.bin / window / wwupdate.c
CommitLineData
60de5df9 1/*
46e9ea25
KB
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
3dd3a9e5
KB
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
87f529ec 8 * %sccs.include.redist.c%
60de5df9
EW
9 */
10
46e9ea25 11#ifndef lint
3dd3a9e5 12static char sccsid[] = "@(#)wwupdate.c 3.29 (Berkeley) %G%";
46e9ea25
KB
13#endif /* not lint */
14
bbb8329f 15#include "ww.h"
e908bfac 16#include "tt.h"
bbb8329f 17
b1189050 18wwupdate1(top, bot)
bbb8329f 19{
b7f39bc5
EW
20 int i;
21 register j;
b7f39bc5 22 char *touched;
6a1ef78a 23 struct ww_update *upd;
6a1ef78a
EW
24 char check_clreos = 0;
25 int scan_top, scan_bot;
bbb8329f 26
861cd1ed 27 wwnupdate++;
6a1ef78a
EW
28 {
29 register char *t1 = wwtouched + top, *t2 = wwtouched + bot;
30 register n;
31
32 while (!*t1++)
33 if (t1 == t2)
34 return;
35 while (!*--t2)
36 ;
37 scan_top = top = t1 - wwtouched - 1;
38 scan_bot = bot = t2 - wwtouched + 1;
96e4efe9
EW
39 if (scan_bot - scan_top > 1 &&
40 (tt.tt_clreos != 0 || tt.tt_clear != 0)) {
41 int st = tt.tt_clreos != 0 ? scan_top : 0;
6a1ef78a 42
4fa33fad
EW
43 /*
44 * t1 is one past the first touched row,
45 * t2 is on the last touched row.
46 */
47 for (t1--, n = 1; t1 < t2;)
6a1ef78a
EW
48 if (*t1++)
49 n++;
4fa33fad
EW
50 /*
51 * If we can't clreos then we try for clearing
52 * the whole screen.
53 */
6a1ef78a
EW
54 if (check_clreos = n * 10 > (wwnrow - st) * 9) {
55 scan_top = st;
56 scan_bot = wwnrow;
57 }
58 }
59 }
60 if (tt.tt_clreol == 0 && !check_clreos)
61 goto simple;
62 for (i = scan_top, touched = &wwtouched[i], upd = &wwupd[i];
63 i < scan_bot;
64 i++, touched++, upd++) {
65 register gain = 0;
66 register best_gain = 0;
67 register best_col;
68 register union ww_char *ns, *os;
69
70 if (wwinterrupt())
71 return;
72 if (!check_clreos && !*touched)
861cd1ed 73 continue;
6a1ef78a
EW
74 wwnupdscan++;
75 j = wwncol;
76 ns = &wwns[i][j];
77 os = &wwos[i][j];
78 while (--j >= 0) {
79 /*
80 * The cost of clearing is:
81 * ncol - nblank + X
82 * The cost of straight update is, more or less:
83 * ncol - nsame
84 * We clear if nblank - nsame > X
85 * X is the clreol overhead.
86 * So we make gain = nblank - nsame.
87 */
88 if ((--ns)->c_w == (--os)->c_w)
89 gain--;
90 else
91 best_gain--;
92 if (ns->c_w == ' ')
93 gain++;
99d51158 94 if (gain > best_gain) {
6a1ef78a
EW
95 best_col = j;
96 best_gain = gain;
97 }
98 }
99 upd->best_gain = best_gain;
100 upd->best_col = best_col;
101 upd->gain = gain;
102 }
103 if (check_clreos) {
104 register struct ww_update *u;
105 register gain = 0;
106 register best_gain = 0;
107 int best_row;
108 register simple_gain = 0;
109 char didit = 0;
b7f39bc5 110
4fa33fad
EW
111 /*
112 * gain is the advantage of clearing all the lines.
113 * best_gain is the advantage of clearing to eos
114 * at best_row and u->best_col.
115 * simple_gain is the advantage of using only clreol.
116 * We use g > best_gain because u->best_col can be
117 * undefined when u->best_gain is 0 so we can't use it.
118 */
6a1ef78a
EW
119 for (j = scan_bot - 1, u = wwupd + j; j >= top; j--, u--) {
120 register g = gain + u->best_gain;
121
4fa33fad 122 if (g > best_gain) {
6a1ef78a
EW
123 best_gain = g;
124 best_row = j;
04d70db4 125 }
6a1ef78a
EW
126 gain += u->gain;
127 if (tt.tt_clreol != 0 && u->best_gain > 4)
128 simple_gain += u->best_gain - 4;
04d70db4 129 }
6a1ef78a
EW
130 if (tt.tt_clreos == 0) {
131 if (gain > simple_gain && gain > 4) {
ab8b3b31 132 xxclear();
6a1ef78a
EW
133 i = top = scan_top;
134 bot = scan_bot;
135 j = 0;
136 didit = 1;
137 }
138 } else
139 if (best_gain > simple_gain && best_gain > 4) {
140 i = best_row;
ab8b3b31 141 xxclreos(i, j = wwupd[i].best_col);
6a1ef78a
EW
142 bot = scan_bot;
143 didit = 1;
144 }
145 if (didit) {
146 wwnupdclreos++;
147 wwnupdclreosline += wwnrow - i;
148 u = wwupd + i;
149 while (i < scan_bot) {
150 register union ww_char *os = &wwos[i][j];
151
152 for (j = wwncol - j; --j >= 0;)
153 os++->c_w = ' ';
96e4efe9 154 wwtouched[i++] |= WWU_TOUCHED;
6a1ef78a
EW
155 u++->best_gain = 0;
156 j = 0;
157 }
158 } else
159 wwnupdclreosmiss++;
160 }
161simple:
162 for (i = top, touched = &wwtouched[i], upd = &wwupd[i]; i < bot;
163 i++, touched++, upd++) {
164 register union ww_char *os, *ns;
165 char didit;
166
167 if (!*touched)
168 continue;
2b19684f 169 *touched = 0;
04d70db4
EW
170 wwnupdline++;
171 didit = 0;
6a1ef78a
EW
172 if (tt.tt_clreol != 0 && upd->best_gain > 4) {
173 wwnupdclreol++;
ab8b3b31 174 xxclreol(i, j = upd->best_col);
6a1ef78a
EW
175 for (os = &wwos[i][j], j = wwncol - j; --j >= 0;)
176 os++->c_w = ' ';
177 didit = 1;
178 }
bbb8329f
EW
179 ns = wwns[i];
180 os = wwos[i];
b7f39bc5 181 for (j = 0; j < wwncol;) {
6e3b31ff
EW
182 register char *p, *q;
183 char m;
184 int c;
185 register n;
186 char buf[512]; /* > wwncol */
187 union ww_char lastc;
188
b7f39bc5
EW
189 for (; j++ < wwncol && ns++->c_w == os++->c_w;)
190 ;
191 if (j > wwncol)
192 break;
193 p = buf;
f4f5703a 194 m = ns[-1].c_m;
b7f39bc5
EW
195 c = j - 1;
196 os[-1] = ns[-1];
197 *p++ = ns[-1].c_c;
6e3b31ff 198 n = 5;
b7f39bc5 199 q = p;
f4f5703a 200 while (j < wwncol && ns->c_m == m) {
b7f39bc5
EW
201 *p++ = ns->c_c;
202 if (ns->c_w == os->c_w) {
6e3b31ff 203 if (--n <= 0)
b7f39bc5
EW
204 break;
205 os++;
206 ns++;
207 } else {
6e3b31ff 208 n = 5;
b7f39bc5 209 q = p;
5e785082 210 lastc = *os;
b7f39bc5
EW
211 *os++ = *ns++;
212 }
213 j++;
bbb8329f 214 }
0ee576ef
EW
215 n = q - buf;
216 if (!wwwrap || i != wwnrow - 1 || c + n != wwncol)
217 xxwrite(i, c, buf, n, m);
218 else if (tt.tt_inschar || tt.tt_insspace) {
219 if (n > 1) {
220 q[-2] = q[-1];
221 n--;
222 } else
223 c--;
224 xxwrite(i, c, buf, n, m);
225 c += n - 1;
226 if (tt.tt_inschar)
227 xxinschar(i, c, ns[-2].c_c,
228 ns[-2].c_m);
229 else {
230 xxinsspace(i, c);
231 xxwrite(i, c, &ns[-2].c_c, 1,
232 ns[-2].c_m);
5e785082 233 }
0ee576ef
EW
234 } else {
235 if (--n)
236 xxwrite(i, c, buf, n, m);
237 os[-1] = lastc;
238 *touched = WWU_TOUCHED;
239 }
6a1ef78a 240 didit = 1;
bbb8329f 241 }
861cd1ed 242 if (!didit)
04d70db4 243 wwnupdmiss++;
bbb8329f
EW
244 }
245}