insert mode bug fix and cleanup
[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 *
5 * Redistribution and use in source and binary forms are permitted
5e8b0e60
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
60de5df9
EW
16 */
17
46e9ea25 18#ifndef lint
d9375810 19static char sccsid[] = "@(#)wwupdate.c 3.26 (Berkeley) %G%";
46e9ea25
KB
20#endif /* not lint */
21
bbb8329f 22#include "ww.h"
e908bfac 23#include "tt.h"
bbb8329f 24
b1189050 25wwupdate1(top, bot)
bbb8329f 26{
b7f39bc5
EW
27 int i;
28 register j;
b7f39bc5 29 char *touched;
6a1ef78a 30 struct ww_update *upd;
6a1ef78a
EW
31 char check_clreos = 0;
32 int scan_top, scan_bot;
bbb8329f 33
861cd1ed 34 wwnupdate++;
6a1ef78a
EW
35 {
36 register char *t1 = wwtouched + top, *t2 = wwtouched + bot;
37 register n;
38
39 while (!*t1++)
40 if (t1 == t2)
41 return;
42 while (!*--t2)
43 ;
44 scan_top = top = t1 - wwtouched - 1;
45 scan_bot = bot = t2 - wwtouched + 1;
96e4efe9
EW
46 if (scan_bot - scan_top > 1 &&
47 (tt.tt_clreos != 0 || tt.tt_clear != 0)) {
48 int st = tt.tt_clreos != 0 ? scan_top : 0;
6a1ef78a 49
4fa33fad
EW
50 /*
51 * t1 is one past the first touched row,
52 * t2 is on the last touched row.
53 */
54 for (t1--, n = 1; t1 < t2;)
6a1ef78a
EW
55 if (*t1++)
56 n++;
4fa33fad
EW
57 /*
58 * If we can't clreos then we try for clearing
59 * the whole screen.
60 */
6a1ef78a
EW
61 if (check_clreos = n * 10 > (wwnrow - st) * 9) {
62 scan_top = st;
63 scan_bot = wwnrow;
64 }
65 }
66 }
67 if (tt.tt_clreol == 0 && !check_clreos)
68 goto simple;
69 for (i = scan_top, touched = &wwtouched[i], upd = &wwupd[i];
70 i < scan_bot;
71 i++, touched++, upd++) {
72 register gain = 0;
73 register best_gain = 0;
74 register best_col;
75 register union ww_char *ns, *os;
76
77 if (wwinterrupt())
78 return;
79 if (!check_clreos && !*touched)
861cd1ed 80 continue;
6a1ef78a
EW
81 wwnupdscan++;
82 j = wwncol;
83 ns = &wwns[i][j];
84 os = &wwos[i][j];
85 while (--j >= 0) {
86 /*
87 * The cost of clearing is:
88 * ncol - nblank + X
89 * The cost of straight update is, more or less:
90 * ncol - nsame
91 * We clear if nblank - nsame > X
92 * X is the clreol overhead.
93 * So we make gain = nblank - nsame.
94 */
95 if ((--ns)->c_w == (--os)->c_w)
96 gain--;
97 else
98 best_gain--;
99 if (ns->c_w == ' ')
100 gain++;
99d51158 101 if (gain > best_gain) {
6a1ef78a
EW
102 best_col = j;
103 best_gain = gain;
104 }
105 }
106 upd->best_gain = best_gain;
107 upd->best_col = best_col;
108 upd->gain = gain;
109 }
110 if (check_clreos) {
111 register struct ww_update *u;
112 register gain = 0;
113 register best_gain = 0;
114 int best_row;
115 register simple_gain = 0;
116 char didit = 0;
b7f39bc5 117
4fa33fad
EW
118 /*
119 * gain is the advantage of clearing all the lines.
120 * best_gain is the advantage of clearing to eos
121 * at best_row and u->best_col.
122 * simple_gain is the advantage of using only clreol.
123 * We use g > best_gain because u->best_col can be
124 * undefined when u->best_gain is 0 so we can't use it.
125 */
6a1ef78a
EW
126 for (j = scan_bot - 1, u = wwupd + j; j >= top; j--, u--) {
127 register g = gain + u->best_gain;
128
4fa33fad 129 if (g > best_gain) {
6a1ef78a
EW
130 best_gain = g;
131 best_row = j;
04d70db4 132 }
6a1ef78a
EW
133 gain += u->gain;
134 if (tt.tt_clreol != 0 && u->best_gain > 4)
135 simple_gain += u->best_gain - 4;
04d70db4 136 }
6a1ef78a
EW
137 if (tt.tt_clreos == 0) {
138 if (gain > simple_gain && gain > 4) {
ab8b3b31 139 xxclear();
6a1ef78a
EW
140 i = top = scan_top;
141 bot = scan_bot;
142 j = 0;
143 didit = 1;
144 }
145 } else
146 if (best_gain > simple_gain && best_gain > 4) {
147 i = best_row;
ab8b3b31 148 xxclreos(i, j = wwupd[i].best_col);
6a1ef78a
EW
149 bot = scan_bot;
150 didit = 1;
151 }
152 if (didit) {
153 wwnupdclreos++;
154 wwnupdclreosline += wwnrow - i;
155 u = wwupd + i;
156 while (i < scan_bot) {
157 register union ww_char *os = &wwos[i][j];
158
159 for (j = wwncol - j; --j >= 0;)
160 os++->c_w = ' ';
96e4efe9 161 wwtouched[i++] |= WWU_TOUCHED;
6a1ef78a
EW
162 u++->best_gain = 0;
163 j = 0;
164 }
165 } else
166 wwnupdclreosmiss++;
167 }
168simple:
169 for (i = top, touched = &wwtouched[i], upd = &wwupd[i]; i < bot;
170 i++, touched++, upd++) {
171 register union ww_char *os, *ns;
172 char didit;
173
174 if (!*touched)
175 continue;
2b19684f 176 *touched = 0;
04d70db4
EW
177 wwnupdline++;
178 didit = 0;
6a1ef78a
EW
179 if (tt.tt_clreol != 0 && upd->best_gain > 4) {
180 wwnupdclreol++;
ab8b3b31 181 xxclreol(i, j = upd->best_col);
6a1ef78a
EW
182 for (os = &wwos[i][j], j = wwncol - j; --j >= 0;)
183 os++->c_w = ' ';
184 didit = 1;
185 }
bbb8329f
EW
186 ns = wwns[i];
187 os = wwos[i];
b7f39bc5 188 for (j = 0; j < wwncol;) {
6e3b31ff
EW
189 register char *p, *q;
190 char m;
191 int c;
192 register n;
193 char buf[512]; /* > wwncol */
194 union ww_char lastc;
195
b7f39bc5
EW
196 for (; j++ < wwncol && ns++->c_w == os++->c_w;)
197 ;
198 if (j > wwncol)
199 break;
200 p = buf;
f4f5703a 201 m = ns[-1].c_m;
b7f39bc5
EW
202 c = j - 1;
203 os[-1] = ns[-1];
204 *p++ = ns[-1].c_c;
6e3b31ff 205 n = 5;
b7f39bc5 206 q = p;
f4f5703a 207 while (j < wwncol && ns->c_m == m) {
b7f39bc5
EW
208 *p++ = ns->c_c;
209 if (ns->c_w == os->c_w) {
6e3b31ff 210 if (--n <= 0)
b7f39bc5
EW
211 break;
212 os++;
213 ns++;
214 } else {
6e3b31ff 215 n = 5;
b7f39bc5 216 q = p;
5e785082 217 lastc = *os;
b7f39bc5
EW
218 *os++ = *ns++;
219 }
220 j++;
bbb8329f 221 }
5e785082
EW
222 if (wwwrap
223 && i == wwnrow - 1 && q - buf + c == wwncol) {
d9375810 224 if (tt.tt_inschar) {
594208de 225 if (q - buf != 1) {
ab8b3b31
EW
226 xxwrite(i, c, buf + 1,
227 q - buf - 1, m);
d9375810 228 xxinschar(i, c, *buf, m);
594208de 229 } else {
ab8b3b31
EW
230 xxwrite(i, c - 1, buf, 1, m);
231 xxinschar(i, c - 1,
d9375810 232 ns[-2].c_c, ns[-2].c_m);
594208de 233 }
d9375810 234 } else if (tt.tt_insspace) {
2d152f42 235 if (q - buf != 1) {
ab8b3b31
EW
236 xxwrite(i, c, buf + 1,
237 q - buf - 1, m);
d9375810 238 xxinsspace(i, c);
ab8b3b31 239 xxwrite(i, c, buf, 1, m);
2d152f42 240 } else {
ab8b3b31 241 xxwrite(i, c - 1, buf, 1, m);
d9375810 242 xxinsspace(i, c - 1);
ab8b3b31
EW
243 xxwrite(i, c - 1, &ns[-2].c_c,
244 1, ns[-2].c_m);
2d152f42 245 }
5e785082 246 } else {
ab8b3b31
EW
247 if (q - buf > 1)
248 xxwrite(i, c, buf,
249 q - buf - 1, m);
2b19684f
EW
250 os[-1] = lastc;
251 *touched = WWU_TOUCHED;
5e785082 252 }
ab8b3b31
EW
253 } else
254 xxwrite(i, c, buf, q - buf, m);
6a1ef78a 255 didit = 1;
bbb8329f 256 }
861cd1ed 257 if (!didit)
04d70db4 258 wwnupdmiss++;
bbb8329f
EW
259 }
260}