13 #define HSIZE 3 /* Type + short count */
15 uchar indata[DATASIZE+1]; /* room for NUL */
16 uchar outdata[DATASIZE];
21 void inmesg(Hmesg, int);
25 void hsetdot(int, long, long);
26 void hmoveto(int, long);
30 int snarfswap(char*, int, char**);
41 while((c=rcvchar()) != -1)
55 count = h.count0|(h.count1<<8);
59 dumperrmsg(count, h.type, h.count0, c);
63 fprint(2, "type %d count %d\n", h.type, count);
64 panic("count>DATASIZE");
76 inmesg(h.type, count);
89 for(i=0; i<nname; i++)
97 inmesg(Hmesg type, int count)
110 fprint(2, "type %d\n", type);
111 panic("rcv unknown");
118 l = invlong(2); /* for 64-bit pointers */
119 if((i=whichmenu(m)) < 0)
121 /* in case of a race, a bindname may already have occurred */
122 if((t=whichtext(m)) == 0)
124 else /* let the old one win; clean up the new one */
125 while(((Text *)l)->nwin>0)
126 closeup(&((Text *)l)->l[((Text *)l)->front]);
135 i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag;
136 if(t==0 && (t = sweeptext(0, m))==0)
138 if(t->l[t->front].textfn==0)
140 lp = &t->l[t->front];
150 if((m=whichmenu(m)) < 0)
155 text[m] = 0; /* suppress panic in menudel */
160 if (nname>0 && text[0]==&cmd)
164 if(strcmp((char*)indata+2, (char*)name[m]+1)<0)
167 menuins(m, indata+2, t, i, (int)l);
171 if(whichmenu(m) >= 0)
172 hgrow(m, l, inlong(6), 1);
176 menuins(0, (uchar *)"", (Text *)0, ' ', m);
204 if(whichmenu(m) >= 0)
205 l += hdata(m, l, indata+6, count-6);
211 center(lp, l>=0? l : lp->p1);
217 if(whichmenu(m) >= 0)
222 if(whichmenu(m)>=0 && (t = whichtext(m))->lock){
230 if(whichmenu(m) >= 0)
231 hsetdot(m, l, inlong(6));
237 hgrow(m, l, inlong(6), 0);
238 whichtext(m)->lock++; /* fake the request */
239 l += hdata(m, l, indata+10, count-10);
248 if((m = whichmenu(m)) >= 0)
253 if((m = whichmenu(m))>=0)
258 if((m=whichmenu(m)) >= 0)
263 if(whichmenu(m) >= 0)
264 hcut(m, l, inlong(6));
268 if(whichmenu(m)<0 || (t = whichtext(m))==0)
271 for(i = 0,lp = t->l; l>0 && i<NL; i++,lp++)
279 setpat((char *)indata);
287 snarflen = inlong(0);
310 setcursor(mousectl, cursor = &lockarrow);
320 setcursor(mousectl, cursor=(Cursor *)0);
326 outTsv(Tstartfile, t->tag, (vlong)t); /* for 64-bit pointers */
331 startnewfile(int type, Text *t)
334 outTv(type, (vlong)t); /* for 64-bit pointers */
340 return indata[n]|(indata[n+1]<<8);
346 return indata[n]|(indata[n+1]<<8)|
347 ((long)indata[n+2]<<16)|((long)indata[n+3]<<24);
355 v = (indata[n+7]<<24) | (indata[n+6]<<16) | (indata[n+5]<<8) | indata[n+4];
356 v = (v<<16) | (indata[n+3]<<8) | indata[n+2];
357 v = (v<<16) | (indata[n+1]<<8) | indata[n];
369 outTl(Tmesg type, long l)
377 outTs(Tmesg type, int s)
385 outTss(Tmesg type, int s1, int s2)
394 outTsll(Tmesg type, int s1, long l1, long l2)
404 outTsl(Tmesg type, int s1, long l1)
413 outTsv(Tmesg type, int s1, vlong v1)
422 outTv(Tmesg type, vlong v1)
430 outTslS(Tmesg type, int s1, long l1, Rune *s)
432 char buf[DATASIZE*UTFmax+1];
440 c += runetochar(c, s++);
442 outcopy(c-buf, (uchar *)buf);
447 outTsls(Tmesg type, int s1, long l1, int s2)
464 outcopy(int count, uchar *data)
467 outdata[HSIZE+outcount++] = *data++;
498 for(i = 0; i < sizeof(buf); i++){
509 if(outcount>DATASIZE-HSIZE)
510 panic("outcount>sizeof outdata");
512 outdata[2]=outcount>>8;
513 if(write(1, (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)
514 panic("write error");
519 hsetdot(int m, long p0, long p1)
521 Text *t = whichtext(m);
522 Flayer *l = &t->l[t->front];
525 flsetselect(l, p0, p1);
529 horigin(int m, long p0)
531 Text *t = whichtext(m);
532 Flayer *l = &t->l[t->front];
542 if(a>=0 && a<l->f.nchars)
543 frdelete(&l->f, 0, a);
544 else if(a<0 && -a<l->f.nchars){
545 r = rload(&t->rasp, p0, l->origin, &n);
546 frinsert(&l->f, r, r+n, 0);
548 frdelete(&l->f, 0, l->f.nchars);
550 scrdraw(l, t->rasp.nrunes);
552 flrefresh(l, l->entire, 0);
557 hmoveto(int m, long p0)
559 Text *t = whichtext(m);
560 Flayer *l = &t->l[t->front];
562 if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)
563 outTsll(Torigin, m, p0, 2L);
578 if(t == 0) /* possible in a half-built window */
580 for(l = &t->l[0], i = 0; i<NL; i++, l++){
581 if(l->textfn==0 || !flprepare(l)) /* BUG: don't
582 need this if BUG below
586 n = rcontig(&t->rasp, a, a+l->f.nchars, 1);
587 if(n<l->f.nchars) /* text missing in middle of screen */
589 else{ /* text missing at end of screen? */
591 if(l->f.lastlinefull)
592 goto Checksel; /* all's well */
593 a = t->l[i].origin+l->f.nchars;
594 n = t->rasp.nrunes-a;
599 n = rcontig(&t->rasp, a, a+n, 1);
601 rload(&t->rasp, a, a+n, 0);
604 flinsert(l, r, r+n, l->origin+nl);
605 if(nl == l->f.nchars) /* made no progress */
611 n = rcontig(&t->rasp, a, a+TBLOCKSIZE, 0);
613 panic("hcheck request==0");
614 outTsls(Trequest, m, a, (int)n);
616 t->lock++; /* for the Trequest */
617 t->lock++; /* for the Tcheck */
621 flsetselect(l, l->p0, l->p1);
626 flnewlyvisible(Flayer *l)
628 hcheck(((Text *)l->user1)->tag);
639 setcursor(mousectl, &deadmouse);
644 n = snarfswap(s2, nc, &s1);
648 s1 = realloc(s1, n+1);
654 if(n>0 && write(1, s1, n)!=n)
655 panic("snarf write error");
660 setcursor(mousectl, cursor);
674 m = plumbunpack(s, nc);
676 plumbsend(plumbfd, m);
683 hgrow(int m, long a, long new, int req)
687 Text *t = whichtext(m);
692 rresize(&t->rasp, a, 0L, new);
693 for(l = &t->l[0], i = 0; i<NL; i++, l++){
697 b = a-o-rmissing(&t->rasp, o, a);
704 /* must prevent b temporarily becoming unsigned */
705 if(!req || a<o || (b>0 && b>l->f.nchars) ||
706 (l->f.nchars==0 && a-o>0))
710 outTsls(Trequest, m, a, (int)new);
717 hdata1(Text *t, long a, Rune *r, int len)
723 for(l = &t->l[0], i=0; i<NL; i++, l++){
727 b = a-o-rmissing(&t->rasp, o, a);
728 /* must prevent b temporarily becoming unsigned */
729 if(a<o || (b>0 && b>l->f.nchars))
731 flinsert(l, r, r+len, o+b);
733 rdata(&t->rasp, a, a+len, r);
739 hdata(int m, long a, uchar *s, int len)
742 Text *t = whichtext(m);
743 Rune buf[DATASIZE], *r;
750 for(i=0; i<len; i+=w,s+=w)
751 w = chartorune(r++, (char*)s);
752 return hdata1(t, a, buf, r-buf);
756 hdatarune(int m, long a, Rune *r, int len)
758 Text *t = whichtext(m);
764 return hdata1(t, a, r, len);
768 hcut(int m, long a, long old)
771 Text *t = whichtext(m);
777 for(l = &t->l[0], i = 0; i<NL; i++, l++){
781 b = a-o-rmissing(&t->rasp, o, a);
782 /* must prevent b temporarily becoming unsigned */
783 if((b<0 || b<l->f.nchars) && a+old>=o){
784 fldelete(l, b<0? o : o+b,
785 a+old-rmissing(&t->rasp, o, a+old));
800 rresize(&t->rasp, a, old, 0L);