Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 67dbeee5 2017-10-10 rsc #include <libsec.h>
12 b3994ec5 2003-12-11 devnull #include "dat.h"
13 b3994ec5 2003-12-11 devnull #include "fns.h"
14 b3994ec5 2003-12-11 devnull
15 b3994ec5 2003-12-11 devnull enum
16 b3994ec5 2003-12-11 devnull {
17 b3994ec5 2003-12-11 devnull Ctlsize = 5*12
18 b3994ec5 2003-12-11 devnull };
19 b3994ec5 2003-12-11 devnull
20 b3994ec5 2003-12-11 devnull char Edel[] = "deleted window";
21 b3994ec5 2003-12-11 devnull char Ebadctl[] = "ill-formed control message";
22 b3994ec5 2003-12-11 devnull char Ebadaddr[] = "bad address syntax";
23 b3994ec5 2003-12-11 devnull char Eaddr[] = "address out of range";
24 b3994ec5 2003-12-11 devnull char Einuse[] = "already in use";
25 b3994ec5 2003-12-11 devnull char Ebadevent[] = "bad event syntax";
26 b3994ec5 2003-12-11 devnull extern char Eperm[];
27 b3994ec5 2003-12-11 devnull
28 b3994ec5 2003-12-11 devnull static
29 b3994ec5 2003-12-11 devnull void
30 b3994ec5 2003-12-11 devnull clampaddr(Window *w)
31 b3994ec5 2003-12-11 devnull {
32 b3994ec5 2003-12-11 devnull if(w->addr.q0 < 0)
33 b3994ec5 2003-12-11 devnull w->addr.q0 = 0;
34 b3994ec5 2003-12-11 devnull if(w->addr.q1 < 0)
35 b3994ec5 2003-12-11 devnull w->addr.q1 = 0;
36 b3994ec5 2003-12-11 devnull if(w->addr.q0 > w->body.file->b.nc)
37 b3994ec5 2003-12-11 devnull w->addr.q0 = w->body.file->b.nc;
38 b3994ec5 2003-12-11 devnull if(w->addr.q1 > w->body.file->b.nc)
39 b3994ec5 2003-12-11 devnull w->addr.q1 = w->body.file->b.nc;
40 b3994ec5 2003-12-11 devnull }
41 b3994ec5 2003-12-11 devnull
42 b3994ec5 2003-12-11 devnull void
43 b3994ec5 2003-12-11 devnull xfidctl(void *arg)
44 b3994ec5 2003-12-11 devnull {
45 b3994ec5 2003-12-11 devnull Xfid *x;
46 b3994ec5 2003-12-11 devnull void (*f)(Xfid*);
47 b3994ec5 2003-12-11 devnull
48 b3994ec5 2003-12-11 devnull threadsetname("xfidctlthread");
49 b3994ec5 2003-12-11 devnull x = arg;
50 b3994ec5 2003-12-11 devnull for(;;){
51 be22ae2d 2004-03-26 devnull f = (void(*)(Xfid*))recvp(x->c);
52 b3994ec5 2003-12-11 devnull (*f)(x);
53 b3994ec5 2003-12-11 devnull flushimage(display, 1);
54 b3994ec5 2003-12-11 devnull sendp(cxfidfree, x);
55 b3994ec5 2003-12-11 devnull }
56 b3994ec5 2003-12-11 devnull }
57 b3994ec5 2003-12-11 devnull
58 b3994ec5 2003-12-11 devnull void
59 b3994ec5 2003-12-11 devnull xfidflush(Xfid *x)
60 b3994ec5 2003-12-11 devnull {
61 b3994ec5 2003-12-11 devnull Fcall fc;
62 b3994ec5 2003-12-11 devnull int i, j;
63 b3994ec5 2003-12-11 devnull Window *w;
64 b3994ec5 2003-12-11 devnull Column *c;
65 b3994ec5 2003-12-11 devnull Xfid *wx;
66 b3994ec5 2003-12-11 devnull
67 4a3fb872 2014-04-30 rsc xfidlogflush(x);
68 4a3fb872 2014-04-30 rsc
69 b3994ec5 2003-12-11 devnull /* search windows for matching tag */
70 b3994ec5 2003-12-11 devnull qlock(&row.lk);
71 b3994ec5 2003-12-11 devnull for(j=0; j<row.ncol; j++){
72 b3994ec5 2003-12-11 devnull c = row.col[j];
73 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
74 b3994ec5 2003-12-11 devnull w = c->w[i];
75 b3994ec5 2003-12-11 devnull winlock(w, 'E');
76 b3994ec5 2003-12-11 devnull wx = w->eventx;
77 b3994ec5 2003-12-11 devnull if(wx!=nil && wx->fcall.tag==x->fcall.oldtag){
78 b3994ec5 2003-12-11 devnull w->eventx = nil;
79 b3994ec5 2003-12-11 devnull wx->flushed = TRUE;
80 b3994ec5 2003-12-11 devnull sendp(wx->c, nil);
81 b3994ec5 2003-12-11 devnull winunlock(w);
82 b3994ec5 2003-12-11 devnull goto out;
83 b3994ec5 2003-12-11 devnull }
84 b3994ec5 2003-12-11 devnull winunlock(w);
85 b3994ec5 2003-12-11 devnull }
86 b3994ec5 2003-12-11 devnull }
87 b3994ec5 2003-12-11 devnull out:
88 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
89 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
90 b3994ec5 2003-12-11 devnull }
91 b3994ec5 2003-12-11 devnull
92 b3994ec5 2003-12-11 devnull void
93 b3994ec5 2003-12-11 devnull xfidopen(Xfid *x)
94 b3994ec5 2003-12-11 devnull {
95 b3994ec5 2003-12-11 devnull Fcall fc;
96 b3994ec5 2003-12-11 devnull Window *w;
97 b3994ec5 2003-12-11 devnull Text *t;
98 b3994ec5 2003-12-11 devnull char *s;
99 b3994ec5 2003-12-11 devnull Rune *r;
100 b3994ec5 2003-12-11 devnull int m, n, q, q0, q1;
101 b3994ec5 2003-12-11 devnull
102 b3994ec5 2003-12-11 devnull w = x->f->w;
103 b3994ec5 2003-12-11 devnull t = &w->body;
104 66301756 2006-05-05 devnull q = FILE(x->f->qid);
105 b3994ec5 2003-12-11 devnull if(w){
106 b3994ec5 2003-12-11 devnull winlock(w, 'E');
107 b3994ec5 2003-12-11 devnull switch(q){
108 b3994ec5 2003-12-11 devnull case QWaddr:
109 07494878 2005-01-27 devnull if(w->nopen[q]++ == 0){
110 07494878 2005-01-27 devnull w->addr = range(0, 0);
111 07494878 2005-01-27 devnull w->limit = range(-1,-1);
112 07494878 2005-01-27 devnull }
113 07494878 2005-01-27 devnull break;
114 07494878 2005-01-27 devnull case QWdata:
115 07494878 2005-01-27 devnull case QWxdata:
116 012a8a02 2004-10-22 devnull w->nopen[q]++;
117 b3994ec5 2003-12-11 devnull break;
118 b3994ec5 2003-12-11 devnull case QWevent:
119 b3994ec5 2003-12-11 devnull if(w->nopen[q]++ == 0){
120 b3994ec5 2003-12-11 devnull if(!w->isdir && w->col!=nil){
121 b3994ec5 2003-12-11 devnull w->filemenu = FALSE;
122 b3994ec5 2003-12-11 devnull winsettag(w);
123 b3994ec5 2003-12-11 devnull }
124 b3994ec5 2003-12-11 devnull }
125 b3994ec5 2003-12-11 devnull break;
126 b3994ec5 2003-12-11 devnull case QWrdsel:
127 b3994ec5 2003-12-11 devnull /*
128 b3994ec5 2003-12-11 devnull * Use a temporary file.
129 b3994ec5 2003-12-11 devnull * A pipe would be the obvious, but we can't afford the
130 b3994ec5 2003-12-11 devnull * broken pipe notification. Using the code to read QWbody
131 b3994ec5 2003-12-11 devnull * is n², which should probably also be fixed. Even then,
132 b3994ec5 2003-12-11 devnull * though, we'd need to squirrel away the data in case it's
133 b3994ec5 2003-12-11 devnull * modified during the operation, e.g. by |sort
134 b3994ec5 2003-12-11 devnull */
135 b3994ec5 2003-12-11 devnull if(w->rdselfd > 0){
136 b3994ec5 2003-12-11 devnull winunlock(w);
137 b3994ec5 2003-12-11 devnull respond(x, &fc, Einuse);
138 b3994ec5 2003-12-11 devnull return;
139 b3994ec5 2003-12-11 devnull }
140 b3994ec5 2003-12-11 devnull w->rdselfd = tempfile();
141 b3994ec5 2003-12-11 devnull if(w->rdselfd < 0){
142 b3994ec5 2003-12-11 devnull winunlock(w);
143 b3994ec5 2003-12-11 devnull respond(x, &fc, "can't create temp file");
144 b3994ec5 2003-12-11 devnull return;
145 b3994ec5 2003-12-11 devnull }
146 b3994ec5 2003-12-11 devnull w->nopen[q]++;
147 b3994ec5 2003-12-11 devnull q0 = t->q0;
148 b3994ec5 2003-12-11 devnull q1 = t->q1;
149 b3994ec5 2003-12-11 devnull r = fbufalloc();
150 b3994ec5 2003-12-11 devnull s = fbufalloc();
151 b3994ec5 2003-12-11 devnull while(q0 < q1){
152 b3994ec5 2003-12-11 devnull n = q1 - q0;
153 b3994ec5 2003-12-11 devnull if(n > BUFSIZE/UTFmax)
154 b3994ec5 2003-12-11 devnull n = BUFSIZE/UTFmax;
155 b3994ec5 2003-12-11 devnull bufread(&t->file->b, q0, r, n);
156 b3994ec5 2003-12-11 devnull m = snprint(s, BUFSIZE+1, "%.*S", n, r);
157 b3994ec5 2003-12-11 devnull if(write(w->rdselfd, s, m) != m){
158 b3994ec5 2003-12-11 devnull warning(nil, "can't write temp file for pipe command %r\n");
159 b3994ec5 2003-12-11 devnull break;
160 b3994ec5 2003-12-11 devnull }
161 b3994ec5 2003-12-11 devnull q0 += n;
162 b3994ec5 2003-12-11 devnull }
163 b3994ec5 2003-12-11 devnull fbuffree(s);
164 b3994ec5 2003-12-11 devnull fbuffree(r);
165 b3994ec5 2003-12-11 devnull break;
166 b3994ec5 2003-12-11 devnull case QWwrsel:
167 b3994ec5 2003-12-11 devnull w->nopen[q]++;
168 b3994ec5 2003-12-11 devnull seq++;
169 b3994ec5 2003-12-11 devnull filemark(t->file);
170 b3994ec5 2003-12-11 devnull cut(t, t, nil, FALSE, TRUE, nil, 0);
171 be22ae2d 2004-03-26 devnull w->wrselrange = range(t->q1, t->q1);
172 b3994ec5 2003-12-11 devnull w->nomark = TRUE;
173 b3994ec5 2003-12-11 devnull break;
174 b3994ec5 2003-12-11 devnull case QWeditout:
175 b3994ec5 2003-12-11 devnull if(editing == FALSE){
176 b3994ec5 2003-12-11 devnull winunlock(w);
177 b3994ec5 2003-12-11 devnull respond(x, &fc, Eperm);
178 b3994ec5 2003-12-11 devnull return;
179 b3994ec5 2003-12-11 devnull }
180 66301756 2006-05-05 devnull if(!canqlock(&w->editoutlk)){
181 66301756 2006-05-05 devnull winunlock(w);
182 66301756 2006-05-05 devnull respond(x, &fc, Einuse);
183 66301756 2006-05-05 devnull return;
184 66301756 2006-05-05 devnull }
185 be22ae2d 2004-03-26 devnull w->wrselrange = range(t->q1, t->q1);
186 b3994ec5 2003-12-11 devnull break;
187 b3994ec5 2003-12-11 devnull }
188 b3994ec5 2003-12-11 devnull winunlock(w);
189 b3994ec5 2003-12-11 devnull }
190 66301756 2006-05-05 devnull else{
191 66301756 2006-05-05 devnull switch(q){
192 4a3fb872 2014-04-30 rsc case Qlog:
193 4a3fb872 2014-04-30 rsc xfidlogopen(x);
194 4a3fb872 2014-04-30 rsc break;
195 66301756 2006-05-05 devnull case Qeditout:
196 66301756 2006-05-05 devnull if(!canqlock(&editoutlk)){
197 66301756 2006-05-05 devnull respond(x, &fc, Einuse);
198 66301756 2006-05-05 devnull return;
199 66301756 2006-05-05 devnull }
200 66301756 2006-05-05 devnull break;
201 66301756 2006-05-05 devnull }
202 66301756 2006-05-05 devnull }
203 b3994ec5 2003-12-11 devnull fc.qid = x->f->qid;
204 b3994ec5 2003-12-11 devnull fc.iounit = messagesize-IOHDRSZ;
205 b3994ec5 2003-12-11 devnull x->f->open = TRUE;
206 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
207 b3994ec5 2003-12-11 devnull }
208 b3994ec5 2003-12-11 devnull
209 b3994ec5 2003-12-11 devnull void
210 b3994ec5 2003-12-11 devnull xfidclose(Xfid *x)
211 b3994ec5 2003-12-11 devnull {
212 b3994ec5 2003-12-11 devnull Fcall fc;
213 b3994ec5 2003-12-11 devnull Window *w;
214 b3994ec5 2003-12-11 devnull int q;
215 b3994ec5 2003-12-11 devnull Text *t;
216 b3994ec5 2003-12-11 devnull
217 b3994ec5 2003-12-11 devnull w = x->f->w;
218 b3994ec5 2003-12-11 devnull x->f->busy = FALSE;
219 49588d5d 2003-12-17 devnull x->f->w = nil;
220 b3994ec5 2003-12-11 devnull if(x->f->open == FALSE){
221 b3994ec5 2003-12-11 devnull if(w != nil)
222 b3994ec5 2003-12-11 devnull winclose(w);
223 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
224 b3994ec5 2003-12-11 devnull return;
225 b3994ec5 2003-12-11 devnull }
226 b3994ec5 2003-12-11 devnull
227 66301756 2006-05-05 devnull q = FILE(x->f->qid);
228 b3994ec5 2003-12-11 devnull x->f->open = FALSE;
229 b3994ec5 2003-12-11 devnull if(w){
230 b3994ec5 2003-12-11 devnull winlock(w, 'E');
231 b3994ec5 2003-12-11 devnull switch(q){
232 b3994ec5 2003-12-11 devnull case QWctl:
233 b3994ec5 2003-12-11 devnull if(w->ctlfid!=~0 && w->ctlfid==x->f->fid){
234 b3994ec5 2003-12-11 devnull w->ctlfid = ~0;
235 b3994ec5 2003-12-11 devnull qunlock(&w->ctllock);
236 b3994ec5 2003-12-11 devnull }
237 b3994ec5 2003-12-11 devnull break;
238 b3994ec5 2003-12-11 devnull case QWdata:
239 012a8a02 2004-10-22 devnull case QWxdata:
240 b3994ec5 2003-12-11 devnull w->nomark = FALSE;
241 b3994ec5 2003-12-11 devnull /* fall through */
242 b3994ec5 2003-12-11 devnull case QWaddr:
243 b3994ec5 2003-12-11 devnull case QWevent: /* BUG: do we need to shut down Xfid? */
244 b3994ec5 2003-12-11 devnull if(--w->nopen[q] == 0){
245 012a8a02 2004-10-22 devnull if(q == QWdata || q == QWxdata)
246 b3994ec5 2003-12-11 devnull w->nomark = FALSE;
247 b3994ec5 2003-12-11 devnull if(q==QWevent && !w->isdir && w->col!=nil){
248 b3994ec5 2003-12-11 devnull w->filemenu = TRUE;
249 b3994ec5 2003-12-11 devnull winsettag(w);
250 b3994ec5 2003-12-11 devnull }
251 b3994ec5 2003-12-11 devnull if(q == QWevent){
252 b3994ec5 2003-12-11 devnull free(w->dumpstr);
253 b3994ec5 2003-12-11 devnull free(w->dumpdir);
254 b3994ec5 2003-12-11 devnull w->dumpstr = nil;
255 b3994ec5 2003-12-11 devnull w->dumpdir = nil;
256 b3994ec5 2003-12-11 devnull }
257 b3994ec5 2003-12-11 devnull }
258 b3994ec5 2003-12-11 devnull break;
259 b3994ec5 2003-12-11 devnull case QWrdsel:
260 b3994ec5 2003-12-11 devnull close(w->rdselfd);
261 b3994ec5 2003-12-11 devnull w->rdselfd = 0;
262 b3994ec5 2003-12-11 devnull break;
263 b3994ec5 2003-12-11 devnull case QWwrsel:
264 b3994ec5 2003-12-11 devnull w->nomark = FALSE;
265 b3994ec5 2003-12-11 devnull t = &w->body;
266 b3994ec5 2003-12-11 devnull /* before: only did this if !w->noscroll, but that didn't seem right in practice */
267 b3994ec5 2003-12-11 devnull textshow(t, min(w->wrselrange.q0, t->file->b.nc),
268 b3994ec5 2003-12-11 devnull min(w->wrselrange.q1, t->file->b.nc), 1);
269 b3994ec5 2003-12-11 devnull textscrdraw(t);
270 66301756 2006-05-05 devnull break;
271 66301756 2006-05-05 devnull case QWeditout:
272 66301756 2006-05-05 devnull qunlock(&w->editoutlk);
273 b3994ec5 2003-12-11 devnull break;
274 b3994ec5 2003-12-11 devnull }
275 b3994ec5 2003-12-11 devnull winunlock(w);
276 b3994ec5 2003-12-11 devnull winclose(w);
277 b3994ec5 2003-12-11 devnull }
278 66301756 2006-05-05 devnull else{
279 66301756 2006-05-05 devnull switch(q){
280 66301756 2006-05-05 devnull case Qeditout:
281 66301756 2006-05-05 devnull qunlock(&editoutlk);
282 66301756 2006-05-05 devnull break;
283 66301756 2006-05-05 devnull }
284 66301756 2006-05-05 devnull }
285 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
286 b3994ec5 2003-12-11 devnull }
287 b3994ec5 2003-12-11 devnull
288 b3994ec5 2003-12-11 devnull void
289 b3994ec5 2003-12-11 devnull xfidread(Xfid *x)
290 b3994ec5 2003-12-11 devnull {
291 b3994ec5 2003-12-11 devnull Fcall fc;
292 b3994ec5 2003-12-11 devnull int n, q;
293 b3994ec5 2003-12-11 devnull uint off;
294 b3994ec5 2003-12-11 devnull char *b;
295 627bae9c 2005-01-04 devnull char buf[256];
296 b3994ec5 2003-12-11 devnull Window *w;
297 b3994ec5 2003-12-11 devnull
298 b3994ec5 2003-12-11 devnull q = FILE(x->f->qid);
299 b3994ec5 2003-12-11 devnull w = x->f->w;
300 b3994ec5 2003-12-11 devnull if(w == nil){
301 b3994ec5 2003-12-11 devnull fc.count = 0;
302 b3994ec5 2003-12-11 devnull switch(q){
303 b3994ec5 2003-12-11 devnull case Qcons:
304 b3994ec5 2003-12-11 devnull case Qlabel:
305 b3994ec5 2003-12-11 devnull break;
306 b3994ec5 2003-12-11 devnull case Qindex:
307 b3994ec5 2003-12-11 devnull xfidindexread(x);
308 b3994ec5 2003-12-11 devnull return;
309 4a3fb872 2014-04-30 rsc case Qlog:
310 4a3fb872 2014-04-30 rsc xfidlogread(x);
311 4a3fb872 2014-04-30 rsc return;
312 b3994ec5 2003-12-11 devnull default:
313 b3994ec5 2003-12-11 devnull warning(nil, "unknown qid %d\n", q);
314 b3994ec5 2003-12-11 devnull break;
315 b3994ec5 2003-12-11 devnull }
316 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
317 b3994ec5 2003-12-11 devnull return;
318 b3994ec5 2003-12-11 devnull }
319 b3994ec5 2003-12-11 devnull winlock(w, 'F');
320 b3994ec5 2003-12-11 devnull if(w->col == nil){
321 b3994ec5 2003-12-11 devnull winunlock(w);
322 b3994ec5 2003-12-11 devnull respond(x, &fc, Edel);
323 b3994ec5 2003-12-11 devnull return;
324 b3994ec5 2003-12-11 devnull }
325 b3994ec5 2003-12-11 devnull off = x->fcall.offset;
326 b3994ec5 2003-12-11 devnull switch(q){
327 b3994ec5 2003-12-11 devnull case QWaddr:
328 b3994ec5 2003-12-11 devnull textcommit(&w->body, TRUE);
329 b3994ec5 2003-12-11 devnull clampaddr(w);
330 b3994ec5 2003-12-11 devnull sprint(buf, "%11d %11d ", w->addr.q0, w->addr.q1);
331 b3994ec5 2003-12-11 devnull goto Readbuf;
332 b3994ec5 2003-12-11 devnull
333 b3994ec5 2003-12-11 devnull case QWbody:
334 b3994ec5 2003-12-11 devnull xfidutfread(x, &w->body, w->body.file->b.nc, QWbody);
335 b3994ec5 2003-12-11 devnull break;
336 b3994ec5 2003-12-11 devnull
337 b3994ec5 2003-12-11 devnull case QWctl:
338 627bae9c 2005-01-04 devnull b = winctlprint(w, buf, 1);
339 627bae9c 2005-01-04 devnull goto Readb;
340 b3994ec5 2003-12-11 devnull
341 b3994ec5 2003-12-11 devnull Readbuf:
342 627bae9c 2005-01-04 devnull b = buf;
343 627bae9c 2005-01-04 devnull Readb:
344 627bae9c 2005-01-04 devnull n = strlen(b);
345 b3994ec5 2003-12-11 devnull if(off > n)
346 b3994ec5 2003-12-11 devnull off = n;
347 b3994ec5 2003-12-11 devnull if(off+x->fcall.count > n)
348 b3994ec5 2003-12-11 devnull x->fcall.count = n-off;
349 b3994ec5 2003-12-11 devnull fc.count = x->fcall.count;
350 627bae9c 2005-01-04 devnull fc.data = b+off;
351 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
352 627bae9c 2005-01-04 devnull if(b != buf)
353 627bae9c 2005-01-04 devnull free(b);
354 b3994ec5 2003-12-11 devnull break;
355 b3994ec5 2003-12-11 devnull
356 b3994ec5 2003-12-11 devnull case QWevent:
357 b3994ec5 2003-12-11 devnull xfideventread(x, w);
358 b3994ec5 2003-12-11 devnull break;
359 b3994ec5 2003-12-11 devnull
360 b3994ec5 2003-12-11 devnull case QWdata:
361 b3994ec5 2003-12-11 devnull /* BUG: what should happen if q1 > q0? */
362 b3994ec5 2003-12-11 devnull if(w->addr.q0 > w->body.file->b.nc){
363 b3994ec5 2003-12-11 devnull respond(x, &fc, Eaddr);
364 b3994ec5 2003-12-11 devnull break;
365 b3994ec5 2003-12-11 devnull }
366 b3994ec5 2003-12-11 devnull w->addr.q0 += xfidruneread(x, &w->body, w->addr.q0, w->body.file->b.nc);
367 b3994ec5 2003-12-11 devnull w->addr.q1 = w->addr.q0;
368 b3994ec5 2003-12-11 devnull break;
369 b3994ec5 2003-12-11 devnull
370 012a8a02 2004-10-22 devnull case QWxdata:
371 012a8a02 2004-10-22 devnull /* BUG: what should happen if q1 > q0? */
372 012a8a02 2004-10-22 devnull if(w->addr.q0 > w->body.file->b.nc){
373 012a8a02 2004-10-22 devnull respond(x, &fc, Eaddr);
374 012a8a02 2004-10-22 devnull break;
375 012a8a02 2004-10-22 devnull }
376 012a8a02 2004-10-22 devnull w->addr.q0 += xfidruneread(x, &w->body, w->addr.q0, w->addr.q1);
377 012a8a02 2004-10-22 devnull break;
378 012a8a02 2004-10-22 devnull
379 b3994ec5 2003-12-11 devnull case QWtag:
380 b3994ec5 2003-12-11 devnull xfidutfread(x, &w->tag, w->tag.file->b.nc, QWtag);
381 b3994ec5 2003-12-11 devnull break;
382 b3994ec5 2003-12-11 devnull
383 b3994ec5 2003-12-11 devnull case QWrdsel:
384 b3994ec5 2003-12-11 devnull seek(w->rdselfd, off, 0);
385 b3994ec5 2003-12-11 devnull n = x->fcall.count;
386 b3994ec5 2003-12-11 devnull if(n > BUFSIZE)
387 b3994ec5 2003-12-11 devnull n = BUFSIZE;
388 b3994ec5 2003-12-11 devnull b = fbufalloc();
389 b3994ec5 2003-12-11 devnull n = read(w->rdselfd, b, n);
390 b3994ec5 2003-12-11 devnull if(n < 0){
391 b3994ec5 2003-12-11 devnull respond(x, &fc, "I/O error in temp file");
392 b3994ec5 2003-12-11 devnull break;
393 b3994ec5 2003-12-11 devnull }
394 b3994ec5 2003-12-11 devnull fc.count = n;
395 b3994ec5 2003-12-11 devnull fc.data = b;
396 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
397 b3994ec5 2003-12-11 devnull fbuffree(b);
398 b3994ec5 2003-12-11 devnull break;
399 b3994ec5 2003-12-11 devnull
400 b3994ec5 2003-12-11 devnull default:
401 b3994ec5 2003-12-11 devnull sprint(buf, "unknown qid %d in read", q);
402 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
403 b3994ec5 2003-12-11 devnull }
404 b3994ec5 2003-12-11 devnull winunlock(w);
405 76864eb6 2011-08-02 rsc }
406 76864eb6 2011-08-02 rsc
407 76864eb6 2011-08-02 rsc static int
408 76864eb6 2011-08-02 rsc shouldscroll(Text *t, uint q0, int qid)
409 76864eb6 2011-08-02 rsc {
410 76864eb6 2011-08-02 rsc if(qid == Qcons)
411 76864eb6 2011-08-02 rsc return TRUE;
412 76864eb6 2011-08-02 rsc return t->org <= q0 && q0 <= t->org+t->fr.nchars;
413 b3994ec5 2003-12-11 devnull }
414 b3994ec5 2003-12-11 devnull
415 5b602890 2012-10-05 rsc static Rune*
416 5b602890 2012-10-05 rsc fullrunewrite(Xfid *x, int *inr)
417 5b602890 2012-10-05 rsc {
418 5b602890 2012-10-05 rsc int q, cnt, c, nb, nr;
419 5b602890 2012-10-05 rsc Rune *r;
420 5b602890 2012-10-05 rsc
421 5b602890 2012-10-05 rsc q = x->f->nrpart;
422 5b602890 2012-10-05 rsc cnt = x->fcall.count;
423 5b602890 2012-10-05 rsc if(q > 0){
424 5b602890 2012-10-05 rsc memmove(x->fcall.data+q, x->fcall.data, cnt); /* there's room; see fsysproc */
425 5b602890 2012-10-05 rsc memmove(x->fcall.data, x->f->rpart, q);
426 5b602890 2012-10-05 rsc cnt += q;
427 5b602890 2012-10-05 rsc x->f->nrpart = 0;
428 5b602890 2012-10-05 rsc }
429 5b602890 2012-10-05 rsc r = runemalloc(cnt);
430 5b602890 2012-10-05 rsc cvttorunes(x->fcall.data, cnt-UTFmax, r, &nb, &nr, nil);
431 5b602890 2012-10-05 rsc /* approach end of buffer */
432 5b602890 2012-10-05 rsc while(fullrune(x->fcall.data+nb, cnt-nb)){
433 5b602890 2012-10-05 rsc c = nb;
434 5b602890 2012-10-05 rsc nb += chartorune(&r[nr], x->fcall.data+c);
435 5b602890 2012-10-05 rsc if(r[nr])
436 5b602890 2012-10-05 rsc nr++;
437 5b602890 2012-10-05 rsc }
438 5b602890 2012-10-05 rsc if(nb < cnt){
439 5b602890 2012-10-05 rsc memmove(x->f->rpart, x->fcall.data+nb, cnt-nb);
440 5b602890 2012-10-05 rsc x->f->nrpart = cnt-nb;
441 5b602890 2012-10-05 rsc }
442 5b602890 2012-10-05 rsc *inr = nr;
443 5b602890 2012-10-05 rsc return r;
444 5b602890 2012-10-05 rsc }
445 5b602890 2012-10-05 rsc
446 b3994ec5 2003-12-11 devnull void
447 b3994ec5 2003-12-11 devnull xfidwrite(Xfid *x)
448 b3994ec5 2003-12-11 devnull {
449 b3994ec5 2003-12-11 devnull Fcall fc;
450 5b602890 2012-10-05 rsc int c, qid, nb, nr, eval;
451 b3994ec5 2003-12-11 devnull char buf[64], *err;
452 b3994ec5 2003-12-11 devnull Window *w;
453 b3994ec5 2003-12-11 devnull Rune *r;
454 b3994ec5 2003-12-11 devnull Range a;
455 b3994ec5 2003-12-11 devnull Text *t;
456 b3994ec5 2003-12-11 devnull uint q0, tq0, tq1;
457 b3994ec5 2003-12-11 devnull
458 b3994ec5 2003-12-11 devnull qid = FILE(x->f->qid);
459 b3994ec5 2003-12-11 devnull w = x->f->w;
460 b3994ec5 2003-12-11 devnull if(w){
461 b3994ec5 2003-12-11 devnull c = 'F';
462 b3994ec5 2003-12-11 devnull if(qid==QWtag || qid==QWbody)
463 b3994ec5 2003-12-11 devnull c = 'E';
464 b3994ec5 2003-12-11 devnull winlock(w, c);
465 b3994ec5 2003-12-11 devnull if(w->col == nil){
466 b3994ec5 2003-12-11 devnull winunlock(w);
467 b3994ec5 2003-12-11 devnull respond(x, &fc, Edel);
468 b3994ec5 2003-12-11 devnull return;
469 b3994ec5 2003-12-11 devnull }
470 b3994ec5 2003-12-11 devnull }
471 b3994ec5 2003-12-11 devnull x->fcall.data[x->fcall.count] = 0;
472 b3994ec5 2003-12-11 devnull switch(qid){
473 b3994ec5 2003-12-11 devnull case Qcons:
474 5a8e63b2 2004-02-29 devnull w = errorwin(x->f->mntdir, 'X');
475 b3994ec5 2003-12-11 devnull t=&w->body;
476 b3994ec5 2003-12-11 devnull goto BodyTag;
477 b3994ec5 2003-12-11 devnull
478 b3994ec5 2003-12-11 devnull case Qlabel:
479 b3994ec5 2003-12-11 devnull fc.count = x->fcall.count;
480 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
481 b3994ec5 2003-12-11 devnull break;
482 b3994ec5 2003-12-11 devnull
483 b3994ec5 2003-12-11 devnull case QWaddr:
484 b3994ec5 2003-12-11 devnull x->fcall.data[x->fcall.count] = 0;
485 b3994ec5 2003-12-11 devnull r = bytetorune(x->fcall.data, &nr);
486 b3994ec5 2003-12-11 devnull t = &w->body;
487 b3994ec5 2003-12-11 devnull wincommit(w, t);
488 b3994ec5 2003-12-11 devnull eval = TRUE;
489 012a8a02 2004-10-22 devnull a = address(FALSE, t, w->limit, w->addr, r, 0, nr, rgetc, &eval, (uint*)&nb);
490 b3994ec5 2003-12-11 devnull free(r);
491 b3994ec5 2003-12-11 devnull if(nb < nr){
492 b3994ec5 2003-12-11 devnull respond(x, &fc, Ebadaddr);
493 b3994ec5 2003-12-11 devnull break;
494 b3994ec5 2003-12-11 devnull }
495 b3994ec5 2003-12-11 devnull if(!eval){
496 b3994ec5 2003-12-11 devnull respond(x, &fc, Eaddr);
497 b3994ec5 2003-12-11 devnull break;
498 b3994ec5 2003-12-11 devnull }
499 b3994ec5 2003-12-11 devnull w->addr = a;
500 b3994ec5 2003-12-11 devnull fc.count = x->fcall.count;
501 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
502 b3994ec5 2003-12-11 devnull break;
503 b3994ec5 2003-12-11 devnull
504 b3994ec5 2003-12-11 devnull case Qeditout:
505 b3994ec5 2003-12-11 devnull case QWeditout:
506 5b602890 2012-10-05 rsc r = fullrunewrite(x, &nr);
507 b3994ec5 2003-12-11 devnull if(w)
508 b3994ec5 2003-12-11 devnull err = edittext(w, w->wrselrange.q1, r, nr);
509 b3994ec5 2003-12-11 devnull else
510 b3994ec5 2003-12-11 devnull err = edittext(nil, 0, r, nr);
511 b3994ec5 2003-12-11 devnull free(r);
512 b3994ec5 2003-12-11 devnull if(err != nil){
513 b3994ec5 2003-12-11 devnull respond(x, &fc, err);
514 b3994ec5 2003-12-11 devnull break;
515 b3994ec5 2003-12-11 devnull }
516 b3994ec5 2003-12-11 devnull fc.count = x->fcall.count;
517 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
518 b3994ec5 2003-12-11 devnull break;
519 b3994ec5 2003-12-11 devnull
520 9d01e221 2005-01-30 devnull case QWerrors:
521 9d01e221 2005-01-30 devnull w = errorwinforwin(w);
522 9d01e221 2005-01-30 devnull t = &w->body;
523 9d01e221 2005-01-30 devnull goto BodyTag;
524 9d01e221 2005-01-30 devnull
525 b3994ec5 2003-12-11 devnull case QWbody:
526 b3994ec5 2003-12-11 devnull case QWwrsel:
527 b3994ec5 2003-12-11 devnull t = &w->body;
528 b3994ec5 2003-12-11 devnull goto BodyTag;
529 b3994ec5 2003-12-11 devnull
530 b3994ec5 2003-12-11 devnull case QWctl:
531 b3994ec5 2003-12-11 devnull xfidctlwrite(x, w);
532 b3994ec5 2003-12-11 devnull break;
533 b3994ec5 2003-12-11 devnull
534 b3994ec5 2003-12-11 devnull case QWdata:
535 b3994ec5 2003-12-11 devnull a = w->addr;
536 b3994ec5 2003-12-11 devnull t = &w->body;
537 b3994ec5 2003-12-11 devnull wincommit(w, t);
538 b3994ec5 2003-12-11 devnull if(a.q0>t->file->b.nc || a.q1>t->file->b.nc){
539 b3994ec5 2003-12-11 devnull respond(x, &fc, Eaddr);
540 b3994ec5 2003-12-11 devnull break;
541 b3994ec5 2003-12-11 devnull }
542 b3994ec5 2003-12-11 devnull r = runemalloc(x->fcall.count);
543 b3994ec5 2003-12-11 devnull cvttorunes(x->fcall.data, x->fcall.count, r, &nb, &nr, nil);
544 b3994ec5 2003-12-11 devnull if(w->nomark == FALSE){
545 b3994ec5 2003-12-11 devnull seq++;
546 b3994ec5 2003-12-11 devnull filemark(t->file);
547 b3994ec5 2003-12-11 devnull }
548 b3994ec5 2003-12-11 devnull q0 = a.q0;
549 b3994ec5 2003-12-11 devnull if(a.q1 > q0){
550 b3994ec5 2003-12-11 devnull textdelete(t, q0, a.q1, TRUE);
551 b3994ec5 2003-12-11 devnull w->addr.q1 = q0;
552 b3994ec5 2003-12-11 devnull }
553 b3994ec5 2003-12-11 devnull tq0 = t->q0;
554 b3994ec5 2003-12-11 devnull tq1 = t->q1;
555 b3994ec5 2003-12-11 devnull textinsert(t, q0, r, nr, TRUE);
556 b3994ec5 2003-12-11 devnull if(tq0 >= q0)
557 b3994ec5 2003-12-11 devnull tq0 += nr;
558 b3994ec5 2003-12-11 devnull if(tq1 >= q0)
559 b3994ec5 2003-12-11 devnull tq1 += nr;
560 b3994ec5 2003-12-11 devnull textsetselect(t, tq0, tq1);
561 76864eb6 2011-08-02 rsc if(shouldscroll(t, q0, qid))
562 ba31ab30 2011-04-27 rsc textshow(t, q0+nr, q0+nr, 0);
563 b3994ec5 2003-12-11 devnull textscrdraw(t);
564 b3994ec5 2003-12-11 devnull winsettag(w);
565 b3994ec5 2003-12-11 devnull free(r);
566 b3994ec5 2003-12-11 devnull w->addr.q0 += nr;
567 b3994ec5 2003-12-11 devnull w->addr.q1 = w->addr.q0;
568 b3994ec5 2003-12-11 devnull fc.count = x->fcall.count;
569 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
570 b3994ec5 2003-12-11 devnull break;
571 b3994ec5 2003-12-11 devnull
572 b3994ec5 2003-12-11 devnull case QWevent:
573 b3994ec5 2003-12-11 devnull xfideventwrite(x, w);
574 b3994ec5 2003-12-11 devnull break;
575 b3994ec5 2003-12-11 devnull
576 b3994ec5 2003-12-11 devnull case QWtag:
577 b3994ec5 2003-12-11 devnull t = &w->tag;
578 b3994ec5 2003-12-11 devnull goto BodyTag;
579 b3994ec5 2003-12-11 devnull
580 b3994ec5 2003-12-11 devnull BodyTag:
581 5b602890 2012-10-05 rsc r = fullrunewrite(x, &nr);
582 b3994ec5 2003-12-11 devnull if(nr > 0){
583 b3994ec5 2003-12-11 devnull wincommit(w, t);
584 b3994ec5 2003-12-11 devnull if(qid == QWwrsel){
585 b3994ec5 2003-12-11 devnull q0 = w->wrselrange.q1;
586 b3994ec5 2003-12-11 devnull if(q0 > t->file->b.nc)
587 b3994ec5 2003-12-11 devnull q0 = t->file->b.nc;
588 b3994ec5 2003-12-11 devnull }else
589 b3994ec5 2003-12-11 devnull q0 = t->file->b.nc;
590 b3994ec5 2003-12-11 devnull if(qid == QWtag)
591 b3994ec5 2003-12-11 devnull textinsert(t, q0, r, nr, TRUE);
592 b3994ec5 2003-12-11 devnull else{
593 b3994ec5 2003-12-11 devnull if(w->nomark == FALSE){
594 b3994ec5 2003-12-11 devnull seq++;
595 b3994ec5 2003-12-11 devnull filemark(t->file);
596 b3994ec5 2003-12-11 devnull }
597 b3994ec5 2003-12-11 devnull q0 = textbsinsert(t, q0, r, nr, TRUE, &nr);
598 b3994ec5 2003-12-11 devnull textsetselect(t, t->q0, t->q1); /* insert could leave it somewhere else */
599 76864eb6 2011-08-02 rsc if(qid!=QWwrsel && shouldscroll(t, q0, qid))
600 b3994ec5 2003-12-11 devnull textshow(t, q0+nr, q0+nr, 1);
601 b3994ec5 2003-12-11 devnull textscrdraw(t);
602 b3994ec5 2003-12-11 devnull }
603 b3994ec5 2003-12-11 devnull winsettag(w);
604 b3994ec5 2003-12-11 devnull if(qid == QWwrsel)
605 b3994ec5 2003-12-11 devnull w->wrselrange.q1 += nr;
606 b3994ec5 2003-12-11 devnull free(r);
607 b3994ec5 2003-12-11 devnull }
608 b3994ec5 2003-12-11 devnull fc.count = x->fcall.count;
609 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
610 b3994ec5 2003-12-11 devnull break;
611 b3994ec5 2003-12-11 devnull
612 b3994ec5 2003-12-11 devnull default:
613 b3994ec5 2003-12-11 devnull sprint(buf, "unknown qid %d in write", qid);
614 b3994ec5 2003-12-11 devnull respond(x, &fc, buf);
615 b3994ec5 2003-12-11 devnull break;
616 b3994ec5 2003-12-11 devnull }
617 b3994ec5 2003-12-11 devnull if(w)
618 b3994ec5 2003-12-11 devnull winunlock(w);
619 b3994ec5 2003-12-11 devnull }
620 b3994ec5 2003-12-11 devnull
621 b3994ec5 2003-12-11 devnull void
622 b3994ec5 2003-12-11 devnull xfidctlwrite(Xfid *x, Window *w)
623 b3994ec5 2003-12-11 devnull {
624 b3994ec5 2003-12-11 devnull Fcall fc;
625 b3994ec5 2003-12-11 devnull int i, m, n, nb, nr, nulls;
626 b3994ec5 2003-12-11 devnull Rune *r;
627 b3994ec5 2003-12-11 devnull char *err, *p, *pp, *q, *e;
628 b3994ec5 2003-12-11 devnull int isfbuf, scrdraw, settag;
629 b3994ec5 2003-12-11 devnull Text *t;
630 b3994ec5 2003-12-11 devnull
631 b3994ec5 2003-12-11 devnull err = nil;
632 b3994ec5 2003-12-11 devnull e = x->fcall.data+x->fcall.count;
633 b3994ec5 2003-12-11 devnull scrdraw = FALSE;
634 b3994ec5 2003-12-11 devnull settag = FALSE;
635 b3994ec5 2003-12-11 devnull isfbuf = TRUE;
636 b3994ec5 2003-12-11 devnull if(x->fcall.count < RBUFSIZE)
637 b3994ec5 2003-12-11 devnull r = fbufalloc();
638 b3994ec5 2003-12-11 devnull else{
639 b3994ec5 2003-12-11 devnull isfbuf = FALSE;
640 b3994ec5 2003-12-11 devnull r = emalloc(x->fcall.count*UTFmax+1);
641 b3994ec5 2003-12-11 devnull }
642 b3994ec5 2003-12-11 devnull x->fcall.data[x->fcall.count] = 0;
643 b3994ec5 2003-12-11 devnull textcommit(&w->tag, TRUE);
644 b3994ec5 2003-12-11 devnull for(n=0; n<x->fcall.count; n+=m){
645 b3994ec5 2003-12-11 devnull p = x->fcall.data+n;
646 b3994ec5 2003-12-11 devnull if(strncmp(p, "lock", 4) == 0){ /* make window exclusive use */
647 b3994ec5 2003-12-11 devnull qlock(&w->ctllock);
648 b3994ec5 2003-12-11 devnull w->ctlfid = x->f->fid;
649 b3994ec5 2003-12-11 devnull m = 4;
650 b3994ec5 2003-12-11 devnull }else
651 b3994ec5 2003-12-11 devnull if(strncmp(p, "unlock", 6) == 0){ /* release exclusive use */
652 b3994ec5 2003-12-11 devnull w->ctlfid = ~0;
653 b3994ec5 2003-12-11 devnull qunlock(&w->ctllock);
654 b3994ec5 2003-12-11 devnull m = 6;
655 b3994ec5 2003-12-11 devnull }else
656 b3994ec5 2003-12-11 devnull if(strncmp(p, "clean", 5) == 0){ /* mark window 'clean', seq=0 */
657 b3994ec5 2003-12-11 devnull t = &w->body;
658 b3994ec5 2003-12-11 devnull t->eq0 = ~0;
659 b3994ec5 2003-12-11 devnull filereset(t->file);
660 b3994ec5 2003-12-11 devnull t->file->mod = FALSE;
661 b3994ec5 2003-12-11 devnull w->dirty = FALSE;
662 b3994ec5 2003-12-11 devnull settag = TRUE;
663 b3994ec5 2003-12-11 devnull m = 5;
664 b3994ec5 2003-12-11 devnull }else
665 b3994ec5 2003-12-11 devnull if(strncmp(p, "dirty", 5) == 0){ /* mark window 'dirty' */
666 b3994ec5 2003-12-11 devnull t = &w->body;
667 b3994ec5 2003-12-11 devnull /* doesn't change sequence number, so "Put" won't appear. it shouldn't. */
668 b3994ec5 2003-12-11 devnull t->file->mod = TRUE;
669 b3994ec5 2003-12-11 devnull w->dirty = TRUE;
670 b3994ec5 2003-12-11 devnull settag = TRUE;
671 b3994ec5 2003-12-11 devnull m = 5;
672 b3994ec5 2003-12-11 devnull }else
673 b3994ec5 2003-12-11 devnull if(strncmp(p, "show", 4) == 0){ /* show dot */
674 b3994ec5 2003-12-11 devnull t = &w->body;
675 b3994ec5 2003-12-11 devnull textshow(t, t->q0, t->q1, 1);
676 b3994ec5 2003-12-11 devnull m = 4;
677 b3994ec5 2003-12-11 devnull }else
678 b3994ec5 2003-12-11 devnull if(strncmp(p, "name ", 5) == 0){ /* set file name */
679 b3994ec5 2003-12-11 devnull pp = p+5;
680 b3994ec5 2003-12-11 devnull m = 5;
681 b3994ec5 2003-12-11 devnull q = memchr(pp, '\n', e-pp);
682 b3994ec5 2003-12-11 devnull if(q==nil || q==pp){
683 b3994ec5 2003-12-11 devnull err = Ebadctl;
684 b3994ec5 2003-12-11 devnull break;
685 b3994ec5 2003-12-11 devnull }
686 b3994ec5 2003-12-11 devnull *q = 0;
687 b3994ec5 2003-12-11 devnull nulls = FALSE;
688 b3994ec5 2003-12-11 devnull cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);
689 b3994ec5 2003-12-11 devnull if(nulls){
690 b3994ec5 2003-12-11 devnull err = "nulls in file name";
691 b3994ec5 2003-12-11 devnull break;
692 b3994ec5 2003-12-11 devnull }
693 b3994ec5 2003-12-11 devnull for(i=0; i<nr; i++)
694 b3994ec5 2003-12-11 devnull if(r[i] <= ' '){
695 b3994ec5 2003-12-11 devnull err = "bad character in file name";
696 b3994ec5 2003-12-11 devnull goto out;
697 b3994ec5 2003-12-11 devnull }
698 b3994ec5 2003-12-11 devnull out:
699 b3994ec5 2003-12-11 devnull seq++;
700 b3994ec5 2003-12-11 devnull filemark(w->body.file);
701 b3994ec5 2003-12-11 devnull winsetname(w, r, nr);
702 b3994ec5 2003-12-11 devnull m += (q+1) - pp;
703 b3994ec5 2003-12-11 devnull }else
704 b3994ec5 2003-12-11 devnull if(strncmp(p, "dump ", 5) == 0){ /* set dump string */
705 b3994ec5 2003-12-11 devnull pp = p+5;
706 b3994ec5 2003-12-11 devnull m = 5;
707 b3994ec5 2003-12-11 devnull q = memchr(pp, '\n', e-pp);
708 b3994ec5 2003-12-11 devnull if(q==nil || q==pp){
709 b3994ec5 2003-12-11 devnull err = Ebadctl;
710 b3994ec5 2003-12-11 devnull break;
711 b3994ec5 2003-12-11 devnull }
712 b3994ec5 2003-12-11 devnull *q = 0;
713 b3994ec5 2003-12-11 devnull nulls = FALSE;
714 b3994ec5 2003-12-11 devnull cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);
715 b3994ec5 2003-12-11 devnull if(nulls){
716 b3994ec5 2003-12-11 devnull err = "nulls in dump string";
717 b3994ec5 2003-12-11 devnull break;
718 b3994ec5 2003-12-11 devnull }
719 b3994ec5 2003-12-11 devnull w->dumpstr = runetobyte(r, nr);
720 b3994ec5 2003-12-11 devnull m += (q+1) - pp;
721 b3994ec5 2003-12-11 devnull }else
722 b3994ec5 2003-12-11 devnull if(strncmp(p, "dumpdir ", 8) == 0){ /* set dump directory */
723 b3994ec5 2003-12-11 devnull pp = p+8;
724 b3994ec5 2003-12-11 devnull m = 8;
725 b3994ec5 2003-12-11 devnull q = memchr(pp, '\n', e-pp);
726 b3994ec5 2003-12-11 devnull if(q==nil || q==pp){
727 b3994ec5 2003-12-11 devnull err = Ebadctl;
728 b3994ec5 2003-12-11 devnull break;
729 b3994ec5 2003-12-11 devnull }
730 b3994ec5 2003-12-11 devnull *q = 0;
731 b3994ec5 2003-12-11 devnull nulls = FALSE;
732 b3994ec5 2003-12-11 devnull cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);
733 b3994ec5 2003-12-11 devnull if(nulls){
734 b3994ec5 2003-12-11 devnull err = "nulls in dump directory string";
735 b3994ec5 2003-12-11 devnull break;
736 b3994ec5 2003-12-11 devnull }
737 b3994ec5 2003-12-11 devnull w->dumpdir = runetobyte(r, nr);
738 b3994ec5 2003-12-11 devnull m += (q+1) - pp;
739 b3994ec5 2003-12-11 devnull }else
740 b3994ec5 2003-12-11 devnull if(strncmp(p, "delete", 6) == 0){ /* delete for sure */
741 b3994ec5 2003-12-11 devnull colclose(w->col, w, TRUE);
742 b3994ec5 2003-12-11 devnull m = 6;
743 b3994ec5 2003-12-11 devnull }else
744 b3994ec5 2003-12-11 devnull if(strncmp(p, "del", 3) == 0){ /* delete, but check dirty */
745 b3994ec5 2003-12-11 devnull if(!winclean(w, TRUE)){
746 b3994ec5 2003-12-11 devnull err = "file dirty";
747 b3994ec5 2003-12-11 devnull break;
748 b3994ec5 2003-12-11 devnull }
749 b3994ec5 2003-12-11 devnull colclose(w->col, w, TRUE);
750 b3994ec5 2003-12-11 devnull m = 3;
751 b3994ec5 2003-12-11 devnull }else
752 b3994ec5 2003-12-11 devnull if(strncmp(p, "get", 3) == 0){ /* get file */
753 b3994ec5 2003-12-11 devnull get(&w->body, nil, nil, FALSE, XXX, nil, 0);
754 b3994ec5 2003-12-11 devnull m = 3;
755 b3994ec5 2003-12-11 devnull }else
756 b3994ec5 2003-12-11 devnull if(strncmp(p, "put", 3) == 0){ /* put file */
757 b3994ec5 2003-12-11 devnull put(&w->body, nil, nil, XXX, XXX, nil, 0);
758 b3994ec5 2003-12-11 devnull m = 3;
759 b3994ec5 2003-12-11 devnull }else
760 b3994ec5 2003-12-11 devnull if(strncmp(p, "dot=addr", 8) == 0){ /* set dot */
761 b3994ec5 2003-12-11 devnull textcommit(&w->body, TRUE);
762 b3994ec5 2003-12-11 devnull clampaddr(w);
763 b3994ec5 2003-12-11 devnull w->body.q0 = w->addr.q0;
764 b3994ec5 2003-12-11 devnull w->body.q1 = w->addr.q1;
765 b3994ec5 2003-12-11 devnull textsetselect(&w->body, w->body.q0, w->body.q1);
766 b3994ec5 2003-12-11 devnull settag = TRUE;
767 b3994ec5 2003-12-11 devnull m = 8;
768 b3994ec5 2003-12-11 devnull }else
769 b3994ec5 2003-12-11 devnull if(strncmp(p, "addr=dot", 8) == 0){ /* set addr */
770 b3994ec5 2003-12-11 devnull w->addr.q0 = w->body.q0;
771 b3994ec5 2003-12-11 devnull w->addr.q1 = w->body.q1;
772 b3994ec5 2003-12-11 devnull m = 8;
773 b3994ec5 2003-12-11 devnull }else
774 b3994ec5 2003-12-11 devnull if(strncmp(p, "limit=addr", 10) == 0){ /* set limit */
775 b3994ec5 2003-12-11 devnull textcommit(&w->body, TRUE);
776 b3994ec5 2003-12-11 devnull clampaddr(w);
777 b3994ec5 2003-12-11 devnull w->limit.q0 = w->addr.q0;
778 b3994ec5 2003-12-11 devnull w->limit.q1 = w->addr.q1;
779 b3994ec5 2003-12-11 devnull m = 10;
780 b3994ec5 2003-12-11 devnull }else
781 b3994ec5 2003-12-11 devnull if(strncmp(p, "nomark", 6) == 0){ /* turn off automatic marking */
782 b3994ec5 2003-12-11 devnull w->nomark = TRUE;
783 b3994ec5 2003-12-11 devnull m = 6;
784 b3994ec5 2003-12-11 devnull }else
785 b3994ec5 2003-12-11 devnull if(strncmp(p, "mark", 4) == 0){ /* mark file */
786 b3994ec5 2003-12-11 devnull seq++;
787 b3994ec5 2003-12-11 devnull filemark(w->body.file);
788 b3994ec5 2003-12-11 devnull settag = TRUE;
789 7927fe8f 2008-03-07 rsc m = 4;
790 7927fe8f 2008-03-07 rsc }else
791 7927fe8f 2008-03-07 rsc if(strncmp(p, "nomenu", 6) == 0){ /* turn off automatic menu */
792 7927fe8f 2008-03-07 rsc w->filemenu = FALSE;
793 7927fe8f 2008-03-07 rsc m = 6;
794 7927fe8f 2008-03-07 rsc }else
795 7927fe8f 2008-03-07 rsc if(strncmp(p, "menu", 4) == 0){ /* enable automatic menu */
796 7927fe8f 2008-03-07 rsc w->filemenu = TRUE;
797 b3994ec5 2003-12-11 devnull m = 4;
798 b3994ec5 2003-12-11 devnull }else
799 b3994ec5 2003-12-11 devnull if(strncmp(p, "cleartag", 8) == 0){ /* wipe tag right of bar */
800 b3994ec5 2003-12-11 devnull wincleartag(w);
801 b3994ec5 2003-12-11 devnull settag = TRUE;
802 b3994ec5 2003-12-11 devnull m = 8;
803 b3994ec5 2003-12-11 devnull }else{
804 b3994ec5 2003-12-11 devnull err = Ebadctl;
805 b3994ec5 2003-12-11 devnull break;
806 b3994ec5 2003-12-11 devnull }
807 b3994ec5 2003-12-11 devnull while(p[m] == '\n')
808 b3994ec5 2003-12-11 devnull m++;
809 b3994ec5 2003-12-11 devnull }
810 b3994ec5 2003-12-11 devnull
811 b3994ec5 2003-12-11 devnull if(isfbuf)
812 b3994ec5 2003-12-11 devnull fbuffree(r);
813 b3994ec5 2003-12-11 devnull else
814 b3994ec5 2003-12-11 devnull free(r);
815 b3994ec5 2003-12-11 devnull if(err)
816 b3994ec5 2003-12-11 devnull n = 0;
817 b3994ec5 2003-12-11 devnull fc.count = n;
818 b3994ec5 2003-12-11 devnull respond(x, &fc, err);
819 b3994ec5 2003-12-11 devnull if(settag)
820 b3994ec5 2003-12-11 devnull winsettag(w);
821 b3994ec5 2003-12-11 devnull if(scrdraw)
822 b3994ec5 2003-12-11 devnull textscrdraw(&w->body);
823 b3994ec5 2003-12-11 devnull }
824 b3994ec5 2003-12-11 devnull
825 b3994ec5 2003-12-11 devnull void
826 b3994ec5 2003-12-11 devnull xfideventwrite(Xfid *x, Window *w)
827 b3994ec5 2003-12-11 devnull {
828 b3994ec5 2003-12-11 devnull Fcall fc;
829 b3994ec5 2003-12-11 devnull int m, n;
830 b3994ec5 2003-12-11 devnull Rune *r;
831 b3994ec5 2003-12-11 devnull char *err, *p, *q;
832 b3994ec5 2003-12-11 devnull int isfbuf;
833 b3994ec5 2003-12-11 devnull Text *t;
834 b3994ec5 2003-12-11 devnull int c;
835 b3994ec5 2003-12-11 devnull uint q0, q1;
836 b3994ec5 2003-12-11 devnull
837 b3994ec5 2003-12-11 devnull err = nil;
838 b3994ec5 2003-12-11 devnull isfbuf = TRUE;
839 b3994ec5 2003-12-11 devnull if(x->fcall.count < RBUFSIZE)
840 b3994ec5 2003-12-11 devnull r = fbufalloc();
841 b3994ec5 2003-12-11 devnull else{
842 b3994ec5 2003-12-11 devnull isfbuf = FALSE;
843 b3994ec5 2003-12-11 devnull r = emalloc(x->fcall.count*UTFmax+1);
844 b3994ec5 2003-12-11 devnull }
845 b3994ec5 2003-12-11 devnull for(n=0; n<x->fcall.count; n+=m){
846 b3994ec5 2003-12-11 devnull p = x->fcall.data+n;
847 b3994ec5 2003-12-11 devnull w->owner = *p++; /* disgusting */
848 b3994ec5 2003-12-11 devnull c = *p++;
849 b3994ec5 2003-12-11 devnull while(*p == ' ')
850 b3994ec5 2003-12-11 devnull p++;
851 b3994ec5 2003-12-11 devnull q0 = strtoul(p, &q, 10);
852 b3994ec5 2003-12-11 devnull if(q == p)
853 b3994ec5 2003-12-11 devnull goto Rescue;
854 b3994ec5 2003-12-11 devnull p = q;
855 b3994ec5 2003-12-11 devnull while(*p == ' ')
856 b3994ec5 2003-12-11 devnull p++;
857 b3994ec5 2003-12-11 devnull q1 = strtoul(p, &q, 10);
858 b3994ec5 2003-12-11 devnull if(q == p)
859 b3994ec5 2003-12-11 devnull goto Rescue;
860 b3994ec5 2003-12-11 devnull p = q;
861 b3994ec5 2003-12-11 devnull while(*p == ' ')
862 b3994ec5 2003-12-11 devnull p++;
863 b3994ec5 2003-12-11 devnull if(*p++ != '\n')
864 b3994ec5 2003-12-11 devnull goto Rescue;
865 b3994ec5 2003-12-11 devnull m = p-(x->fcall.data+n);
866 b3994ec5 2003-12-11 devnull if('a'<=c && c<='z')
867 b3994ec5 2003-12-11 devnull t = &w->tag;
868 b3994ec5 2003-12-11 devnull else if('A'<=c && c<='Z')
869 b3994ec5 2003-12-11 devnull t = &w->body;
870 b3994ec5 2003-12-11 devnull else
871 b3994ec5 2003-12-11 devnull goto Rescue;
872 b3994ec5 2003-12-11 devnull if(q0>t->file->b.nc || q1>t->file->b.nc || q0>q1)
873 b3994ec5 2003-12-11 devnull goto Rescue;
874 b3994ec5 2003-12-11 devnull
875 b3994ec5 2003-12-11 devnull qlock(&row.lk); /* just like mousethread */
876 b3994ec5 2003-12-11 devnull switch(c){
877 b3994ec5 2003-12-11 devnull case 'x':
878 b3994ec5 2003-12-11 devnull case 'X':
879 b3994ec5 2003-12-11 devnull execute(t, q0, q1, TRUE, nil);
880 b3994ec5 2003-12-11 devnull break;
881 b3994ec5 2003-12-11 devnull case 'l':
882 b3994ec5 2003-12-11 devnull case 'L':
883 b3994ec5 2003-12-11 devnull look3(t, q0, q1, TRUE);
884 b3994ec5 2003-12-11 devnull break;
885 b3994ec5 2003-12-11 devnull default:
886 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
887 b3994ec5 2003-12-11 devnull goto Rescue;
888 b3994ec5 2003-12-11 devnull }
889 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
890 b3994ec5 2003-12-11 devnull
891 b3994ec5 2003-12-11 devnull }
892 b3994ec5 2003-12-11 devnull
893 b3994ec5 2003-12-11 devnull Out:
894 b3994ec5 2003-12-11 devnull if(isfbuf)
895 b3994ec5 2003-12-11 devnull fbuffree(r);
896 b3994ec5 2003-12-11 devnull else
897 b3994ec5 2003-12-11 devnull free(r);
898 b3994ec5 2003-12-11 devnull if(err)
899 b3994ec5 2003-12-11 devnull n = 0;
900 b3994ec5 2003-12-11 devnull fc.count = n;
901 b3994ec5 2003-12-11 devnull respond(x, &fc, err);
902 b3994ec5 2003-12-11 devnull return;
903 b3994ec5 2003-12-11 devnull
904 b3994ec5 2003-12-11 devnull Rescue:
905 b3994ec5 2003-12-11 devnull err = Ebadevent;
906 b3994ec5 2003-12-11 devnull goto Out;
907 b3994ec5 2003-12-11 devnull }
908 b3994ec5 2003-12-11 devnull
909 b3994ec5 2003-12-11 devnull void
910 b3994ec5 2003-12-11 devnull xfidutfread(Xfid *x, Text *t, uint q1, int qid)
911 b3994ec5 2003-12-11 devnull {
912 b3994ec5 2003-12-11 devnull Fcall fc;
913 b3994ec5 2003-12-11 devnull Window *w;
914 b3994ec5 2003-12-11 devnull Rune *r;
915 b3994ec5 2003-12-11 devnull char *b, *b1;
916 b3994ec5 2003-12-11 devnull uint q, off, boff;
917 b3994ec5 2003-12-11 devnull int m, n, nr, nb;
918 b3994ec5 2003-12-11 devnull
919 b3994ec5 2003-12-11 devnull w = t->w;
920 b3994ec5 2003-12-11 devnull wincommit(w, t);
921 b3994ec5 2003-12-11 devnull off = x->fcall.offset;
922 b3994ec5 2003-12-11 devnull r = fbufalloc();
923 b3994ec5 2003-12-11 devnull b = fbufalloc();
924 b3994ec5 2003-12-11 devnull b1 = fbufalloc();
925 b3994ec5 2003-12-11 devnull n = 0;
926 b3994ec5 2003-12-11 devnull if(qid==w->utflastqid && off>=w->utflastboff && w->utflastq<=q1){
927 b3994ec5 2003-12-11 devnull boff = w->utflastboff;
928 b3994ec5 2003-12-11 devnull q = w->utflastq;
929 b3994ec5 2003-12-11 devnull }else{
930 b3994ec5 2003-12-11 devnull /* BUG: stupid code: scan from beginning */
931 b3994ec5 2003-12-11 devnull boff = 0;
932 b3994ec5 2003-12-11 devnull q = 0;
933 b3994ec5 2003-12-11 devnull }
934 b3994ec5 2003-12-11 devnull w->utflastqid = qid;
935 b3994ec5 2003-12-11 devnull while(q<q1 && n<x->fcall.count){
936 b3994ec5 2003-12-11 devnull /*
937 b3994ec5 2003-12-11 devnull * Updating here avoids partial rune problem: we're always on a
938 b3994ec5 2003-12-11 devnull * char boundary. The cost is we will usually do one more read
939 b3994ec5 2003-12-11 devnull * than we really need, but that's better than being n^2.
940 b3994ec5 2003-12-11 devnull */
941 b3994ec5 2003-12-11 devnull w->utflastboff = boff;
942 b3994ec5 2003-12-11 devnull w->utflastq = q;
943 b3994ec5 2003-12-11 devnull nr = q1-q;
944 b3994ec5 2003-12-11 devnull if(nr > BUFSIZE/UTFmax)
945 b3994ec5 2003-12-11 devnull nr = BUFSIZE/UTFmax;
946 b3994ec5 2003-12-11 devnull bufread(&t->file->b, q, r, nr);
947 b3994ec5 2003-12-11 devnull nb = snprint(b, BUFSIZE+1, "%.*S", nr, r);
948 b3994ec5 2003-12-11 devnull if(boff >= off){
949 b3994ec5 2003-12-11 devnull m = nb;
950 b3994ec5 2003-12-11 devnull if(boff+m > off+x->fcall.count)
951 b3994ec5 2003-12-11 devnull m = off+x->fcall.count - boff;
952 b3994ec5 2003-12-11 devnull memmove(b1+n, b, m);
953 b3994ec5 2003-12-11 devnull n += m;
954 b3994ec5 2003-12-11 devnull }else if(boff+nb > off){
955 b3994ec5 2003-12-11 devnull if(n != 0)
956 b3994ec5 2003-12-11 devnull error("bad count in utfrune");
957 b3994ec5 2003-12-11 devnull m = nb - (off-boff);
958 b3994ec5 2003-12-11 devnull if(m > x->fcall.count)
959 b3994ec5 2003-12-11 devnull m = x->fcall.count;
960 b3994ec5 2003-12-11 devnull memmove(b1, b+(off-boff), m);
961 b3994ec5 2003-12-11 devnull n += m;
962 b3994ec5 2003-12-11 devnull }
963 b3994ec5 2003-12-11 devnull boff += nb;
964 b3994ec5 2003-12-11 devnull q += nr;
965 b3994ec5 2003-12-11 devnull }
966 b3994ec5 2003-12-11 devnull fbuffree(r);
967 b3994ec5 2003-12-11 devnull fbuffree(b);
968 b3994ec5 2003-12-11 devnull fc.count = n;
969 b3994ec5 2003-12-11 devnull fc.data = b1;
970 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
971 b3994ec5 2003-12-11 devnull fbuffree(b1);
972 b3994ec5 2003-12-11 devnull }
973 b3994ec5 2003-12-11 devnull
974 b3994ec5 2003-12-11 devnull int
975 b3994ec5 2003-12-11 devnull xfidruneread(Xfid *x, Text *t, uint q0, uint q1)
976 b3994ec5 2003-12-11 devnull {
977 b3994ec5 2003-12-11 devnull Fcall fc;
978 b3994ec5 2003-12-11 devnull Window *w;
979 b3994ec5 2003-12-11 devnull Rune *r, junk;
980 b3994ec5 2003-12-11 devnull char *b, *b1;
981 b3994ec5 2003-12-11 devnull uint q, boff;
982 b3994ec5 2003-12-11 devnull int i, rw, m, n, nr, nb;
983 b3994ec5 2003-12-11 devnull
984 b3994ec5 2003-12-11 devnull w = t->w;
985 b3994ec5 2003-12-11 devnull wincommit(w, t);
986 b3994ec5 2003-12-11 devnull r = fbufalloc();
987 b3994ec5 2003-12-11 devnull b = fbufalloc();
988 b3994ec5 2003-12-11 devnull b1 = fbufalloc();
989 b3994ec5 2003-12-11 devnull n = 0;
990 b3994ec5 2003-12-11 devnull q = q0;
991 b3994ec5 2003-12-11 devnull boff = 0;
992 b3994ec5 2003-12-11 devnull while(q<q1 && n<x->fcall.count){
993 b3994ec5 2003-12-11 devnull nr = q1-q;
994 b3994ec5 2003-12-11 devnull if(nr > BUFSIZE/UTFmax)
995 b3994ec5 2003-12-11 devnull nr = BUFSIZE/UTFmax;
996 b3994ec5 2003-12-11 devnull bufread(&t->file->b, q, r, nr);
997 b3994ec5 2003-12-11 devnull nb = snprint(b, BUFSIZE+1, "%.*S", nr, r);
998 b3994ec5 2003-12-11 devnull m = nb;
999 b3994ec5 2003-12-11 devnull if(boff+m > x->fcall.count){
1000 b3994ec5 2003-12-11 devnull i = x->fcall.count - boff;
1001 b3994ec5 2003-12-11 devnull /* copy whole runes only */
1002 b3994ec5 2003-12-11 devnull m = 0;
1003 b3994ec5 2003-12-11 devnull nr = 0;
1004 b3994ec5 2003-12-11 devnull while(m < i){
1005 b3994ec5 2003-12-11 devnull rw = chartorune(&junk, b+m);
1006 b3994ec5 2003-12-11 devnull if(m+rw > i)
1007 b3994ec5 2003-12-11 devnull break;
1008 b3994ec5 2003-12-11 devnull m += rw;
1009 b3994ec5 2003-12-11 devnull nr++;
1010 b3994ec5 2003-12-11 devnull }
1011 b3994ec5 2003-12-11 devnull if(m == 0)
1012 b3994ec5 2003-12-11 devnull break;
1013 b3994ec5 2003-12-11 devnull }
1014 b3994ec5 2003-12-11 devnull memmove(b1+n, b, m);
1015 b3994ec5 2003-12-11 devnull n += m;
1016 b3994ec5 2003-12-11 devnull boff += nb;
1017 b3994ec5 2003-12-11 devnull q += nr;
1018 b3994ec5 2003-12-11 devnull }
1019 b3994ec5 2003-12-11 devnull fbuffree(r);
1020 b3994ec5 2003-12-11 devnull fbuffree(b);
1021 b3994ec5 2003-12-11 devnull fc.count = n;
1022 b3994ec5 2003-12-11 devnull fc.data = b1;
1023 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
1024 b3994ec5 2003-12-11 devnull fbuffree(b1);
1025 b3994ec5 2003-12-11 devnull return q-q0;
1026 b3994ec5 2003-12-11 devnull }
1027 b3994ec5 2003-12-11 devnull
1028 b3994ec5 2003-12-11 devnull void
1029 b3994ec5 2003-12-11 devnull xfideventread(Xfid *x, Window *w)
1030 b3994ec5 2003-12-11 devnull {
1031 b3994ec5 2003-12-11 devnull Fcall fc;
1032 b3994ec5 2003-12-11 devnull int i, n;
1033 b3994ec5 2003-12-11 devnull
1034 b3994ec5 2003-12-11 devnull i = 0;
1035 b3994ec5 2003-12-11 devnull x->flushed = FALSE;
1036 b3994ec5 2003-12-11 devnull while(w->nevents == 0){
1037 b3994ec5 2003-12-11 devnull if(i){
1038 b3994ec5 2003-12-11 devnull if(!x->flushed)
1039 b3994ec5 2003-12-11 devnull respond(x, &fc, "window shut down");
1040 b3994ec5 2003-12-11 devnull return;
1041 b3994ec5 2003-12-11 devnull }
1042 b3994ec5 2003-12-11 devnull w->eventx = x;
1043 b3994ec5 2003-12-11 devnull winunlock(w);
1044 b3994ec5 2003-12-11 devnull recvp(x->c);
1045 b3994ec5 2003-12-11 devnull winlock(w, 'F');
1046 b3994ec5 2003-12-11 devnull i++;
1047 b3994ec5 2003-12-11 devnull }
1048 b3994ec5 2003-12-11 devnull
1049 b3994ec5 2003-12-11 devnull n = w->nevents;
1050 b3994ec5 2003-12-11 devnull if(n > x->fcall.count)
1051 b3994ec5 2003-12-11 devnull n = x->fcall.count;
1052 b3994ec5 2003-12-11 devnull fc.count = n;
1053 b3994ec5 2003-12-11 devnull fc.data = w->events;
1054 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
1055 b3994ec5 2003-12-11 devnull w->nevents -= n;
1056 95409400 2006-02-21 devnull if(w->nevents){
1057 95409400 2006-02-21 devnull memmove(w->events, w->events+n, w->nevents);
1058 95409400 2006-02-21 devnull w->events = erealloc(w->events, w->nevents);
1059 95409400 2006-02-21 devnull }else{
1060 95409400 2006-02-21 devnull free(w->events);
1061 95409400 2006-02-21 devnull w->events = nil;
1062 95409400 2006-02-21 devnull }
1063 b3994ec5 2003-12-11 devnull }
1064 b3994ec5 2003-12-11 devnull
1065 b3994ec5 2003-12-11 devnull void
1066 b3994ec5 2003-12-11 devnull xfidindexread(Xfid *x)
1067 b3994ec5 2003-12-11 devnull {
1068 b3994ec5 2003-12-11 devnull Fcall fc;
1069 b3994ec5 2003-12-11 devnull int i, j, m, n, nmax, isbuf, cnt, off;
1070 b3994ec5 2003-12-11 devnull Window *w;
1071 b3994ec5 2003-12-11 devnull char *b;
1072 b3994ec5 2003-12-11 devnull Rune *r;
1073 b3994ec5 2003-12-11 devnull Column *c;
1074 b3994ec5 2003-12-11 devnull
1075 b3994ec5 2003-12-11 devnull qlock(&row.lk);
1076 b3994ec5 2003-12-11 devnull nmax = 0;
1077 b3994ec5 2003-12-11 devnull for(j=0; j<row.ncol; j++){
1078 b3994ec5 2003-12-11 devnull c = row.col[j];
1079 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
1080 b3994ec5 2003-12-11 devnull w = c->w[i];
1081 b3994ec5 2003-12-11 devnull nmax += Ctlsize + w->tag.file->b.nc*UTFmax + 1;
1082 b3994ec5 2003-12-11 devnull }
1083 b3994ec5 2003-12-11 devnull }
1084 b3994ec5 2003-12-11 devnull nmax++;
1085 b3994ec5 2003-12-11 devnull isbuf = (nmax<=RBUFSIZE);
1086 b3994ec5 2003-12-11 devnull if(isbuf)
1087 b3994ec5 2003-12-11 devnull b = (char*)x->buf;
1088 b3994ec5 2003-12-11 devnull else
1089 b3994ec5 2003-12-11 devnull b = emalloc(nmax);
1090 b3994ec5 2003-12-11 devnull r = fbufalloc();
1091 b3994ec5 2003-12-11 devnull n = 0;
1092 b3994ec5 2003-12-11 devnull for(j=0; j<row.ncol; j++){
1093 b3994ec5 2003-12-11 devnull c = row.col[j];
1094 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
1095 b3994ec5 2003-12-11 devnull w = c->w[i];
1096 b3994ec5 2003-12-11 devnull /* only show the currently active window of a set */
1097 b3994ec5 2003-12-11 devnull if(w->body.file->curtext != &w->body)
1098 b3994ec5 2003-12-11 devnull continue;
1099 b3994ec5 2003-12-11 devnull winctlprint(w, b+n, 0);
1100 b3994ec5 2003-12-11 devnull n += Ctlsize;
1101 b3994ec5 2003-12-11 devnull m = min(RBUFSIZE, w->tag.file->b.nc);
1102 b3994ec5 2003-12-11 devnull bufread(&w->tag.file->b, 0, r, m);
1103 b3994ec5 2003-12-11 devnull m = n + snprint(b+n, nmax-n-1, "%.*S", m, r);
1104 b3994ec5 2003-12-11 devnull while(n<m && b[n]!='\n')
1105 b3994ec5 2003-12-11 devnull n++;
1106 b3994ec5 2003-12-11 devnull b[n++] = '\n';
1107 b3994ec5 2003-12-11 devnull }
1108 b3994ec5 2003-12-11 devnull }
1109 b3994ec5 2003-12-11 devnull qunlock(&row.lk);
1110 b3994ec5 2003-12-11 devnull off = x->fcall.offset;
1111 b3994ec5 2003-12-11 devnull cnt = x->fcall.count;
1112 b3994ec5 2003-12-11 devnull if(off > n)
1113 b3994ec5 2003-12-11 devnull off = n;
1114 b3994ec5 2003-12-11 devnull if(off+cnt > n)
1115 b3994ec5 2003-12-11 devnull cnt = n-off;
1116 b3994ec5 2003-12-11 devnull fc.count = cnt;
1117 b3994ec5 2003-12-11 devnull memmove(r, b+off, cnt);
1118 b3994ec5 2003-12-11 devnull fc.data = (char*)r;
1119 b3994ec5 2003-12-11 devnull if(!isbuf)
1120 b3994ec5 2003-12-11 devnull free(b);
1121 b3994ec5 2003-12-11 devnull respond(x, &fc, nil);
1122 b3994ec5 2003-12-11 devnull fbuffree(r);
1123 b3994ec5 2003-12-11 devnull }