delay calling wwupdate1() until cursor moved off this line
[unix-history] / usr / src / usr.bin / window / wwwrite.c
CommitLineData
fe3db729 1#ifndef lint
b17025b3 2static char sccsid[] = "@(#)wwwrite.c 3.24 %G%";
fe3db729
EW
3#endif
4
60de5df9
EW
5/*
6 * Copyright (c) 1983 Regents of the University of California,
7 * All rights reserved. Redistribution permitted subject to
8 * the terms of the Berkeley Software License Agreement.
9 */
10
fe3db729 11#include "ww.h"
b1189050 12#include "tt.h"
0e64e422 13#include "char.h"
fe3db729 14
0e64e422
EW
15/*
16 * To support control character expansion, we save the old
17 * p and q values in r and s, and point p at the beginning
18 * of the expanded string, and q at some safe place beyond it
19 * (p + 10). At strategic points in the loops, we check
20 * for (r && !*p) and restore the saved values back into
21 * p and q. Essentially, we implement a stack of depth 2,
22 * to avoid recursion, which might be a better idea.
23 */
fe3db729
EW
24wwwrite(w, p, n)
25register struct ww *w;
26register char *p;
2b269ee7 27int n;
fe3db729 28{
19f9784c 29 char hascursor;
b1189050
EW
30 char *savep = p;
31 char *q = p + n;
0e64e422
EW
32 char *r = 0;
33 char *s;
fe3db729 34
1b032f84
EW
35#ifdef lint
36 s = 0; /* define it before possible use */
37#endif
73218728
EW
38 if (hascursor = w->ww_hascursor)
39 wwcursor(w, 0);
b1189050 40 while (p < q && !w->ww_stopped && (!wwinterrupt() || w->ww_nointr)) {
0e64e422
EW
41 if (r && !*p) {
42 p = r;
43 q = s;
44 r = 0;
45 continue;
46 }
47 if (w->ww_wstate == 0 && (isprt(*p)
48 || w->ww_unctrl && isunctrl(*p))) {
19f9784c 49 register i;
19f9784c 50 register union ww_char *bp;
04d70db4 51 int col, col1;
19f9784c 52
04d70db4 53 if (w->ww_insert) { /* this is very slow */
b1189050
EW
54 if (*p == '\t') {
55 p++;
56 w->ww_cur.c += 8 -
57 (w->ww_cur.c - w->ww_w.l & 7);
58 goto chklf;
59 }
0e64e422
EW
60 if (!isprt(*p)) {
61 r = p + 1;
62 s = q;
63 p = unctrl(*p);
64 q = p + 10;
65 }
f2a77fe1 66 wwinschar(w, w->ww_cur.r, w->ww_cur.c,
19f9784c
EW
67 *p++ | w->ww_modes << WWC_MSHIFT);
68 goto right;
69 }
70
b1189050
EW
71 bp = &w->ww_buf[w->ww_cur.r][w->ww_cur.c];
72 i = w->ww_cur.c;
0e64e422
EW
73 while (i < w->ww_w.r && p < q)
74 if (!*p && r) {
75 p = r;
76 q = s;
77 r = 0;
78 } else if (*p == '\t') {
b1189050
EW
79 register tmp = 8 - (i - w->ww_w.l & 7);
80 p++;
81 i += tmp;
82 bp += tmp;
0e64e422 83 } else if (isprt(*p)) {
b1189050
EW
84 bp++->c_w = *p++
85 | w->ww_modes << WWC_MSHIFT;
86 i++;
0e64e422
EW
87 } else if (w->ww_unctrl && isunctrl(*p)) {
88 r = p + 1;
89 s = q;
90 p = unctrl(*p);
91 q = p + 10;
92 } else
93 break;
04d70db4 94 col = MAX(w->ww_cur.c, w->ww_i.l);
b1189050
EW
95 col1 = MIN(i, w->ww_i.r);
96 w->ww_cur.c = i;
0e64e422
EW
97 if (w->ww_cur.r >= w->ww_i.t
98 && w->ww_cur.r < w->ww_i.b) {
04d70db4
EW
99 register union ww_char *ns = wwns[w->ww_cur.r];
100 register char *smap = &wwsmap[w->ww_cur.r][col];
101 register char *win = w->ww_win[w->ww_cur.r];
b1189050 102 int nchanged = 0;
bb05dfb5 103
04d70db4
EW
104 bp = w->ww_buf[w->ww_cur.r];
105 for (i = col; i < col1; i++)
2b269ee7 106 if (*smap++ == w->ww_index) {
b1189050 107 nchanged++;
04d70db4
EW
108 ns[i].c_w = bp[i].c_w
109 ^ win[i] << WWC_MSHIFT;
30647f51 110 }
b17025b3 111 if (nchanged > 0)
b1189050 112 wwtouched[w->ww_cur.r] |= WWU_TOUCHED;
19f9784c 113 }
b1189050
EW
114 chklf:
115 if (w->ww_cur.c >= w->ww_w.r)
116 goto crlf;
117 } else switch (w->ww_wstate) {
19f9784c
EW
118 case 0:
119 switch (*p++) {
fe3db729 120 case '\n':
bb05dfb5 121 if (w->ww_mapnl)
b1189050 122 crlf:
f2a77fe1 123 w->ww_cur.c = w->ww_w.l;
bb05dfb5 124 lf:
b17025b3
EW
125 if (!w->ww_noupdate && wwtouched[w->ww_cur.r])
126 wwupdate1(w->ww_cur.r, w->ww_cur.r + 1);
f2a77fe1
EW
127 if (++w->ww_cur.r >= w->ww_w.b) {
128 w->ww_cur.r = w->ww_w.b - 1;
86697c44
EW
129 if (w->ww_w.b < w->ww_b.b) {
130 (void) wwscroll1(w, w->ww_i.t,
131 w->ww_i.b, 1, 0);
132 w->ww_buf++;
133 w->ww_b.t--;
134 w->ww_b.b--;
135 } else
f2a77fe1 136 wwdelline(w, w->ww_b.t);
bb05dfb5 137 }
fe3db729 138 break;
fe3db729 139 case '\b':
f2a77fe1
EW
140 if (--w->ww_cur.c < w->ww_w.l) {
141 w->ww_cur.c = w->ww_w.r - 1;
b0d4d9e2
EW
142 goto up;
143 }
bb05dfb5 144 break;
fe3db729 145 case '\r':
f2a77fe1 146 w->ww_cur.c = w->ww_w.l;
bb05dfb5 147 break;
0e64e422
EW
148 case ctrl(g):
149 ttputc(ctrl(g));
fe3db729 150 break;
0e64e422 151 case ctrl([):
fe3db729
EW
152 w->ww_wstate = 1;
153 break;
154 }
155 break;
156 case 1:
157 w->ww_wstate = 0;
19f9784c 158 switch (*p++) {
fe3db729
EW
159 case '@':
160 w->ww_insert = 1;
161 break;
162 case 'A':
b0d4d9e2 163 up:
b17025b3
EW
164 if (!w->ww_noupdate && wwtouched[w->ww_cur.r])
165 wwupdate1(w->ww_cur.r, w->ww_cur.r + 1);
f2a77fe1
EW
166 if (--w->ww_cur.r < w->ww_w.t) {
167 w->ww_cur.r = w->ww_w.t;
86697c44
EW
168 if (w->ww_w.t > w->ww_b.t) {
169 (void) wwscroll1(w, w->ww_i.t,
170 w->ww_i.b, -1, 0);
171 w->ww_buf--;
172 w->ww_b.t++;
173 w->ww_b.b++;
174 } else
f2a77fe1 175 wwinsline(w, w->ww_b.t);
b0d4d9e2 176 }
fe3db729
EW
177 break;
178 case 'B':
bb05dfb5 179 goto lf;
fe3db729 180 case 'C':
f2a77fe1 181 right:
b1189050
EW
182 w->ww_cur.c++;
183 goto chklf;
fe3db729 184 case 'E':
215eb00f 185 w->ww_buf -= w->ww_w.t - w->ww_b.t;
f2a77fe1
EW
186 w->ww_b.t = w->ww_w.t;
187 w->ww_b.b = w->ww_b.t + w->ww_b.nr;
188 w->ww_cur.r = w->ww_w.t;
189 w->ww_cur.c = w->ww_w.l;
190 wwclreos(w, w->ww_w.t, w->ww_w.l);
fe3db729
EW
191 break;
192 case 'H':
b17025b3
EW
193 if (!w->ww_noupdate && wwtouched[w->ww_cur.r])
194 wwupdate1(w->ww_cur.r, w->ww_cur.r + 1);
f2a77fe1
EW
195 w->ww_cur.r = w->ww_w.t;
196 w->ww_cur.c = w->ww_w.l;
fe3db729
EW
197 break;
198 case 'J':
f2a77fe1 199 wwclreos(w, w->ww_cur.r, w->ww_cur.c);
fe3db729
EW
200 break;
201 case 'K':
f2a77fe1 202 wwclreol(w, w->ww_cur.r, w->ww_cur.c);
fe3db729
EW
203 break;
204 case 'L':
b17025b3
EW
205 if (!w->ww_noupdate && wwtouched[w->ww_cur.r])
206 wwupdate1(w->ww_cur.r, w->ww_cur.r + 1);
f2a77fe1 207 wwinsline(w, w->ww_cur.r);
fe3db729
EW
208 break;
209 case 'M':
f2a77fe1 210 wwdelline(w, w->ww_cur.r);
fe3db729
EW
211 break;
212 case 'N':
f2a77fe1 213 wwdelchar(w, w->ww_cur.r, w->ww_cur.c);
fe3db729
EW
214 break;
215 case 'O':
216 w->ww_insert = 0;
217 break;
218 case 'Y':
b17025b3
EW
219 if (!w->ww_noupdate && wwtouched[w->ww_cur.r])
220 wwupdate1(w->ww_cur.r, w->ww_cur.r + 1);
fe3db729
EW
221 w->ww_wstate = 2;
222 break;
7d77e730 223 case 's':
a6833679 224 w->ww_wstate = 4;
78be6843 225 break;
a6833679
EW
226 case 'r':
227 w->ww_wstate = 5;
78be6843 228 break;
fe3db729
EW
229 }
230 break;
231 case 2:
4c1c1e83
EW
232 w->ww_cur.r = w->ww_w.t +
233 (unsigned)(*p++ - ' ') % w->ww_w.nr;
f2a77fe1 234 w->ww_wstate = 3;
fe3db729
EW
235 break;
236 case 3:
4c1c1e83
EW
237 w->ww_cur.c = w->ww_w.l +
238 (unsigned)(*p++ - ' ') % w->ww_w.nc;
fe3db729
EW
239 w->ww_wstate = 0;
240 break;
a6833679
EW
241 case 4:
242 w->ww_modes |= *p++ & wwavailmodes;
243 w->ww_wstate = 0;
244 break;
245 case 5:
246 w->ww_modes &= ~*p++;
247 w->ww_wstate = 0;
248 break;
fe3db729
EW
249 }
250 }
73218728
EW
251 if (hascursor)
252 wwcursor(w, 1);
b1189050
EW
253 wwnwwr++;
254 wwnwwra += n;
255 n = p - savep;
256 wwnwwrc += n;
257 return n;
fe3db729 258}