10 typedef struct Event Event;
22 char b[EVENTSIZE*UTFmax+1];
62 int label(char*, int);
64 void stdinproc(void*);
65 void stdoutproc(void*);
66 void type(Event*, int, Fid*, Fid*);
67 void sende(Event*, int, Fid*, Fid*, Fid*, int);
68 char *onestring(int, char**);
70 void deltype(uint, uint);
74 fsfidprint(Fid *fid, char *fmt, ...)
81 n = vsnprint(buf, sizeof buf, fmt, arg);
83 return fswrite(fid, buf, n);
89 fprint(2, "usage: win cmd args...\n");
90 threadexitsall("usage");
94 nopipes(void *v, char *msg)
97 if(strcmp(msg, "sys: write on closed pipe") == 0)
110 threadmain(int argc, char **argv)
132 threadnotify(nopipes, 1);
133 if((fs = nsmount("acme", "")) < 0)
134 sysfatal("nsmount acme: %r");
135 ctlfd = fsopen(fs, "new/ctl", ORDWR|OCEXEC);
136 if(ctlfd < 0 || fsread(ctlfd, buf, 12) != 12)
139 sprint(buf, "%d/tag", id);
140 fd = fsopenfd(fs, buf, OWRITE|OCEXEC);
141 write(fd, " Send Delete", 12);
143 sprint(buf, "%d/event", id);
144 eventfd = fsopen(fs, buf, ORDWR|OCEXEC);
145 sprint(buf, "%d/addr", id);
146 addrfd = fsopen(fs, buf, ORDWR|OCEXEC);
147 sprint(buf, "%d/data", id);
148 datafd = fsopen(fs, buf, ORDWR|OCEXEC);
149 sprint(buf, "%d/body", id);
150 /* bodyfd = fsopenfd(fs, buf, ORDWR|OCEXEC); */
151 if(eventfd==nil || addrfd==nil || datafd==nil)
152 sysfatal("data files: %r");
154 if(eventfd<0 || addrfd<0 || datafd<0 || bodyfd<0)
155 sysfatal("data files: %r");
160 sysfatal("pipe: %r");
162 cpid = chancreate(sizeof(ulong), 1);
163 cwait = threadwaitchan();
164 threadcreate(waitthread, nil, STACK);
165 threadcreate(runproc, nil, STACK);
168 sysfatal("exec failed");
170 getwd(buf1, sizeof buf1);
171 sprint(buf, "name %s/-%s\n0\n", buf1, name);
172 fswrite(ctlfd, buf, strlen(buf));
173 sprint(buf, "dumpdir %s/\n", buf1);
174 fswrite(ctlfd, buf, strlen(buf));
175 sprint(buf, "dump %s\n", onestring(argc, argv));
176 fswrite(ctlfd, buf, strlen(buf));
178 threadcreate(stdoutproc, nil, STACK);
182 char *shell[] = { "rc", "-i", 0 };
199 if((sh = getenv("SHELL")) != nil)
202 threadexec(cpid, fd, prog[0], prog);
210 fprint(2, "win: %s: %r\n", s);
214 postnote(PNGROUP, pid, "hangup");
219 onestring(int argc, char **argv)
223 static char buf[1024];
228 for(i=0; i<argc; i++){
230 if(p+n+1 >= buf+sizeof buf)
232 memmove(p, argv[i], n);
243 static char buf[8192];
248 nbuf = fsread(efd, buf, sizeof buf);
263 while('0'<=(c=getec(efd)) && c<='9')
266 error("event number syntax");
271 geter(Fid *efd, char *buf, int *nb)
281 while(!fullrune(buf, n))
282 buf[n++] = getec(efd);
290 gete(Fid *efd, Event *e)
298 e->flag = geten(efd);
300 if(e->nr > EVENTSIZE)
301 error("event string too long");
303 for(i=0; i<e->nr; i++){
304 e->r[i] = geter(efd, e->b+e->nb, &nb);
309 if(getec(efd) != '\n')
310 error("event syntax 2");
314 nrunes(char *s, int nb)
321 i += chartorune(&r, s+i);
339 fprint(2, "typing[%d,%d)\n", q.p, q.p+ntyper);
342 fprint(2, "msg %c%c q[%d,%d)... ", e.c1, e.c2, e.q0, e.q1);
347 print("unknown message %c%c\n", e.c1, e.c2);
350 case 'E': /* write to body; can't affect us */
352 fprint(2, "shift typing %d... ", e.q1-e.q0);
356 case 'F': /* generated by our actions; ignore */
365 fprint(2, "shift typing %d... ", e.q1-e.q0);
368 else if(e.q0 <= q.p+ntyper){
370 fprint(2, "type... ");
371 type(&e, fd0, afd, dfd);
387 if(e.flag&1 || (e.c2=='x' && e.nr==0 && e2.nr==0)){
388 /* send it straight back */
389 fsfidprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1);
392 if(e.q0==e.q1 && (e.flag&2)){
398 sende(&e, fd0, cfd, afd, dfd, 0);
399 sende(&blank, fd0, cfd, afd, dfd, 0);
401 sende(&e3, fd0, cfd, afd, dfd, 1);
402 }else if(e.q1 != e.q0)
403 sende(&e, fd0, cfd, afd, dfd, 1);
408 /* just send it back */
411 fsfidprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1);
435 char x[16], hold[UTFmax];
438 threadnotify(nopipes, 1);
439 buf = malloc(8192+UTFmax+1);
442 n = threadread(fd1, buf+npart, 8192);
449 s = memchr(buf+npart, 0, n);
451 for(t=s; s<buf+npart+n; s++)
452 if(*t = *s) /* assign = */
459 /* hold on to final partial rune */
461 while(n>0 && (buf[n-1]&0xC0)){
464 if((buf[n]&0xC0)!=0x80){
465 if(fullrune(buf+n, npart)){
466 w = chartorune(&r, buf+n);
474 memmove(hold, buf+n, npart);
479 m = sprint(x, "#%d", q.p);
480 if(fswrite(afd, x, m) != m)
481 error("stdout writing address");
482 if(fswrite(dfd, buf, n) != n)
483 error("stdout writing body");
484 q.p += nrunes(buf, n);
486 memmove(buf, hold, npart);
493 label(char *sr, int n)
495 char *sl, *el, *er, *r;
498 for(r=er-1; r>=sr; r--)
505 if(el-sr > sizeof wdir)
506 sr = el - sizeof wdir;
507 for(sl=el-3; sl>=sr; sl--)
508 if(sl[0]=='\033' && sl[1]==']' && sl[2]==';')
514 snprint(wdir, sizeof wdir, "name %s/-%s\n0\n", sl+3, name);
515 fswrite(ctlfd, wdir, strlen(wdir));
517 memmove(sl, el, er-el);
549 addtype(int c, uint p0, char *b, int nb, int nr)
556 for(i=0; i<nb; i+=w){
557 w = chartorune(&r, b+i);
558 if((r==0x7F||r==3) && c=='K'){
559 postnote(PNGROUP, pid, "interrupt");
560 /* toss all typing */
565 /* buglet: more than one delete ignored */
568 if(r=='\n' || r==0x04)
571 typing = realloc(typing, ntypeb+nb);
575 memmove(typing+ntypeb, b, nb);
578 for(p=0; p<p0 && b0<typing+ntypeb; p++){
579 w = chartorune(&r, b0+i);
583 error("typing: findrune");
584 memmove(b0+nb, b0, (typing+ntypeb)-b0);
597 for(i=0; i<ntypeb; i++)
598 if(typing[i]=='\n' || typing[i]==0x04){
599 n = i + (typing[i] == '\n');
601 if(write(fd0, typing, n) != n)
602 error("sending to program");
603 nr = nrunes(typing, i);
607 memmove(typing, typing+i, ntypeb);
611 print("no breakchar\n");
618 deltype(uint p0, uint p1)
626 for(p=0; p<p0 && b0<ntypeb; p++){
627 w = chartorune(&r, typing+b0);
634 for(; p<p1 && b1<ntypeb; p++){
635 w = chartorune(&r, typing+b1);
637 if(r=='\n' || r==0x04)
642 memmove(typing+b0, typing+b1, ntypeb-b1);
648 type(Event *e, int fd0, Fid *afd, Fid *dfd)
654 addtype(e->c1, e->q0-q.p, e->b, e->nb, e->nr);
658 n = sprint(buf, "#%d", m);
659 fswrite(afd, buf, n);
660 n = fsread(dfd, buf, sizeof buf);
663 do; while(n>0 && (buf[--n]&0xC0)==0x80);
668 addtype(e->c1, m-q.p, buf, n, nr);
676 sende(Event *e, int fd0, Fid *cfd, Fid *afd, Fid *dfd, int donl)
678 int l, m, n, nr, lastc, end;
679 char abuf[16], buf[128];
682 l = sprint(abuf, "#%d", end);
683 fswrite(afd, abuf, l);
685 fswrite(dfd, e->b, e->nb);
686 addtype(e->c1, ntyper, e->b, e->nb, e->nr);
687 lastc = e->r[e->nr-1];
692 n = sprint(buf, "#%d", m);
693 fswrite(afd, buf, n);
694 n = fsread(dfd, buf, sizeof buf);
697 do; while(n>0 && (buf[--n]&0xC0)==0x80);
702 l = sprint(abuf, "#%d", end);
703 fswrite(afd, abuf, l);
704 fswrite(dfd, buf, n);
705 addtype(e->c1, ntyper, buf, n, nr);
711 if(donl && lastc!='\n'){
712 fswrite(dfd, "\n", 1);
713 addtype(e->c1, ntyper, "\n", 1, 1);
715 fswrite(cfd, "dot=addr", 8);