13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <libg.h> 43e12c5d1SDavid du Colombier #include <frame.h> 53e12c5d1SDavid du Colombier #include "flayer.h" 63e12c5d1SDavid du Colombier #include "samterm.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier #define HSIZE 3 /* Type + short count */ 93e12c5d1SDavid du Colombier Header h; 103e12c5d1SDavid du Colombier uchar indata[DATASIZE+1]; /* room for NUL */ 113e12c5d1SDavid du Colombier uchar outdata[DATASIZE]; 123e12c5d1SDavid du Colombier short outcount; 133e12c5d1SDavid du Colombier int hversion; 143e12c5d1SDavid du Colombier 153e12c5d1SDavid du Colombier void inmesg(Hmesg, int); 163e12c5d1SDavid du Colombier int inshort(int); 173e12c5d1SDavid du Colombier long inlong(int); 18*219b2ee8SDavid du Colombier long invlong(int); 193e12c5d1SDavid du Colombier void hsetdot(int, long, long); 203e12c5d1SDavid du Colombier void hmoveto(int, long); 213e12c5d1SDavid du Colombier void hsetsnarf(int); 223e12c5d1SDavid du Colombier void clrlock(void); 233e12c5d1SDavid du Colombier int snarfswap(char*, int, char**); 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier void 263e12c5d1SDavid du Colombier rcv(void) 273e12c5d1SDavid du Colombier { 283e12c5d1SDavid du Colombier int c; 293e12c5d1SDavid du Colombier static state = 0; 303e12c5d1SDavid du Colombier static count = 0; 313e12c5d1SDavid du Colombier static i = 0; 323e12c5d1SDavid du Colombier static int errs = 0; 333e12c5d1SDavid du Colombier 343e12c5d1SDavid du Colombier while((c=rcvchar()) != -1) 353e12c5d1SDavid du Colombier switch(state){ 363e12c5d1SDavid du Colombier case 0: 373e12c5d1SDavid du Colombier h.type = c; 383e12c5d1SDavid du Colombier state++; 393e12c5d1SDavid du Colombier break; 403e12c5d1SDavid du Colombier 413e12c5d1SDavid du Colombier case 1: 423e12c5d1SDavid du Colombier h.count0 = c; 433e12c5d1SDavid du Colombier state++; 443e12c5d1SDavid du Colombier break; 453e12c5d1SDavid du Colombier 463e12c5d1SDavid du Colombier case 2: 473e12c5d1SDavid du Colombier h.count1 = c; 483e12c5d1SDavid du Colombier count = h.count0|(h.count1<<8); 493e12c5d1SDavid du Colombier i = 0; 503e12c5d1SDavid du Colombier if(count > DATASIZE){ 513e12c5d1SDavid du Colombier if(++errs < 5){ 523e12c5d1SDavid du Colombier dumperrmsg(count, h.type, h.count0, c); 533e12c5d1SDavid du Colombier state = 0; 543e12c5d1SDavid du Colombier continue; 553e12c5d1SDavid du Colombier } 563e12c5d1SDavid du Colombier fprint(2, "type %d count %d\n", h.type, count); 573e12c5d1SDavid du Colombier panic("count>DATASIZE"); 583e12c5d1SDavid du Colombier } 593e12c5d1SDavid du Colombier if(count == 0) 603e12c5d1SDavid du Colombier goto zerocount; 613e12c5d1SDavid du Colombier state++; 623e12c5d1SDavid du Colombier break; 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier case 3: 653e12c5d1SDavid du Colombier indata[i++] = c; 663e12c5d1SDavid du Colombier if(i == count){ 673e12c5d1SDavid du Colombier zerocount: 683e12c5d1SDavid du Colombier indata[i] = 0; 693e12c5d1SDavid du Colombier inmesg(h.type, count); 703e12c5d1SDavid du Colombier state = count = 0; 713e12c5d1SDavid du Colombier continue; 723e12c5d1SDavid du Colombier } 733e12c5d1SDavid du Colombier break; 743e12c5d1SDavid du Colombier } 753e12c5d1SDavid du Colombier } 763e12c5d1SDavid du Colombier 773e12c5d1SDavid du Colombier Text * 783e12c5d1SDavid du Colombier whichtext(int tg) 793e12c5d1SDavid du Colombier { 803e12c5d1SDavid du Colombier int i; 813e12c5d1SDavid du Colombier 823e12c5d1SDavid du Colombier for(i=0; i<nname; i++) 833e12c5d1SDavid du Colombier if(tag[i] == tg) 843e12c5d1SDavid du Colombier return text[i]; 853e12c5d1SDavid du Colombier panic("whichtext"); 863e12c5d1SDavid du Colombier return 0; 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier 893e12c5d1SDavid du Colombier void 903e12c5d1SDavid du Colombier inmesg(Hmesg type, int count) 913e12c5d1SDavid du Colombier { 923e12c5d1SDavid du Colombier Text *t; 933e12c5d1SDavid du Colombier int i, m; 943e12c5d1SDavid du Colombier long l; 953e12c5d1SDavid du Colombier Flayer *lp; 963e12c5d1SDavid du Colombier 973e12c5d1SDavid du Colombier m = inshort(0); 983e12c5d1SDavid du Colombier l = inlong(2); 993e12c5d1SDavid du Colombier switch(type){ 1003e12c5d1SDavid du Colombier case -1: 1013e12c5d1SDavid du Colombier panic("rcv error"); 1023e12c5d1SDavid du Colombier default: 1033e12c5d1SDavid du Colombier fprint(2, "type %d\n", type); 1043e12c5d1SDavid du Colombier panic("rcv unknown"); 1053e12c5d1SDavid du Colombier 1063e12c5d1SDavid du Colombier case Hversion: 1073e12c5d1SDavid du Colombier hversion = m; 1083e12c5d1SDavid du Colombier break; 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier case Hbindname: 111*219b2ee8SDavid du Colombier l = invlong(2); /* for 64-bit pointers */ 1123e12c5d1SDavid du Colombier if((i=whichmenu(m)) < 0) 1133e12c5d1SDavid du Colombier break; 1143e12c5d1SDavid du Colombier /* in case of a race, a bindname may already have occurred */ 1153e12c5d1SDavid du Colombier if((t=whichtext(m)) == 0) 1163e12c5d1SDavid du Colombier t=(Text *)l; 1173e12c5d1SDavid du Colombier else /* let the old one win; clean up the new one */ 1183e12c5d1SDavid du Colombier while(((Text *)l)->nwin>0) 1193e12c5d1SDavid du Colombier closeup(&((Text *)l)->l[((Text *)l)->front]); 1203e12c5d1SDavid du Colombier text[i] = t; 1213e12c5d1SDavid du Colombier text[i]->tag = m; 1223e12c5d1SDavid du Colombier break; 1233e12c5d1SDavid du Colombier 1243e12c5d1SDavid du Colombier case Hcurrent: 1253e12c5d1SDavid du Colombier if(whichmenu(m)<0) 1263e12c5d1SDavid du Colombier break; 1273e12c5d1SDavid du Colombier t = whichtext(m); 1283e12c5d1SDavid du Colombier i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag; 1293e12c5d1SDavid du Colombier if(t==0 && (t = sweeptext(0, m))==0) 1303e12c5d1SDavid du Colombier break; 1313e12c5d1SDavid du Colombier if(t->l[t->front].textfn==0) 1323e12c5d1SDavid du Colombier panic("Hcurrent"); 1333e12c5d1SDavid du Colombier lp = &t->l[t->front]; 1343e12c5d1SDavid du Colombier if(i){ 1353e12c5d1SDavid du Colombier flupfront(lp); 1363e12c5d1SDavid du Colombier flborder(lp, 0); 1373e12c5d1SDavid du Colombier work = lp; 1383e12c5d1SDavid du Colombier }else 1393e12c5d1SDavid du Colombier current(lp); 1403e12c5d1SDavid du Colombier break; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier case Hmovname: 1433e12c5d1SDavid du Colombier if((m=whichmenu(m)) < 0) 1443e12c5d1SDavid du Colombier break; 1453e12c5d1SDavid du Colombier t = text[m]; 1463e12c5d1SDavid du Colombier l = tag[m]; 1473e12c5d1SDavid du Colombier i = name[m][0]; 1483e12c5d1SDavid du Colombier text[m] = 0; /* suppress panic in menudel */ 1493e12c5d1SDavid du Colombier menudel(m); 1503e12c5d1SDavid du Colombier if(t == &cmd) 1513e12c5d1SDavid du Colombier m = 0; 1523e12c5d1SDavid du Colombier else{ 1533e12c5d1SDavid du Colombier if (nname>0 && text[0]==&cmd) 1543e12c5d1SDavid du Colombier m = 1; 1553e12c5d1SDavid du Colombier else m = 0; 1563e12c5d1SDavid du Colombier for(; m<nname; m++) 1573e12c5d1SDavid du Colombier if(strcmp((char*)indata+2, (char*)name[m]+1)<0) 1583e12c5d1SDavid du Colombier break; 1593e12c5d1SDavid du Colombier } 1603e12c5d1SDavid du Colombier menuins(m, indata+2, t, i, (int)l); 1613e12c5d1SDavid du Colombier break; 1623e12c5d1SDavid du Colombier 1633e12c5d1SDavid du Colombier case Hgrow: 1643e12c5d1SDavid du Colombier if(whichmenu(m) >= 0) 1653e12c5d1SDavid du Colombier hgrow(m, l, inlong(6), 1); 1663e12c5d1SDavid du Colombier break; 1673e12c5d1SDavid du Colombier 1683e12c5d1SDavid du Colombier case Hnewname: 1693e12c5d1SDavid du Colombier menuins(0, (uchar *)"", (Text *)0, ' ', m); 1703e12c5d1SDavid du Colombier break; 1713e12c5d1SDavid du Colombier 1723e12c5d1SDavid du Colombier case Hcheck0: 173*219b2ee8SDavid du Colombier i = whichmenu(m); 174*219b2ee8SDavid du Colombier if(i>=0) { 175*219b2ee8SDavid du Colombier t = text[i]; 176*219b2ee8SDavid du Colombier if (t) 177*219b2ee8SDavid du Colombier t->lock++; 1783e12c5d1SDavid du Colombier outTs(Tcheck, m); 179*219b2ee8SDavid du Colombier } 1803e12c5d1SDavid du Colombier break; 1813e12c5d1SDavid du Colombier 1823e12c5d1SDavid du Colombier case Hcheck: 183*219b2ee8SDavid du Colombier i = whichmenu(m); 184*219b2ee8SDavid du Colombier if(i>=0) { 185*219b2ee8SDavid du Colombier t = text[i]; 186*219b2ee8SDavid du Colombier if (t && t->lock) 187*219b2ee8SDavid du Colombier t->lock--; 1883e12c5d1SDavid du Colombier hcheck(m); 189*219b2ee8SDavid du Colombier } 1903e12c5d1SDavid du Colombier break; 1913e12c5d1SDavid du Colombier 1923e12c5d1SDavid du Colombier case Hunlock: 1933e12c5d1SDavid du Colombier clrlock(); 1943e12c5d1SDavid du Colombier break; 1953e12c5d1SDavid du Colombier 1963e12c5d1SDavid du Colombier case Hdata: 1973e12c5d1SDavid du Colombier if(whichmenu(m) >= 0) 1983e12c5d1SDavid du Colombier l += hdata(m, l, indata+6, count-6); 1993e12c5d1SDavid du Colombier Checkscroll: 2003e12c5d1SDavid du Colombier if(m == cmd.tag){ 2013e12c5d1SDavid du Colombier for(i=0; i<NL; i++){ 2023e12c5d1SDavid du Colombier lp = &cmd.l[i]; 2033e12c5d1SDavid du Colombier if(lp->textfn) 2043e12c5d1SDavid du Colombier center(lp, l>=0? l : lp->p1); 2053e12c5d1SDavid du Colombier } 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier break; 2083e12c5d1SDavid du Colombier 2093e12c5d1SDavid du Colombier case Horigin: 2103e12c5d1SDavid du Colombier if(whichmenu(m) >= 0) 2113e12c5d1SDavid du Colombier horigin(m, l); 2123e12c5d1SDavid du Colombier break; 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier case Hunlockfile: 2153e12c5d1SDavid du Colombier if(whichmenu(m)>=0 && (t = whichtext(m))->lock){ 2163e12c5d1SDavid du Colombier --t->lock; 2173e12c5d1SDavid du Colombier l = -1; 2183e12c5d1SDavid du Colombier goto Checkscroll; 2193e12c5d1SDavid du Colombier } 2203e12c5d1SDavid du Colombier break; 2213e12c5d1SDavid du Colombier 2223e12c5d1SDavid du Colombier case Hsetdot: 2233e12c5d1SDavid du Colombier if(whichmenu(m) >= 0) 2243e12c5d1SDavid du Colombier hsetdot(m, l, inlong(6)); 2253e12c5d1SDavid du Colombier break; 2263e12c5d1SDavid du Colombier 2273e12c5d1SDavid du Colombier case Hgrowdata: 2283e12c5d1SDavid du Colombier if(whichmenu(m)<0) 2293e12c5d1SDavid du Colombier break; 2303e12c5d1SDavid du Colombier hgrow(m, l, inlong(6), 0); 2313e12c5d1SDavid du Colombier whichtext(m)->lock++; /* fake the request */ 2323e12c5d1SDavid du Colombier l += hdata(m, l, indata+10, count-10); 2333e12c5d1SDavid du Colombier goto Checkscroll; 2343e12c5d1SDavid du Colombier 2353e12c5d1SDavid du Colombier case Hmoveto: 2363e12c5d1SDavid du Colombier if(whichmenu(m)>=0) 2373e12c5d1SDavid du Colombier hmoveto(m, l); 2383e12c5d1SDavid du Colombier break; 2393e12c5d1SDavid du Colombier 2403e12c5d1SDavid du Colombier case Hclean: 2413e12c5d1SDavid du Colombier if((m = whichmenu(m)) >= 0) 2423e12c5d1SDavid du Colombier name[m][0] = ' '; 2433e12c5d1SDavid du Colombier break; 2443e12c5d1SDavid du Colombier 2453e12c5d1SDavid du Colombier case Hdirty: 2463e12c5d1SDavid du Colombier if((m = whichmenu(m))>=0) 2473e12c5d1SDavid du Colombier name[m][0] = '\''; 2483e12c5d1SDavid du Colombier break; 2493e12c5d1SDavid du Colombier 2503e12c5d1SDavid du Colombier case Hdelname: 2513e12c5d1SDavid du Colombier if((m=whichmenu(m)) >= 0) 2523e12c5d1SDavid du Colombier menudel(m); 2533e12c5d1SDavid du Colombier break; 2543e12c5d1SDavid du Colombier 2553e12c5d1SDavid du Colombier case Hcut: 2563e12c5d1SDavid du Colombier if(whichmenu(m) >= 0) 2573e12c5d1SDavid du Colombier hcut(m, l, inlong(6)); 2583e12c5d1SDavid du Colombier break; 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier case Hclose: 2613e12c5d1SDavid du Colombier if(whichmenu(m)<0 || (t = whichtext(m))==0) 2623e12c5d1SDavid du Colombier break; 263bd389b36SDavid du Colombier l = t->nwin; 264bd389b36SDavid du Colombier for(i = 0,lp = t->l; l>0 && i<NL; i++,lp++) 265bd389b36SDavid du Colombier if(lp->textfn){ 2663e12c5d1SDavid du Colombier closeup(lp); 267bd389b36SDavid du Colombier --l; 268bd389b36SDavid du Colombier } 2693e12c5d1SDavid du Colombier break; 2703e12c5d1SDavid du Colombier 2713e12c5d1SDavid du Colombier case Hsetpat: 2723e12c5d1SDavid du Colombier setpat((char *)indata); 2733e12c5d1SDavid du Colombier break; 2743e12c5d1SDavid du Colombier 2753e12c5d1SDavid du Colombier case Hsetsnarf: 2763e12c5d1SDavid du Colombier hsetsnarf(m); 2773e12c5d1SDavid du Colombier break; 2783e12c5d1SDavid du Colombier 2793e12c5d1SDavid du Colombier case Hsnarflen: 2803e12c5d1SDavid du Colombier snarflen = inlong(0); 2813e12c5d1SDavid du Colombier break; 2823e12c5d1SDavid du Colombier 2833e12c5d1SDavid du Colombier case Hack: 2843e12c5d1SDavid du Colombier outT0(Tack); 2853e12c5d1SDavid du Colombier break; 2863e12c5d1SDavid du Colombier 2873e12c5d1SDavid du Colombier case Hexit: 2883e12c5d1SDavid du Colombier outT0(Texit); 2893e12c5d1SDavid du Colombier mouseexit(); 2903e12c5d1SDavid du Colombier break; 2913e12c5d1SDavid du Colombier } 2923e12c5d1SDavid du Colombier } 2933e12c5d1SDavid du Colombier 2943e12c5d1SDavid du Colombier void 2953e12c5d1SDavid du Colombier setlock(void) 2963e12c5d1SDavid du Colombier { 2973e12c5d1SDavid du Colombier lock++; 2983e12c5d1SDavid du Colombier cursorswitch(cursor = &lockarrow); 2993e12c5d1SDavid du Colombier } 3003e12c5d1SDavid du Colombier 3013e12c5d1SDavid du Colombier void 3023e12c5d1SDavid du Colombier clrlock(void) 3033e12c5d1SDavid du Colombier { 3043e12c5d1SDavid du Colombier hasunlocked = 1; 3053e12c5d1SDavid du Colombier if(lock > 0) 3063e12c5d1SDavid du Colombier lock--; 3073e12c5d1SDavid du Colombier if(lock == 0) 3083e12c5d1SDavid du Colombier cursorswitch(cursor=(Cursor *)0); 3093e12c5d1SDavid du Colombier } 3103e12c5d1SDavid du Colombier 3113e12c5d1SDavid du Colombier void 3123e12c5d1SDavid du Colombier startfile(Text *t) 3133e12c5d1SDavid du Colombier { 314*219b2ee8SDavid du Colombier outTsv(Tstartfile, t->tag, t); /* for 64-bit pointers */ 3153e12c5d1SDavid du Colombier setlock(); 3163e12c5d1SDavid du Colombier } 3173e12c5d1SDavid du Colombier 3183e12c5d1SDavid du Colombier void 3193e12c5d1SDavid du Colombier startnewfile(int type, Text *t) 3203e12c5d1SDavid du Colombier { 3213e12c5d1SDavid du Colombier t->tag = Untagged; 322*219b2ee8SDavid du Colombier outTv(type, t); /* for 64-bit pointers */ 3233e12c5d1SDavid du Colombier } 3243e12c5d1SDavid du Colombier 3253e12c5d1SDavid du Colombier int 3263e12c5d1SDavid du Colombier inshort(int n) 3273e12c5d1SDavid du Colombier { 3283e12c5d1SDavid du Colombier return indata[n]|(indata[n+1]<<8); 3293e12c5d1SDavid du Colombier } 3303e12c5d1SDavid du Colombier 3313e12c5d1SDavid du Colombier long 3323e12c5d1SDavid du Colombier inlong(int n) 3333e12c5d1SDavid du Colombier { 3343e12c5d1SDavid du Colombier return indata[n]|(indata[n+1]<<8)| 3353e12c5d1SDavid du Colombier ((long)indata[n+2]<<16)|((long)indata[n+3]<<24); 3363e12c5d1SDavid du Colombier } 3373e12c5d1SDavid du Colombier 338*219b2ee8SDavid du Colombier long 339*219b2ee8SDavid du Colombier invlong(int n) 340*219b2ee8SDavid du Colombier { 341*219b2ee8SDavid du Colombier long l; 342*219b2ee8SDavid du Colombier 343*219b2ee8SDavid du Colombier l = (indata[n+7]<<24) | (indata[n+6]<<16) | (indata[n+5]<<8) | indata[n+4]; 344*219b2ee8SDavid du Colombier l = (l<<16) | (indata[n+3]<<8) | indata[n+2]; 345*219b2ee8SDavid du Colombier l = (l<<16) | (indata[n+1]<<8) | indata[n]; 346*219b2ee8SDavid du Colombier return l; 347*219b2ee8SDavid du Colombier } 348*219b2ee8SDavid du Colombier 3493e12c5d1SDavid du Colombier void 3503e12c5d1SDavid du Colombier outT0(Tmesg type) 3513e12c5d1SDavid du Colombier { 3523e12c5d1SDavid du Colombier outstart(type); 3533e12c5d1SDavid du Colombier outsend(); 3543e12c5d1SDavid du Colombier } 3553e12c5d1SDavid du Colombier 3563e12c5d1SDavid du Colombier void 3573e12c5d1SDavid du Colombier outTl(Tmesg type, long l) 3583e12c5d1SDavid du Colombier { 3593e12c5d1SDavid du Colombier outstart(type); 3603e12c5d1SDavid du Colombier outlong(l); 3613e12c5d1SDavid du Colombier outsend(); 3623e12c5d1SDavid du Colombier } 3633e12c5d1SDavid du Colombier 3643e12c5d1SDavid du Colombier void 3653e12c5d1SDavid du Colombier outTs(Tmesg type, int s) 3663e12c5d1SDavid du Colombier { 3673e12c5d1SDavid du Colombier outstart(type); 3683e12c5d1SDavid du Colombier outshort(s); 3693e12c5d1SDavid du Colombier outsend(); 3703e12c5d1SDavid du Colombier } 3713e12c5d1SDavid du Colombier 3723e12c5d1SDavid du Colombier void 3733e12c5d1SDavid du Colombier outTss(Tmesg type, int s1, int s2) 3743e12c5d1SDavid du Colombier { 3753e12c5d1SDavid du Colombier outstart(type); 3763e12c5d1SDavid du Colombier outshort(s1); 3773e12c5d1SDavid du Colombier outshort(s2); 3783e12c5d1SDavid du Colombier outsend(); 3793e12c5d1SDavid du Colombier } 3803e12c5d1SDavid du Colombier 3813e12c5d1SDavid du Colombier void 3823e12c5d1SDavid du Colombier outTsll(Tmesg type, int s1, long l1, long l2) 3833e12c5d1SDavid du Colombier { 3843e12c5d1SDavid du Colombier outstart(type); 3853e12c5d1SDavid du Colombier outshort(s1); 3863e12c5d1SDavid du Colombier outlong(l1); 3873e12c5d1SDavid du Colombier outlong(l2); 3883e12c5d1SDavid du Colombier outsend(); 3893e12c5d1SDavid du Colombier } 3903e12c5d1SDavid du Colombier 3913e12c5d1SDavid du Colombier void 3923e12c5d1SDavid du Colombier outTsl(Tmesg type, int s1, long l1) 3933e12c5d1SDavid du Colombier { 3943e12c5d1SDavid du Colombier outstart(type); 3953e12c5d1SDavid du Colombier outshort(s1); 3963e12c5d1SDavid du Colombier outlong(l1); 3973e12c5d1SDavid du Colombier outsend(); 3983e12c5d1SDavid du Colombier } 3993e12c5d1SDavid du Colombier 4003e12c5d1SDavid du Colombier void 401*219b2ee8SDavid du Colombier outTsv(Tmesg type, int s1, void *l1) 402*219b2ee8SDavid du Colombier { 403*219b2ee8SDavid du Colombier outstart(type); 404*219b2ee8SDavid du Colombier outshort(s1); 405*219b2ee8SDavid du Colombier outvlong(l1); 406*219b2ee8SDavid du Colombier outsend(); 407*219b2ee8SDavid du Colombier } 408*219b2ee8SDavid du Colombier 409*219b2ee8SDavid du Colombier void 410*219b2ee8SDavid du Colombier outTv(Tmesg type, void *l1) 411*219b2ee8SDavid du Colombier { 412*219b2ee8SDavid du Colombier outstart(type); 413*219b2ee8SDavid du Colombier outvlong(l1); 414*219b2ee8SDavid du Colombier outsend(); 415*219b2ee8SDavid du Colombier } 416*219b2ee8SDavid du Colombier 417*219b2ee8SDavid du Colombier void 4183e12c5d1SDavid du Colombier outTslS(Tmesg type, int s1, long l1, Rune *s) 4193e12c5d1SDavid du Colombier { 4203e12c5d1SDavid du Colombier char buf[DATASIZE*3+1]; 4213e12c5d1SDavid du Colombier char *c; 4223e12c5d1SDavid du Colombier 4233e12c5d1SDavid du Colombier outstart(type); 4243e12c5d1SDavid du Colombier outshort(s1); 4253e12c5d1SDavid du Colombier outlong(l1); 4263e12c5d1SDavid du Colombier c = buf; 4273e12c5d1SDavid du Colombier while(*s) 4283e12c5d1SDavid du Colombier c += runetochar(c, s++); 4293e12c5d1SDavid du Colombier *c++ = 0; 4303e12c5d1SDavid du Colombier outcopy(c-buf, (uchar *)buf); 4313e12c5d1SDavid du Colombier outsend(); 4323e12c5d1SDavid du Colombier } 4333e12c5d1SDavid du Colombier 4343e12c5d1SDavid du Colombier void 4353e12c5d1SDavid du Colombier outTsls(Tmesg type, int s1, long l1, int s2) 4363e12c5d1SDavid du Colombier { 4373e12c5d1SDavid du Colombier outstart(type); 4383e12c5d1SDavid du Colombier outshort(s1); 4393e12c5d1SDavid du Colombier outlong(l1); 4403e12c5d1SDavid du Colombier outshort(s2); 4413e12c5d1SDavid du Colombier outsend(); 4423e12c5d1SDavid du Colombier } 4433e12c5d1SDavid du Colombier 4443e12c5d1SDavid du Colombier void 4453e12c5d1SDavid du Colombier outstart(Tmesg type) 4463e12c5d1SDavid du Colombier { 4473e12c5d1SDavid du Colombier outdata[0] = type; 4483e12c5d1SDavid du Colombier outcount = 0; 4493e12c5d1SDavid du Colombier } 4503e12c5d1SDavid du Colombier 4513e12c5d1SDavid du Colombier void 4523e12c5d1SDavid du Colombier outcopy(int count, uchar *data) 4533e12c5d1SDavid du Colombier { 4543e12c5d1SDavid du Colombier while(count--) 4553e12c5d1SDavid du Colombier outdata[HSIZE+outcount++] = *data++; 4563e12c5d1SDavid du Colombier } 4573e12c5d1SDavid du Colombier 4583e12c5d1SDavid du Colombier void 4593e12c5d1SDavid du Colombier outshort(int s) 4603e12c5d1SDavid du Colombier { 4613e12c5d1SDavid du Colombier uchar buf[2]; 4623e12c5d1SDavid du Colombier 4633e12c5d1SDavid du Colombier buf[0]=s; 4643e12c5d1SDavid du Colombier buf[1]=s>>8; 4653e12c5d1SDavid du Colombier outcopy(2, buf); 4663e12c5d1SDavid du Colombier } 4673e12c5d1SDavid du Colombier 4683e12c5d1SDavid du Colombier void 4693e12c5d1SDavid du Colombier outlong(long l) 4703e12c5d1SDavid du Colombier { 4713e12c5d1SDavid du Colombier uchar buf[4]; 4723e12c5d1SDavid du Colombier 4733e12c5d1SDavid du Colombier buf[0]=l; 4743e12c5d1SDavid du Colombier buf[1]=l>>8; 4753e12c5d1SDavid du Colombier buf[2]=l>>16; 4763e12c5d1SDavid du Colombier buf[3]=l>>24; 4773e12c5d1SDavid du Colombier outcopy(4, buf); 4783e12c5d1SDavid du Colombier } 4793e12c5d1SDavid du Colombier 4803e12c5d1SDavid du Colombier void 481*219b2ee8SDavid du Colombier outvlong(void *v) 482*219b2ee8SDavid du Colombier { 483*219b2ee8SDavid du Colombier int i; 484*219b2ee8SDavid du Colombier ulong l; 485*219b2ee8SDavid du Colombier uchar buf[8]; 486*219b2ee8SDavid du Colombier 487*219b2ee8SDavid du Colombier l = (ulong) v; 488*219b2ee8SDavid du Colombier for(i = 0; i < sizeof(buf); i++, l >>= 8) 489*219b2ee8SDavid du Colombier buf[i] = l; 490*219b2ee8SDavid du Colombier 491*219b2ee8SDavid du Colombier outcopy(8, buf); 492*219b2ee8SDavid du Colombier } 493*219b2ee8SDavid du Colombier 494*219b2ee8SDavid du Colombier void 4953e12c5d1SDavid du Colombier outsend(void) 4963e12c5d1SDavid du Colombier { 4973e12c5d1SDavid du Colombier if(outcount>DATASIZE-HSIZE) 4983e12c5d1SDavid du Colombier panic("outcount>sizeof outdata"); 4993e12c5d1SDavid du Colombier outdata[1]=outcount; 5003e12c5d1SDavid du Colombier outdata[2]=outcount>>8; 5013e12c5d1SDavid du Colombier if(write(1, (char *)outdata, outcount+HSIZE)!=outcount+HSIZE) 5023e12c5d1SDavid du Colombier exits("write error"); 5033e12c5d1SDavid du Colombier } 5043e12c5d1SDavid du Colombier 5053e12c5d1SDavid du Colombier 5063e12c5d1SDavid du Colombier void 5073e12c5d1SDavid du Colombier hsetdot(int m, long p0, long p1) 5083e12c5d1SDavid du Colombier { 5093e12c5d1SDavid du Colombier Text *t = whichtext(m); 5103e12c5d1SDavid du Colombier Flayer *l = &t->l[t->front]; 5113e12c5d1SDavid du Colombier 5123e12c5d1SDavid du Colombier flushtyping(1); 5133e12c5d1SDavid du Colombier flsetselect(l, p0, p1); 5143e12c5d1SDavid du Colombier } 5153e12c5d1SDavid du Colombier 5163e12c5d1SDavid du Colombier void 5173e12c5d1SDavid du Colombier horigin(int m, long p0) 5183e12c5d1SDavid du Colombier { 5193e12c5d1SDavid du Colombier Text *t = whichtext(m); 5203e12c5d1SDavid du Colombier Flayer *l = &t->l[t->front]; 5213e12c5d1SDavid du Colombier long a; 5223e12c5d1SDavid du Colombier ulong n; 5233e12c5d1SDavid du Colombier Rune *r; 5243e12c5d1SDavid du Colombier 5253e12c5d1SDavid du Colombier if(!flprepare(l)){ 5263e12c5d1SDavid du Colombier l->origin = p0; 5273e12c5d1SDavid du Colombier return; 5283e12c5d1SDavid du Colombier } 5293e12c5d1SDavid du Colombier a = p0-l->origin; 5303e12c5d1SDavid du Colombier if(a>=0 && a<l->f.nchars) 5313e12c5d1SDavid du Colombier frdelete(&l->f, 0, a); 5323e12c5d1SDavid du Colombier else if(a<0 && -a<l->f.nchars){ 5333e12c5d1SDavid du Colombier r = rload(&t->rasp, p0, l->origin, &n); 5343e12c5d1SDavid du Colombier frinsert(&l->f, r, r+n, 0); 5353e12c5d1SDavid du Colombier }else 5363e12c5d1SDavid du Colombier frdelete(&l->f, 0, l->f.nchars); 5373e12c5d1SDavid du Colombier l->origin = p0; 5383e12c5d1SDavid du Colombier scrdraw(l, t->rasp.nrunes); 5393e12c5d1SDavid du Colombier if(l->visible==Some) 5403e12c5d1SDavid du Colombier flrefresh(l, l->entire, 0); 5413e12c5d1SDavid du Colombier hcheck(m); 5423e12c5d1SDavid du Colombier } 5433e12c5d1SDavid du Colombier 5443e12c5d1SDavid du Colombier void 5453e12c5d1SDavid du Colombier hmoveto(int m, long p0) 5463e12c5d1SDavid du Colombier { 5473e12c5d1SDavid du Colombier Text *t = whichtext(m); 5483e12c5d1SDavid du Colombier Flayer *l = &t->l[t->front]; 5493e12c5d1SDavid du Colombier 5503e12c5d1SDavid du Colombier if(p0<l->origin || p0-l->origin>l->f.nchars*9/10) 5513e12c5d1SDavid du Colombier outTsll(Torigin, m, p0, 2L); 5523e12c5d1SDavid du Colombier } 5533e12c5d1SDavid du Colombier 5543e12c5d1SDavid du Colombier void 5553e12c5d1SDavid du Colombier hcheck(int m) 5563e12c5d1SDavid du Colombier { 5573e12c5d1SDavid du Colombier Flayer *l; 5583e12c5d1SDavid du Colombier Text *t; 5593e12c5d1SDavid du Colombier int reqd = 0, i; 5603e12c5d1SDavid du Colombier long n, nl, a; 5613e12c5d1SDavid du Colombier Rune *r; 5623e12c5d1SDavid du Colombier 5633e12c5d1SDavid du Colombier if(m == Untagged) 5643e12c5d1SDavid du Colombier return; 5653e12c5d1SDavid du Colombier t = whichtext(m); 5663e12c5d1SDavid du Colombier if(t == 0) /* possible in a half-built window */ 5673e12c5d1SDavid du Colombier return; 5683e12c5d1SDavid du Colombier for(l = &t->l[0], i = 0; i<NL; i++, l++){ 5693e12c5d1SDavid du Colombier if(l->textfn==0 || !flprepare(l)) /* BUG: don't 5703e12c5d1SDavid du Colombier need this if BUG below 5713e12c5d1SDavid du Colombier is fixed */ 5723e12c5d1SDavid du Colombier continue; 5733e12c5d1SDavid du Colombier a = t->l[i].origin; 5743e12c5d1SDavid du Colombier n = rcontig(&t->rasp, a, a+l->f.nchars, 1); 5753e12c5d1SDavid du Colombier if(n<l->f.nchars) /* text missing in middle of screen */ 5763e12c5d1SDavid du Colombier a+=n; 5773e12c5d1SDavid du Colombier else{ /* text missing at end of screen? */ 5783e12c5d1SDavid du Colombier Again: 5793e12c5d1SDavid du Colombier if(l->f.lastlinefull) 5803e12c5d1SDavid du Colombier goto Checksel; /* all's well */ 5813e12c5d1SDavid du Colombier a = t->l[i].origin+l->f.nchars; 5823e12c5d1SDavid du Colombier n = t->rasp.nrunes-a; 5833e12c5d1SDavid du Colombier if(n==0) 5843e12c5d1SDavid du Colombier goto Checksel; 5853e12c5d1SDavid du Colombier if(n>TBLOCKSIZE) 5863e12c5d1SDavid du Colombier n = TBLOCKSIZE; 5873e12c5d1SDavid du Colombier n = rcontig(&t->rasp, a, a+n, 1); 5883e12c5d1SDavid du Colombier if(n>0){ 5893e12c5d1SDavid du Colombier rload(&t->rasp, a, a+n, 0); 5903e12c5d1SDavid du Colombier nl = l->f.nchars; 5913e12c5d1SDavid du Colombier r = scratch; 5923e12c5d1SDavid du Colombier flinsert(l, r, r+n, l->origin+nl); 5933e12c5d1SDavid du Colombier if(nl == l->f.nchars) /* made no progress */ 5943e12c5d1SDavid du Colombier goto Checksel; 5953e12c5d1SDavid du Colombier goto Again; 5963e12c5d1SDavid du Colombier } 5973e12c5d1SDavid du Colombier } 5983e12c5d1SDavid du Colombier if(!reqd){ 5993e12c5d1SDavid du Colombier n = rcontig(&t->rasp, a, a+TBLOCKSIZE, 0); 6003e12c5d1SDavid du Colombier if(n <= 0) 6013e12c5d1SDavid du Colombier panic("hcheck request==0"); 6023e12c5d1SDavid du Colombier outTsls(Trequest, m, a, (int)n); 6033e12c5d1SDavid du Colombier outTs(Tcheck, m); 604*219b2ee8SDavid du Colombier t->lock++; /* for the Trequest */ 605*219b2ee8SDavid du Colombier t->lock++; /* for the Tcheck */ 6063e12c5d1SDavid du Colombier reqd++; 6073e12c5d1SDavid du Colombier } 6083e12c5d1SDavid du Colombier Checksel: 6093e12c5d1SDavid du Colombier flsetselect(l, l->p0, l->p1); 6103e12c5d1SDavid du Colombier } 6113e12c5d1SDavid du Colombier } 6123e12c5d1SDavid du Colombier 6133e12c5d1SDavid du Colombier void 6143e12c5d1SDavid du Colombier flnewlyvisible(Flayer *l) 6153e12c5d1SDavid du Colombier { 6163e12c5d1SDavid du Colombier hcheck(((Text *)l->user1)->tag); 6173e12c5d1SDavid du Colombier } 6183e12c5d1SDavid du Colombier 6193e12c5d1SDavid du Colombier void 6203e12c5d1SDavid du Colombier hsetsnarf(int nc) 6213e12c5d1SDavid du Colombier { 6223e12c5d1SDavid du Colombier char *s2; 6233e12c5d1SDavid du Colombier char *s1; 6243e12c5d1SDavid du Colombier int i; 6253e12c5d1SDavid du Colombier int n; 6263e12c5d1SDavid du Colombier 6273e12c5d1SDavid du Colombier cursorswitch(&deadmouse); 6283e12c5d1SDavid du Colombier s2 = alloc(nc+1); 6293e12c5d1SDavid du Colombier for(i=0; i<nc; i++) 6303e12c5d1SDavid du Colombier s2[i] = getch(); 6313e12c5d1SDavid du Colombier s2[nc] = 0; 6323e12c5d1SDavid du Colombier n = snarfswap(s2, nc, &s1); 6333e12c5d1SDavid du Colombier if(n >= 0){ 6343e12c5d1SDavid du Colombier if(!s1) 6353e12c5d1SDavid du Colombier n = 0; 636bd389b36SDavid du Colombier if(n > SNARFSIZE-1) 637bd389b36SDavid du Colombier n = SNARFSIZE-1; 638bd389b36SDavid du Colombier s1 = realloc(s1, n+1); 639*219b2ee8SDavid du Colombier if (!s1) 640*219b2ee8SDavid du Colombier exits("malloc"); 641bd389b36SDavid du Colombier s1[n] = 0; 6423e12c5d1SDavid du Colombier snarflen = n; 6433e12c5d1SDavid du Colombier outTs(Tsetsnarf, n); 6443e12c5d1SDavid du Colombier if(n>0 && write(1, s1, n)!=n) 6453e12c5d1SDavid du Colombier exits("write error"); 6463e12c5d1SDavid du Colombier free(s1); 647*219b2ee8SDavid du Colombier }else 648*219b2ee8SDavid du Colombier outTs(Tsetsnarf, 0); 6493e12c5d1SDavid du Colombier free(s2); 6503e12c5d1SDavid du Colombier cursorswitch(cursor); 6513e12c5d1SDavid du Colombier } 6523e12c5d1SDavid du Colombier 6533e12c5d1SDavid du Colombier void 6543e12c5d1SDavid du Colombier hgrow(int m, long a, long new, int req) 6553e12c5d1SDavid du Colombier { 6563e12c5d1SDavid du Colombier int i; 6573e12c5d1SDavid du Colombier Flayer *l; 6583e12c5d1SDavid du Colombier Text *t = whichtext(m); 6593e12c5d1SDavid du Colombier long o, b; 6603e12c5d1SDavid du Colombier 6613e12c5d1SDavid du Colombier if(new <= 0) 6623e12c5d1SDavid du Colombier panic("hgrow"); 6633e12c5d1SDavid du Colombier rresize(&t->rasp, a, 0L, new); 6643e12c5d1SDavid du Colombier for(l = &t->l[0], i = 0; i<NL; i++, l++){ 6653e12c5d1SDavid du Colombier if(l->textfn == 0) 6663e12c5d1SDavid du Colombier continue; 6673e12c5d1SDavid du Colombier o = l->origin; 6683e12c5d1SDavid du Colombier b = a-o-rmissing(&t->rasp, o, a); 6693e12c5d1SDavid du Colombier if(a < o) 6703e12c5d1SDavid du Colombier l->origin+=new; 6713e12c5d1SDavid du Colombier if(a < l->p0) 6723e12c5d1SDavid du Colombier l->p0+=new; 6733e12c5d1SDavid du Colombier if(a < l->p1) 6743e12c5d1SDavid du Colombier l->p1+=new; 6753e12c5d1SDavid du Colombier /* must prevent b temporarily becoming unsigned */ 6763e12c5d1SDavid du Colombier if(!req || a<o || (b>0 && b>l->f.nchars) || 6773e12c5d1SDavid du Colombier (l->f.nchars==0 && a-o>0)) 6783e12c5d1SDavid du Colombier continue; 6793e12c5d1SDavid du Colombier if(new>TBLOCKSIZE) 6803e12c5d1SDavid du Colombier new = TBLOCKSIZE; 6813e12c5d1SDavid du Colombier outTsls(Trequest, m, a, (int)new); 6823e12c5d1SDavid du Colombier t->lock++; 6833e12c5d1SDavid du Colombier req = 0; 6843e12c5d1SDavid du Colombier } 6853e12c5d1SDavid du Colombier } 6863e12c5d1SDavid du Colombier 6873e12c5d1SDavid du Colombier int 6883e12c5d1SDavid du Colombier hdata1(Text *t, long a, Rune *r, int len) 6893e12c5d1SDavid du Colombier { 6903e12c5d1SDavid du Colombier int i; 6913e12c5d1SDavid du Colombier Flayer *l; 6923e12c5d1SDavid du Colombier long o, b; 6933e12c5d1SDavid du Colombier 6943e12c5d1SDavid du Colombier for(l = &t->l[0], i=0; i<NL; i++, l++){ 6953e12c5d1SDavid du Colombier if(l->textfn==0) 6963e12c5d1SDavid du Colombier continue; 6973e12c5d1SDavid du Colombier o = l->origin; 6983e12c5d1SDavid du Colombier b = a-o-rmissing(&t->rasp, o, a); 6993e12c5d1SDavid du Colombier /* must prevent b temporarily becoming unsigned */ 7003e12c5d1SDavid du Colombier if(a<o || (b>0 && b>l->f.nchars)) 7013e12c5d1SDavid du Colombier continue; 7023e12c5d1SDavid du Colombier flinsert(l, r, r+len, o+b); 7033e12c5d1SDavid du Colombier } 7043e12c5d1SDavid du Colombier rdata(&t->rasp, a, a+len, r); 7053e12c5d1SDavid du Colombier rclean(&t->rasp); 7063e12c5d1SDavid du Colombier return len; 7073e12c5d1SDavid du Colombier } 7083e12c5d1SDavid du Colombier 7093e12c5d1SDavid du Colombier int 7103e12c5d1SDavid du Colombier hdata(int m, long a, uchar *s, int len) 7113e12c5d1SDavid du Colombier { 7123e12c5d1SDavid du Colombier int i, w; 7133e12c5d1SDavid du Colombier Text *t = whichtext(m); 7143e12c5d1SDavid du Colombier Rune buf[DATASIZE], *r; 7153e12c5d1SDavid du Colombier 7163e12c5d1SDavid du Colombier if(t->lock) 7173e12c5d1SDavid du Colombier --t->lock; 7183e12c5d1SDavid du Colombier if(len == 0) 7193e12c5d1SDavid du Colombier return 0; 7203e12c5d1SDavid du Colombier r = buf; 7213e12c5d1SDavid du Colombier for(i=0; i<len; i+=w,s+=w) 7223e12c5d1SDavid du Colombier w = chartorune(r++, (char*)s); 7233e12c5d1SDavid du Colombier return hdata1(t, a, buf, r-buf); 7243e12c5d1SDavid du Colombier } 7253e12c5d1SDavid du Colombier 7263e12c5d1SDavid du Colombier int 7273e12c5d1SDavid du Colombier hdatarune(int m, long a, Rune *r, int len) 7283e12c5d1SDavid du Colombier { 7293e12c5d1SDavid du Colombier Text *t = whichtext(m); 7303e12c5d1SDavid du Colombier 7313e12c5d1SDavid du Colombier if(t->lock) 7323e12c5d1SDavid du Colombier --t->lock; 7333e12c5d1SDavid du Colombier if(len == 0) 7343e12c5d1SDavid du Colombier return 0; 7353e12c5d1SDavid du Colombier return hdata1(t, a, r, len); 7363e12c5d1SDavid du Colombier } 7373e12c5d1SDavid du Colombier 7383e12c5d1SDavid du Colombier void 7393e12c5d1SDavid du Colombier hcut(int m, long a, long old) 7403e12c5d1SDavid du Colombier { 7413e12c5d1SDavid du Colombier Flayer *l; 7423e12c5d1SDavid du Colombier Text *t = whichtext(m); 7433e12c5d1SDavid du Colombier int i; 7443e12c5d1SDavid du Colombier long o, b; 7453e12c5d1SDavid du Colombier 7463e12c5d1SDavid du Colombier if(t->lock) 7473e12c5d1SDavid du Colombier --t->lock; 7483e12c5d1SDavid du Colombier for(l = &t->l[0], i = 0; i<NL; i++, l++){ 7493e12c5d1SDavid du Colombier if(l->textfn == 0) 7503e12c5d1SDavid du Colombier continue; 7513e12c5d1SDavid du Colombier o = l->origin; 7523e12c5d1SDavid du Colombier b = a-o-rmissing(&t->rasp, o, a); 7533e12c5d1SDavid du Colombier /* must prevent b temporarily becoming unsigned */ 7543e12c5d1SDavid du Colombier if((b<0 || b<l->f.nchars) && a+old>=o){ 7553e12c5d1SDavid du Colombier fldelete(l, b<0? o : o+b, 7563e12c5d1SDavid du Colombier a+old-rmissing(&t->rasp, o, a+old)); 7573e12c5d1SDavid du Colombier } 7583e12c5d1SDavid du Colombier if(a+old<o) 7593e12c5d1SDavid du Colombier l->origin-=old; 7603e12c5d1SDavid du Colombier else if(a<=o) 7613e12c5d1SDavid du Colombier l->origin = a; 7623e12c5d1SDavid du Colombier if(a+old<l->p0) 7633e12c5d1SDavid du Colombier l->p0-=old; 7643e12c5d1SDavid du Colombier else if(a<=l->p0) 7653e12c5d1SDavid du Colombier l->p0 = a; 7663e12c5d1SDavid du Colombier if(a+old<l->p1) 7673e12c5d1SDavid du Colombier l->p1-=old; 7683e12c5d1SDavid du Colombier else if(a<=l->p1) 7693e12c5d1SDavid du Colombier l->p1 = a; 7703e12c5d1SDavid du Colombier } 7713e12c5d1SDavid du Colombier rresize(&t->rasp, a, old, 0L); 7723e12c5d1SDavid du Colombier rclean(&t->rasp); 7733e12c5d1SDavid du Colombier } 774