1 9f1fdc12 2005-10-29 devnull #include <u.h>
2 9f1fdc12 2005-10-29 devnull #include <libc.h>
3 9f1fdc12 2005-10-29 devnull #include <bio.h>
4 9f1fdc12 2005-10-29 devnull #include <thread.h>
5 9f1fdc12 2005-10-29 devnull #include <plumb.h>
6 3f8c36d6 2006-02-09 devnull #include <9pclient.h>
7 9f1fdc12 2005-10-29 devnull #include "dat.h"
10 9f1fdc12 2005-10-29 devnull newwindow(void)
12 9f1fdc12 2005-10-29 devnull char buf[12];
13 9f1fdc12 2005-10-29 devnull Window *w;
15 9f1fdc12 2005-10-29 devnull w = emalloc(sizeof(Window));
16 9f1fdc12 2005-10-29 devnull w->ctl = fsopen(acmefs, "new/ctl", ORDWR|OCEXEC);
17 3f8c36d6 2006-02-09 devnull if(w->ctl == nil || fsread(w->ctl, buf, 12)!=12)
18 9f1fdc12 2005-10-29 devnull error("can't open window ctl file: %r");
20 9f1fdc12 2005-10-29 devnull ctlprint(w->ctl, "noscroll\n");
21 9f1fdc12 2005-10-29 devnull w->id = atoi(buf);
22 3f8c36d6 2006-02-09 devnull w->event = winopenfile(w, "event");
23 9f1fdc12 2005-10-29 devnull w->addr = nil; /* will be opened when needed */
24 9f1fdc12 2005-10-29 devnull w->body = nil;
25 9f1fdc12 2005-10-29 devnull w->data = nil;
26 9f1fdc12 2005-10-29 devnull w->cevent = chancreate(sizeof(Event*), 0);
27 880ab2f1 2006-02-15 devnull w->ref = 1;
28 9f1fdc12 2005-10-29 devnull return w;
32 880ab2f1 2006-02-15 devnull winincref(Window *w)
34 880ab2f1 2006-02-15 devnull qlock(&w->lk);
35 880ab2f1 2006-02-15 devnull ++w->ref;
36 880ab2f1 2006-02-15 devnull qunlock(&w->lk);
40 880ab2f1 2006-02-15 devnull windecref(Window *w)
42 880ab2f1 2006-02-15 devnull qlock(&w->lk);
43 880ab2f1 2006-02-15 devnull if(--w->ref > 0){
44 880ab2f1 2006-02-15 devnull qunlock(&w->lk);
47 880ab2f1 2006-02-15 devnull fsclose(w->event);
48 880ab2f1 2006-02-15 devnull chanfree(w->cevent);
53 9f1fdc12 2005-10-29 devnull winsetdump(Window *w, char *dir, char *cmd)
55 9f1fdc12 2005-10-29 devnull if(dir != nil)
56 9f1fdc12 2005-10-29 devnull ctlprint(w->ctl, "dumpdir %s\n", dir);
57 9f1fdc12 2005-10-29 devnull if(cmd != nil)
58 9f1fdc12 2005-10-29 devnull ctlprint(w->ctl, "dump %s\n", cmd);
62 9f1fdc12 2005-10-29 devnull wineventproc(void *v)
64 9f1fdc12 2005-10-29 devnull Window *w;
68 9f1fdc12 2005-10-29 devnull for(i=0; ; i++){
69 9f1fdc12 2005-10-29 devnull if(i >= NEVENT)
71 9f1fdc12 2005-10-29 devnull wingetevent(w, &w->e[i]);
72 9f1fdc12 2005-10-29 devnull sendp(w->cevent, &w->e[i]);
76 9f1fdc12 2005-10-29 devnull static CFid*
77 3f8c36d6 2006-02-09 devnull winopenfile1(Window *w, char *f, int m)
79 9f1fdc12 2005-10-29 devnull char buf[64];
80 9f1fdc12 2005-10-29 devnull CFid* fd;
82 9f1fdc12 2005-10-29 devnull sprint(buf, "%d/%s", w->id, f);
83 9f1fdc12 2005-10-29 devnull fd = fsopen(acmefs, buf, m|OCEXEC);
84 9f1fdc12 2005-10-29 devnull if(fd == nil)
85 9f1fdc12 2005-10-29 devnull error("can't open window file %s: %r", f);
86 9f1fdc12 2005-10-29 devnull return fd;
90 9f1fdc12 2005-10-29 devnull winopenfile(Window *w, char *f)
92 9f1fdc12 2005-10-29 devnull return winopenfile1(w, f, ORDWR);
96 9f1fdc12 2005-10-29 devnull wintagwrite(Window *w, char *s, int n)
98 9f1fdc12 2005-10-29 devnull CFid* fid;
100 3f8c36d6 2006-02-09 devnull fid = winopenfile(w, "tag");
101 9f1fdc12 2005-10-29 devnull if(fswrite(fid, s, n) != n)
102 9f1fdc12 2005-10-29 devnull error("tag write: %r");
103 9f1fdc12 2005-10-29 devnull fsclose(fid);
107 9f1fdc12 2005-10-29 devnull winname(Window *w, char *s)
109 9f1fdc12 2005-10-29 devnull ctlprint(w->ctl, "name %s\n", s);
113 9f1fdc12 2005-10-29 devnull winopenbody(Window *w, int mode)
115 9f1fdc12 2005-10-29 devnull char buf[256];
116 9f1fdc12 2005-10-29 devnull CFid* fid;
118 9f1fdc12 2005-10-29 devnull sprint(buf, "%d/body", w->id);
119 3f8c36d6 2006-02-09 devnull fid = fsopen(acmefs, buf, mode|OCEXEC);
120 3f8c36d6 2006-02-09 devnull w->body = fid;
121 9f1fdc12 2005-10-29 devnull if(w->body == nil)
122 9f1fdc12 2005-10-29 devnull error("can't open window body file: %r");
126 9f1fdc12 2005-10-29 devnull winclosebody(Window *w)
128 9f1fdc12 2005-10-29 devnull if(w->body != nil){
129 9f1fdc12 2005-10-29 devnull fsclose(w->body);
130 9f1fdc12 2005-10-29 devnull w->body = nil;
135 9f1fdc12 2005-10-29 devnull winwritebody(Window *w, char *s, int n)
137 9f1fdc12 2005-10-29 devnull if(w->body == nil)
138 9f1fdc12 2005-10-29 devnull winopenbody(w, OWRITE);
139 9f1fdc12 2005-10-29 devnull if(fswrite(w->body, s, n) != n)
140 9f1fdc12 2005-10-29 devnull error("write error to window: %r");
144 9f1fdc12 2005-10-29 devnull wingetec(Window *w)
146 9f1fdc12 2005-10-29 devnull if(w->nbuf == 0){
147 9f1fdc12 2005-10-29 devnull w->nbuf = fsread(w->event, w->buf, sizeof w->buf);
148 9f1fdc12 2005-10-29 devnull if(w->nbuf <= 0){
149 9f1fdc12 2005-10-29 devnull /* probably because window has exited, and only called by wineventproc, so just shut down */
150 880ab2f1 2006-02-15 devnull windecref(w);
151 9f1fdc12 2005-10-29 devnull threadexits(nil);
153 9f1fdc12 2005-10-29 devnull w->bufp = w->buf;
155 9f1fdc12 2005-10-29 devnull w->nbuf--;
156 9f1fdc12 2005-10-29 devnull return *w->bufp++;
160 9f1fdc12 2005-10-29 devnull wingeten(Window *w)
162 9f1fdc12 2005-10-29 devnull int n, c;
165 9f1fdc12 2005-10-29 devnull while('0'<=(c=wingetec(w)) && c<='9')
166 9f1fdc12 2005-10-29 devnull n = n*10+(c-'0');
167 9f1fdc12 2005-10-29 devnull if(c != ' ')
168 9f1fdc12 2005-10-29 devnull error("event number syntax");
169 9f1fdc12 2005-10-29 devnull return n;
173 9f1fdc12 2005-10-29 devnull wingeter(Window *w, char *buf, int *nb)
178 9f1fdc12 2005-10-29 devnull r = wingetec(w);
179 9f1fdc12 2005-10-29 devnull buf[0] = r;
181 9f1fdc12 2005-10-29 devnull if(r >= Runeself) {
182 9f1fdc12 2005-10-29 devnull while(!fullrune(buf, n))
183 9f1fdc12 2005-10-29 devnull buf[n++] = wingetec(w);
184 9f1fdc12 2005-10-29 devnull chartorune(&r, buf);
186 9f1fdc12 2005-10-29 devnull *nb = n;
187 9f1fdc12 2005-10-29 devnull return r;
191 9f1fdc12 2005-10-29 devnull wingetevent(Window *w, Event *e)
193 9f1fdc12 2005-10-29 devnull int i, nb;
195 9f1fdc12 2005-10-29 devnull e->c1 = wingetec(w);
196 9f1fdc12 2005-10-29 devnull e->c2 = wingetec(w);
197 9f1fdc12 2005-10-29 devnull e->q0 = wingeten(w);
198 9f1fdc12 2005-10-29 devnull e->q1 = wingeten(w);
199 9f1fdc12 2005-10-29 devnull e->flag = wingeten(w);
200 9f1fdc12 2005-10-29 devnull e->nr = wingeten(w);
201 9f1fdc12 2005-10-29 devnull if(e->nr > EVENTSIZE)
202 9f1fdc12 2005-10-29 devnull error("event string too long");
203 9f1fdc12 2005-10-29 devnull e->nb = 0;
204 9f1fdc12 2005-10-29 devnull for(i=0; i<e->nr; i++){
205 9f1fdc12 2005-10-29 devnull e->r[i] = wingeter(w, e->b+e->nb, &nb);
206 9f1fdc12 2005-10-29 devnull e->nb += nb;
208 9f1fdc12 2005-10-29 devnull e->r[e->nr] = 0;
209 9f1fdc12 2005-10-29 devnull e->b[e->nb] = 0;
210 9f1fdc12 2005-10-29 devnull if(wingetec(w) != '\n')
211 9f1fdc12 2005-10-29 devnull error("event syntax error");
215 9f1fdc12 2005-10-29 devnull winwriteevent(Window *w, Event *e)
217 9f1fdc12 2005-10-29 devnull fsprint(w->event, "%c%c%d %d\n", e->c1, e->c2, e->q0, e->q1);
221 9f1fdc12 2005-10-29 devnull winread(Window *w, uint q0, uint q1, char *data)
223 9f1fdc12 2005-10-29 devnull int m, n, nr;
224 9f1fdc12 2005-10-29 devnull char buf[256];
226 9f1fdc12 2005-10-29 devnull if(w->addr == nil)
227 3f8c36d6 2006-02-09 devnull w->addr = winopenfile(w, "addr");
228 9f1fdc12 2005-10-29 devnull if(w->data == nil)
229 3f8c36d6 2006-02-09 devnull w->data = winopenfile(w, "data");
231 9f1fdc12 2005-10-29 devnull while(m < q1){
232 9f1fdc12 2005-10-29 devnull n = sprint(buf, "#%d", m);
233 9f1fdc12 2005-10-29 devnull if(fswrite(w->addr, buf, n) != n)
234 9f1fdc12 2005-10-29 devnull error("error writing addr: %r");
235 9f1fdc12 2005-10-29 devnull n = fsread(w->data, buf, sizeof buf);
236 9f1fdc12 2005-10-29 devnull if(n <= 0)
237 9f1fdc12 2005-10-29 devnull error("reading data: %r");
238 9f1fdc12 2005-10-29 devnull nr = utfnlen(buf, n);
239 9f1fdc12 2005-10-29 devnull while(m+nr >q1){
240 9f1fdc12 2005-10-29 devnull do; while(n>0 && (buf[--n]&0xC0)==0x80);
243 9f1fdc12 2005-10-29 devnull if(n == 0)
245 9f1fdc12 2005-10-29 devnull memmove(data, buf, n);
246 9f1fdc12 2005-10-29 devnull data += n;
247 9f1fdc12 2005-10-29 devnull *data = 0;
248 9f1fdc12 2005-10-29 devnull m += nr;
253 9f1fdc12 2005-10-29 devnull windormant(Window *w)
255 9f1fdc12 2005-10-29 devnull if(w->addr != nil){
256 9f1fdc12 2005-10-29 devnull fsclose(w->addr);
257 9f1fdc12 2005-10-29 devnull w->addr = nil;
259 9f1fdc12 2005-10-29 devnull if(w->body != nil){
260 9f1fdc12 2005-10-29 devnull fsclose(w->body);
261 9f1fdc12 2005-10-29 devnull w->body = nil;
263 9f1fdc12 2005-10-29 devnull if(w->data != nil){
264 9f1fdc12 2005-10-29 devnull fsclose(w->data);
265 9f1fdc12 2005-10-29 devnull w->data = nil;
271 9f1fdc12 2005-10-29 devnull windel(Window *w, int sure)
273 3f8c36d6 2006-02-09 devnull if(sure)
274 9f1fdc12 2005-10-29 devnull fswrite(w->ctl, "delete\n", 7);
275 3f8c36d6 2006-02-09 devnull else if(fswrite(w->ctl, "del\n", 4) != 4)
276 9f1fdc12 2005-10-29 devnull return 0;
277 9f1fdc12 2005-10-29 devnull /* event proc will die due to read error from event file */
278 9f1fdc12 2005-10-29 devnull windormant(w);
279 9f1fdc12 2005-10-29 devnull fsclose(w->ctl);
280 9f1fdc12 2005-10-29 devnull w->ctl = nil;
281 9f1fdc12 2005-10-29 devnull return 1;
285 9f1fdc12 2005-10-29 devnull winclean(Window *w)
287 9f1fdc12 2005-10-29 devnull ctlprint(w->ctl, "clean\n");
291 9f1fdc12 2005-10-29 devnull winsetaddr(Window *w, char *addr, int errok)
293 9f1fdc12 2005-10-29 devnull if(w->addr == nil)
294 3f8c36d6 2006-02-09 devnull w->addr = winopenfile(w, "addr");
295 9f1fdc12 2005-10-29 devnull if(fswrite(w->addr, addr, strlen(addr)) < 0){
296 9f1fdc12 2005-10-29 devnull if(!errok)
297 9f1fdc12 2005-10-29 devnull error("error writing addr(%s): %r", addr);
298 9f1fdc12 2005-10-29 devnull return 0;
300 9f1fdc12 2005-10-29 devnull return 1;
304 9f1fdc12 2005-10-29 devnull winselect(Window *w, char *addr, int errok)
306 9f1fdc12 2005-10-29 devnull if(winsetaddr(w, addr, errok)){
307 9f1fdc12 2005-10-29 devnull ctlprint(w->ctl, "dot=addr\n");
308 9f1fdc12 2005-10-29 devnull return 1;
310 9f1fdc12 2005-10-29 devnull return 0;
314 9f1fdc12 2005-10-29 devnull winreadbody(Window *w, int *np) /* can't use readfile because acme doesn't report the length */
316 9f1fdc12 2005-10-29 devnull char *s;
317 9f1fdc12 2005-10-29 devnull int m, na, n;
319 9f1fdc12 2005-10-29 devnull if(w->body != nil)
320 9f1fdc12 2005-10-29 devnull winclosebody(w);
321 9f1fdc12 2005-10-29 devnull winopenbody(w, OREAD);
322 9f1fdc12 2005-10-29 devnull s = nil;
325 9f1fdc12 2005-10-29 devnull for(;;){
326 9f1fdc12 2005-10-29 devnull if(na < n+512){
327 9f1fdc12 2005-10-29 devnull na += 1024;
328 9f1fdc12 2005-10-29 devnull s = realloc(s, na+1);
330 9f1fdc12 2005-10-29 devnull m = fsread(w->body, s+n, na-n);
331 9f1fdc12 2005-10-29 devnull if(m <= 0)
335 9f1fdc12 2005-10-29 devnull s[n] = 0;
336 9f1fdc12 2005-10-29 devnull winclosebody(w);
337 9f1fdc12 2005-10-29 devnull *np = n;
338 9f1fdc12 2005-10-29 devnull return s;
342 9f1fdc12 2005-10-29 devnull winselection(Window *w)
344 9f1fdc12 2005-10-29 devnull int m, n;
345 9f1fdc12 2005-10-29 devnull char *buf;
346 9f1fdc12 2005-10-29 devnull char tmp[256];
347 9f1fdc12 2005-10-29 devnull CFid* fid;
349 3f8c36d6 2006-02-09 devnull fid = winopenfile1(w, "rdsel", OREAD);
350 9f1fdc12 2005-10-29 devnull if(fid == nil)
351 9f1fdc12 2005-10-29 devnull error("can't open rdsel: %r");
353 9f1fdc12 2005-10-29 devnull buf = nil;
354 9f1fdc12 2005-10-29 devnull for(;;){
355 9f1fdc12 2005-10-29 devnull m = fsread(fid, tmp, sizeof tmp);
356 9f1fdc12 2005-10-29 devnull if(m <= 0)
358 9f1fdc12 2005-10-29 devnull buf = erealloc(buf, n+m+1);
359 9f1fdc12 2005-10-29 devnull memmove(buf+n, tmp, m);
361 9f1fdc12 2005-10-29 devnull buf[n] = '\0';
363 9f1fdc12 2005-10-29 devnull fsclose(fid);
364 9f1fdc12 2005-10-29 devnull return buf;