|
|
1.1 ! root 1: #include "samterm.h" ! 2: ! 3: #define HSIZE 3 /* Type + short count */ ! 4: Header h; ! 5: uchar indata[DATASIZE]; ! 6: uchar outdata[DATASIZE]; ! 7: short outcount; ! 8: long inlong(); ! 9: Text *sweeptext(); ! 10: rcv(){ ! 11: register c; ! 12: static state=0; ! 13: static count=0; ! 14: static i=0; ! 15: while((c=rcvchar())!=-1) ! 16: switch(state){ ! 17: case 0: ! 18: h.type=c; ! 19: state++; ! 20: break; ! 21: case 1: ! 22: h.count0=c; ! 23: state++; ! 24: break; ! 25: case 2: ! 26: h.count1=c; ! 27: count=h.count0|(h.count1<<8); ! 28: i=0; ! 29: if(count>DATASIZE) ! 30: panic("count>DATASIZE"); ! 31: if(count==0) ! 32: goto zerocount; ! 33: state++; ! 34: break; ! 35: case 3: ! 36: indata[i++]=c; ! 37: if(i==count){ ! 38: zerocount: ! 39: inmesg(h.type, count); ! 40: state=count=0; ! 41: continue; ! 42: } ! 43: break; ! 44: } ! 45: } ! 46: Text * ! 47: whichtext(tg) ! 48: register tg; ! 49: { ! 50: register i; ! 51: for(i=0; i<nname; i++) ! 52: if(tag[i]==tg) ! 53: return text[i]; ! 54: panic("whichtext"); ! 55: return 0; ! 56: } ! 57: inmesg(type, count) ! 58: Hmesg type; ! 59: { ! 60: register Text *t; ! 61: register i, m; ! 62: register long l; ! 63: register Flayer *lp; ! 64: m=inshort(0); ! 65: l=inlong(2); ! 66: switch(type){ ! 67: case -1: ! 68: panic("rcv error"); ! 69: default: ! 70: panic("rcv unknown"); ! 71: case Hnewname: ! 72: menuins(0, (uchar *)"", (Text *)0, ' ', m); ! 73: break; ! 74: case Hdelname: ! 75: if((m=whichmenu(m))>=0) ! 76: menudel(m); ! 77: break; ! 78: case Hmovname: ! 79: if((m=whichmenu(m))<0) ! 80: break; ! 81: t=text[m]; ! 82: l=tag[m]; ! 83: i=name[m][0]; ! 84: text[m]=0; /* suppress panic in menudel */ ! 85: menudel(m); ! 86: if(t==&cmd) ! 87: m=0; ! 88: else{ ! 89: for(m=nname>0 && text[0]==&cmd; m<nname; m++) ! 90: if(strcmp(indata+2, name[m]+1)<0) ! 91: break; ! 92: } ! 93: menuins(m, indata+2, t, i, (int)l); ! 94: break; ! 95: case Hbindname: ! 96: if((i=whichmenu(m))<0) ! 97: break; ! 98: /* in case of a race, a bindname may already have occurred */ ! 99: if((t=whichtext(m))==0) ! 100: t=(Text *)l; ! 101: else /* let the old one win; clean up the new one */ ! 102: while(((Text *)l)->nwin>0) ! 103: close(&((Text *)l)->l[((Text *)l)->front]); ! 104: text[i]=t; ! 105: text[i]->tag=m; ! 106: break; ! 107: case Hcurrent: ! 108: if(whichmenu(m)<0) ! 109: break; ! 110: t=whichtext(m); ! 111: i=which && ((Text *)which->user1)==&cmd && m!=cmd.tag; ! 112: if(t==0 && (t=sweeptext(0, m))==0) ! 113: break; ! 114: if(t->l[t->front].textfn==0) ! 115: panic("Hcurrent"); ! 116: lp=&t->l[t->front]; ! 117: if(i){ ! 118: flupfront(lp); ! 119: flborder(lp, 0); ! 120: work=lp; ! 121: }else ! 122: current(lp); ! 123: break; ! 124: case Hgrow: ! 125: if(whichmenu(m)>=0) ! 126: hgrow(m, l, inlong(6), 1); ! 127: break; ! 128: case Hdata: ! 129: if(whichmenu(m)>=0) ! 130: hdata(m, l, indata+6, count-7); ! 131: Checkscroll: ! 132: if(m==cmd.tag) ! 133: for(i=0; i<NL; i++){ ! 134: lp=&cmd.l[i]; ! 135: if(lp->textfn && lp->user0) ! 136: center(lp, l+1); ! 137: } ! 138: break; ! 139: case Hgrowdata: ! 140: if(whichmenu(m)<0) ! 141: break; ! 142: hgrow(m, l, inlong(6), 0); ! 143: whichtext(m)->lock++; /* fake the request */ ! 144: hdata(m, l, indata+10, count-11); ! 145: goto Checkscroll; ! 146: case Hcut: ! 147: if(whichmenu(m)>=0) ! 148: hcut(m, l, inlong(6)); ! 149: break; ! 150: case Hclean: ! 151: if((m=whichmenu(m))>=0) ! 152: name[m][0]=' '; ! 153: break; ! 154: case Hdirty: ! 155: if((m=whichmenu(m))>=0) ! 156: name[m][0]='\''; ! 157: break; ! 158: case Hcheck0: ! 159: if(whichmenu(m)>=0) ! 160: outTs(Tcheck, m); ! 161: break; ! 162: case Hcheck: ! 163: if(whichmenu(m)>=0) ! 164: hcheck(m); ! 165: break; ! 166: case Hmoveto: ! 167: if(whichmenu(m)>=0) ! 168: hmoveto(m, l); ! 169: break; ! 170: case Hsetdot: ! 171: if(whichmenu(m)>=0) ! 172: hsetdot(m, l, inlong(6)); ! 173: break; ! 174: case Horigin: ! 175: if(whichmenu(m)>=0) ! 176: horigin(m, l); ! 177: break; ! 178: case Hclose: ! 179: if(whichmenu(m)<0 || (t=whichtext(m))==0) ! 180: break; ! 181: for(i=0,lp=t->l; i<NL; i++,lp++) ! 182: if(lp->textfn) ! 183: close(lp); ! 184: break; ! 185: case Hunlock: ! 186: clrlock(); ! 187: break; ! 188: case Hsetpat: ! 189: setpat((char *)indata); ! 190: break; ! 191: case Hunlockfile: ! 192: if(whichmenu(m)>=0 && (t=whichtext(m))->lock) ! 193: --t->lock; ! 194: break; ! 195: case Hsetsnarf: ! 196: hsetsnarf(m); ! 197: break; ! 198: case Hsnarflen: ! 199: snarflen=inlong(0); ! 200: break; ! 201: case Hexit: ! 202: outT0(Texit); ! 203: break; ! 204: } ! 205: } ! 206: setlock(){ ! 207: lock++; ! 208: cursswitch(cursor=&lockarrow); ! 209: } ! 210: clrlock(){ ! 211: lock=0; ! 212: cursswitch(cursor=(Texture *)0); ! 213: } ! 214: startfile(t) ! 215: Text *t; ! 216: { ! 217: outTsl(Tstartfile, t->tag, (long)t); ! 218: outTs(Tunlockfile, t->tag); ! 219: t->lock++; ! 220: } ! 221: startnewfile(type, t) ! 222: Text *t; ! 223: { ! 224: t->tag=Untagged; ! 225: outTl(type, (long)t); ! 226: } ! 227: inshort(n) ! 228: { ! 229: return indata[n]|(indata[n+1]<<8); ! 230: } ! 231: long ! 232: inlong(n) ! 233: { ! 234: return indata[n]|(indata[n+1]<<8)| ! 235: ((long)indata[n+2]<<16)|((long)indata[n+3]<<24); ! 236: } ! 237: outT0(type) ! 238: Tmesg type; ! 239: { ! 240: outstart(type); ! 241: outsend(); ! 242: } ! 243: outTl(type, l) ! 244: Tmesg type; ! 245: long l; ! 246: { ! 247: outstart(type); ! 248: outlong(l); ! 249: outsend(); ! 250: } ! 251: outTs(type, s) ! 252: Tmesg type; ! 253: { ! 254: outstart(type); ! 255: outshort(s); ! 256: outsend(); ! 257: } ! 258: outTss(type, s1, s2) ! 259: Tmesg type; ! 260: { ! 261: outstart(type); ! 262: outshort(s1); ! 263: outshort(s2); ! 264: outsend(); ! 265: } ! 266: outTsll(type, s1, l1, l2) ! 267: Tmesg type; ! 268: long l1, l2; ! 269: { ! 270: outstart(type); ! 271: outshort(s1); ! 272: outlong(l1); ! 273: outlong(l2); ! 274: outsend(); ! 275: } ! 276: outTsl(type, s1, l1) ! 277: Tmesg type; ! 278: long l1; ! 279: { ! 280: outstart(type); ! 281: outshort(s1); ! 282: outlong(l1); ! 283: outsend(); ! 284: } ! 285: outTslS(type, s1, l1, s) ! 286: Tmesg type; ! 287: long l1; ! 288: uchar *s; ! 289: { ! 290: outstart(type); ! 291: outshort(s1); ! 292: outlong(l1); ! 293: outcopy(strlen(s)+1, s); ! 294: outsend(); ! 295: } ! 296: outTsls(type, s1, l1, s2) ! 297: Tmesg type; ! 298: long l1; ! 299: { ! 300: outstart(type); ! 301: outshort(s1); ! 302: outlong(l1); ! 303: outshort(s2); ! 304: outsend(); ! 305: } ! 306: outstart(type) ! 307: Tmesg type; ! 308: { ! 309: outdata[0]=type; ! 310: outcount=0; ! 311: } ! 312: outcopy(count, data) ! 313: register uchar *data; ! 314: { ! 315: while(count--) ! 316: outdata[HSIZE+outcount++]=*data++; ! 317: } ! 318: outshort(s) ! 319: { ! 320: uchar buf[2]; ! 321: buf[0]=s; ! 322: buf[1]=s>>8; ! 323: outcopy(2, buf); ! 324: } ! 325: outlong(l) ! 326: long l; ! 327: { ! 328: uchar buf[4]; ! 329: buf[0]=l; ! 330: buf[1]=l>>8; ! 331: buf[2]=l>>16; ! 332: buf[3]=l>>24; ! 333: outcopy(4, buf); ! 334: } ! 335: outsend() ! 336: { ! 337: if(outcount>sizeof outdata-HSIZE) ! 338: panic("outcount>sizeof outdata"); ! 339: outdata[1]=outcount; ! 340: outdata[2]=outcount>>8; ! 341: sendnchars(outcount+HSIZE, (char *)outdata); ! 342: } ! 343: hsetdot(m, p0, p1) ! 344: register long p0, p1; ! 345: { ! 346: register Text *t=whichtext(m); ! 347: register Flayer *l=&t->l[t->front]; ! 348: flsetselect(l, p0, p1); ! 349: } ! 350: horigin(m, p0) ! 351: register long p0; ! 352: { ! 353: register Text *t=whichtext(m); ! 354: register Flayer *l=&t->l[t->front]; ! 355: register long a; ! 356: if(!flprepare(l)){ ! 357: l->origin=p0; ! 358: return; ! 359: } ! 360: a=p0-l->origin; ! 361: if(a>=0 && a<l->f.nchars) ! 362: frdelete(&l->f, (Posn)0, (Posn)a); ! 363: else if(a<0 && -a<l->f.nchars) ! 364: frinsert(&l->f, rload(&t->rasp, p0, l->origin), 0); ! 365: else ! 366: frdelete(&l->f, (Posn)0, l->f.nchars); ! 367: l->origin=p0; ! 368: scrdraw(l, t->rasp.nbytes); ! 369: if(l->visible==Some) ! 370: flrefresh(l, l->entire, 0); ! 371: hcheck(m); ! 372: } ! 373: hmoveto(m, p0) ! 374: register long p0; ! 375: { ! 376: register Text *t=whichtext(m); ! 377: register Flayer *l=&t->l[t->front]; ! 378: if(p0<l->origin || p0-l->origin>muldiv(l->f.nchars, 9, 10)) ! 379: outTsll(Torigin, m, p0, 2L); ! 380: } ! 381: hcheck(m) ! 382: { ! 383: register Flayer *l; ! 384: register Text *t; ! 385: register reqd=0, i; ! 386: register long n, a; ! 387: if(m==Untagged) ! 388: return; ! 389: t=whichtext(m); ! 390: for(l=&t->l[0], i=0; i<NL; i++, l++){ ! 391: if(l->textfn==0 || !flprepare(l)) /* BUG: don't ! 392: need this if BUG below ! 393: is fixed */ ! 394: continue; ! 395: a=t->l[i].origin; ! 396: n=rcontig(&t->rasp, a, a+l->f.nchars, 1); ! 397: if(n<l->f.nchars) /* text missing in middle of screen */ ! 398: a+=n; ! 399: else{ /* text missing at end of screen? */ ! 400: Again: ! 401: if(l->f.nlines==l->f.maxlines && /* BUG: lastlinefull!! */ ! 402: ptofchar(&l->f, l->f.nchars).y>= ! 403: l->f.r.origin.y+l->f.maxlines*l->f.font->height) ! 404: goto Checksel; /* all's well */ ! 405: a=t->l[i].origin+l->f.nchars; ! 406: n=t->rasp.nbytes-a; ! 407: if(n==0) ! 408: goto Checksel; ! 409: if(n>TBLOCKSIZE) ! 410: n=TBLOCKSIZE; ! 411: n=rcontig(&t->rasp, a, a+n, 1); ! 412: if(n>0){ ! 413: rload(&t->rasp, a, a+n); ! 414: n=l->f.nchars; ! 415: flinsert(l, &scratch, l->origin+n); ! 416: if(n==l->f.nchars) /* made no progress */ ! 417: goto Checksel; ! 418: goto Again; ! 419: } ! 420: } ! 421: if(!reqd){ ! 422: n=rcontig(&t->rasp, a, a+TBLOCKSIZE, 0); ! 423: if(n<=0) ! 424: panic("hcheck request==0"); ! 425: outTsls(Trequest, m, a, (int)n); ! 426: outTs(Tcheck, m); ! 427: t->lock++; ! 428: reqd++; ! 429: } ! 430: Checksel: ! 431: flsetselect(l, l->p0, l->p1); ! 432: } ! 433: } ! 434: flnewlyvisible(l) ! 435: register Flayer *l; ! 436: { ! 437: hcheck(((Text *)l->user1)->tag); ! 438: } ! 439: hsetsnarf(m){ ! 440: struct{ ! 441: uchar *s; ! 442: short n; ! 443: short size; ! 444: }s1, s2; ! 445: register c, i; ! 446: cursswitch(&deadmouse); ! 447: s1.s=0; ! 448: s1.n=s1.size=0; ! 449: getmuxbuf(&s1); ! 450: s2.n=s2.size=m; ! 451: GCALLOC(m, &s2.s); ! 452: for(i=0; i<m; i++){ ! 453: while((c=rcvchar())<0) ! 454: wait(RCV); ! 455: s2.s[i]=c; ! 456: } ! 457: setmuxbuf(&s2); ! 458: gcfree(s2.s); ! 459: snarflen=s1.n; ! 460: outTs(Tsetsnarf, s1.n); ! 461: sendnchars(s1.n, s1.s); ! 462: gcfree(s1.s); ! 463: cursswitch(cursor); ! 464: } ! 465: hgrow(m, a, new, req) ! 466: register long a, new; ! 467: { ! 468: register i; ! 469: register Flayer *l; ! 470: register Text *t=whichtext(m); ! 471: register long o, b; ! 472: if(new<=0) ! 473: panic("hgrow"); ! 474: rresize(&t->rasp, a, 0L, new); ! 475: for(l=&t->l[0], i=0; i<NL; i++, l++){ ! 476: if(l->textfn==0) ! 477: continue; ! 478: o=l->origin; ! 479: b=a-o-rmissing(&t->rasp, o, a); ! 480: if(a<o) ! 481: l->origin+=new; ! 482: if(a<l->p0) ! 483: l->p0+=new; ! 484: if(a<l->p1) ! 485: l->p1+=new; ! 486: if(!req || a<o || b>(long)l->f.nchars || ! 487: (l->f.nchars==0 && a-o>0)) ! 488: continue; ! 489: if(new>TBLOCKSIZE) ! 490: new=TBLOCKSIZE; ! 491: outTsls(Trequest, m, a, (int)new); ! 492: t->lock++; ! 493: req=0; ! 494: } ! 495: } ! 496: hdata(m, a, s, len) ! 497: register long a; ! 498: uchar *s; ! 499: { ! 500: register i; ! 501: register Flayer *l; ! 502: register Text *t=whichtext(m); ! 503: register long o, b; ! 504: if(t->lock) ! 505: --t->lock; ! 506: for(l=&t->l[0], i=0; i<NL; i++, l++){ ! 507: if(l->textfn==0) ! 508: continue; ! 509: o=l->origin; ! 510: b=a-o-rmissing(&t->rasp, o, a); ! 511: if(a<o || b>(long)l->f.nchars) ! 512: continue; ! 513: flinsert(l, &s, o+b); ! 514: } ! 515: rdata(&t->rasp, a, a+len, s); ! 516: rclean(&t->rasp); ! 517: } ! 518: #define a A /* need this line or get 'redeclaration of a' error! */ ! 519: hcut(m, a, old) ! 520: register long a, old; ! 521: { ! 522: register Flayer *l; ! 523: register Text *t=whichtext(m); ! 524: register i; ! 525: register long o, b; ! 526: if(t->lock) ! 527: --t->lock; ! 528: for(l=&t->l[0], i=0; i<NL; i++, l++){ ! 529: if(l->textfn==0) ! 530: continue; ! 531: o=l->origin; ! 532: b=a-o-rmissing(&t->rasp, o, a); ! 533: if(b<(long)l->f.nchars && a+old>=o) ! 534: fldelete(l, b<0? o : o+b, ! 535: a+old-rmissing(&t->rasp, o, a+old)); ! 536: if(a+old<o) ! 537: l->origin-=old; ! 538: else if(a<=o) ! 539: l->origin=a; ! 540: if(a+old<l->p0) ! 541: l->p0-=old; ! 542: else if(a<=l->p0) ! 543: l->p0=a; ! 544: if(a+old<l->p1) ! 545: l->p1-=old; ! 546: else if(a<=l->p1) ! 547: l->p1=a; ! 548: } ! 549: rresize(&t->rasp, a, old, 0L); ! 550: rclean(&t->rasp); ! 551: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.