|
|
1.1 ! root 1: #include "samterm.h" ! 2: ! 3: Text cmd; ! 4: uchar *scratch; ! 5: long nscralloc; ! 6: long typeaddr= -1; ! 7: Cursor *cursor; ! 8: Flayer *which=0; ! 9: Flayer *work=0; ! 10: long snarflen; ! 11: char lock=1; /* goes to 2 soon */ ! 12: main(argc, argv) ! 13: int argc; ! 14: char **argv; ! 15: { ! 16: register got, scr; ! 17: register Text *t; ! 18: Rectangle r; ! 19: register Flayer *nwhich; ! 20: ! 21: request(MOUSE|KBD|RCV); ! 22: initdisplay(argc, argv); ! 23: initcursors(); ! 24: GCALLOC(100, &scratch); ! 25: nscralloc=100; ! 26: cursswitch(&sweep); ! 27: do { ! 28: while(!button3()) ! 29: wait(MOUSE); ! 30: } while(!getr(&r, 0)); ! 31: cursswitch((Cursor *)0); ! 32: setlock(); ! 33: flstart(Drect); ! 34: rinit(&cmd.rasp); ! 35: flnew(&cmd.l[0], gettext, 1, (char *)&cmd); ! 36: flinit(&cmd.l[0], r, &defont); ! 37: cmd.nwin=1; ! 38: which= &cmd.l[0]; ! 39: cmd.tag=Untagged; ! 40: startnewfile(Tstartcmdfile, &cmd); ! 41: for(;;){ ! 42: if ((P->state&KBD) && which && (lock || ((Text *)which->user1)->lock)) ! 43: wait(MOUSE|RCV); ! 44: else ! 45: wait(MOUSE|KBD|RCV); ! 46: if (P->state&RCV) { ! 47: rcv(); ! 48: continue; ! 49: } ! 50: if(lock<2 && (P->state&RESHAPED)) { ! 51: P->state &= ~RESHAPED; ! 52: reshape(); ! 53: } ! 54: if(which && (P->state&KBD)) ! 55: type(which); ! 56: if(lock<2){ ! 57: if(!button123() || !ptinrect(mouse.xy, Drect)) ! 58: continue; ! 59: nwhich=flwhich(mouse.xy); ! 60: scr=which && ptinrect(mouse.xy, which->scroll); ! 61: if(button1()){ ! 62: typeaddr= -1; ! 63: if(nwhich){ ! 64: if(nwhich!=which) ! 65: current(nwhich); ! 66: else if(scr) ! 67: scroll(which, 1); ! 68: else{ ! 69: t=(Text *)which->user1; ! 70: if(flselect(which)){ ! 71: outTsl(Tdclick, t->tag, which->p0); ! 72: t->lock++; ! 73: }else if(t!=&cmd) ! 74: outcmd(); ! 75: } ! 76: } ! 77: }else if(button2() && which){ ! 78: typeaddr= -1; ! 79: if(scr) ! 80: scroll(which, 2); ! 81: else ! 82: menu2hit(); ! 83: }else if(button3()){ ! 84: typeaddr= -1; ! 85: if(scr) ! 86: scroll(which, 3); ! 87: else ! 88: menu3hit(); ! 89: } ! 90: } ! 91: } ! 92: } ! 93: reshape(){ ! 94: register i; ! 95: flreshape(Drect); ! 96: for(i=0; i<nname; i++) ! 97: if(text[i]){ ! 98: hcheck(text[i]->tag); ! 99: } ! 100: } ! 101: current(nw) ! 102: register Flayer *nw; ! 103: { ! 104: register Text *t; ! 105: if(which) ! 106: flborder(which, 0); ! 107: if(nw){ ! 108: typeaddr= -1; ! 109: cursswitch(&deadmouse); ! 110: flupfront(nw); ! 111: flborder(nw, 1); ! 112: (Up); ! 113: cursswitch(cursor); ! 114: t=(Text *)nw->user1; ! 115: t->front=nw-&t->l[0]; ! 116: if(t!=&cmd) ! 117: work=nw; ! 118: } ! 119: which=nw; ! 120: } ! 121: Sclose(l) ! 122: register Flayer *l; ! 123: { ! 124: register Text *t=(Text *)l->user1; ! 125: register m; ! 126: m=whichmenu(t->tag); ! 127: if(m<0) ! 128: return; ! 129: cursswitch(&deadmouse); ! 130: flclose(l); ! 131: cursswitch(cursor); ! 132: if(l==which){ ! 133: which=0; ! 134: current(flwhich(Pt(0, 0))); ! 135: } ! 136: if(l==work) ! 137: work=0; ! 138: if(--t->nwin==0){ ! 139: rclear(&t->rasp); ! 140: free((char *)t); ! 141: text[m]=0; ! 142: }else if(l==&t->l[t->front]){ ! 143: for(m=0; m<NL; m++) /* find one; any one will do */ ! 144: if(t->l[m].textfn){ ! 145: t->front=m; ! 146: return; ! 147: } ! 148: panic("Sclose"); ! 149: } ! 150: } ! 151: Flayer * ! 152: findl(t) ! 153: register Text *t; ! 154: { ! 155: register i; ! 156: for(i=0; i<NL; i++) ! 157: if(t->l[i].textfn==0) ! 158: return &t->l[i]; ! 159: return 0; ! 160: } ! 161: duplicate(l, r, f, close) ! 162: register Flayer *l; ! 163: Rectangle r; ! 164: Font *f; ! 165: { ! 166: register Text *t=(Text *)l->user1; ! 167: register Flayer *nl=findl(t); ! 168: if(nl){ ! 169: cursswitch(&deadmouse); ! 170: flnew(nl, gettext, l->user0, (char *)t); ! 171: flinit(nl, r, f); ! 172: nl->origin=l->origin; ! 173: flinsert(nl, (*l->textfn)(l, l->f.nchars), l->origin); ! 174: flsetselect(nl, l->p0, l->p1); ! 175: if(close){ ! 176: flclose(l); ! 177: if(l==which) ! 178: which=0; ! 179: }else ! 180: t->nwin++; ! 181: current(nl); ! 182: hcheck(t->tag); ! 183: } ! 184: cursswitch(cursor); ! 185: } ! 186: getr(rp, block) ! 187: Rectangle *rp; ! 188: { ! 189: Point p; ! 190: Rectangle r; ! 191: *rp=getrectb(1,block); ! 192: if(rp->corner.x && rp->corner.x-rp->origin.x<=5 && rp->corner.y-rp->origin.y<=5){ ! 193: p=rp->origin; ! 194: r=cmd.l[cmd.front].entire; ! 195: *rp=Drect; ! 196: if(cmd.nwin==1){ ! 197: if (p.y <= r.origin.y) ! 198: rp->corner.y = r.origin.y; ! 199: else if (p.y >= r.corner.y) ! 200: rp->origin.y = r.corner.y; ! 201: else if (p.x <= r.origin.x) ! 202: rp->corner.x = r.origin.x; ! 203: else if (p.x >= r.corner.x) ! 204: rp->origin.x = r.corner.x; ! 205: } ! 206: } ! 207: return rectclip(rp, Drect) && ! 208: rp->corner.x-rp->origin.x>100 && rp->corner.y-rp->origin.y>40; ! 209: } ! 210: snarf(t, w) ! 211: register Text *t; ! 212: { ! 213: register Flayer *l= &t->l[w]; ! 214: if(l->p1>l->p0){ ! 215: snarflen=l->p1-l->p0; ! 216: outTsll(Tsnarf, t->tag, l->p0, l->p1); ! 217: } ! 218: } ! 219: cut(t, w, save) ! 220: Text *t; ! 221: { ! 222: register long p0, p1; ! 223: if((p0=t->l[w].p0)==(p1=t->l[w].p1)) ! 224: return; ! 225: if(save) ! 226: snarf(t, w); ! 227: outTsll(Tcut, t->tag, p0, p1); ! 228: t->lock++; ! 229: flsetselect(&t->l[w], p0, p0); ! 230: hcut(t->tag, p0, p1-p0); ! 231: hcheck(t->tag); ! 232: } ! 233: paste(t, w) ! 234: Text *t; ! 235: { ! 236: long p0=t->l[w].p0; ! 237: if(snarflen){ ! 238: cut(t, w, 0); ! 239: t->lock++; ! 240: outTsl(Tpaste, t->tag, p0); ! 241: } ! 242: } ! 243: strlen(s) ! 244: register uchar *s; ! 245: { ! 246: register n=0; ! 247: while(*s++) ! 248: n++; ! 249: return n; ! 250: } ! 251: alnum(c) ! 252: register c; ! 253: { ! 254: return ('0'<=c && c<='9') || (c=='_') || ! 255: ('a'<=c && c<='z') || ('A'<=c && c<='Z'); ! 256: } ! 257: raspc(r, p) ! 258: register Rasp *r; ! 259: register long p; ! 260: { ! 261: rload(r, p, p+1); ! 262: return scratch[0]; /* will be 0 if p is in a hole */ ! 263: } ! 264: long ! 265: ctlw(r, o, p) ! 266: register Rasp *r; ! 267: register long o, p; ! 268: { ! 269: register c; ! 270: if(--p<o) ! 271: return o; ! 272: if(raspc(r, p)=='\n') ! 273: return p; ! 274: for(; p>=o && !alnum(c=raspc(r, p)); --p) ! 275: if(c=='\n') ! 276: return p+1; ! 277: for(; p>o && alnum(raspc(r, p-1)); --p) ! 278: ; ! 279: return p>=o? p : o; ! 280: } ! 281: #define ESC 0x1B ! 282: type(l) /* what a bloody mess this is */ ! 283: register Flayer *l; ! 284: { ! 285: Text *t=(Text *)l->user1; ! 286: uchar buf[100]; ! 287: register uchar *p=buf; ! 288: register c, backspacing=0; ! 289: register long a; ! 290: if(lock || t->lock) ! 291: return; ! 292: if((a=l->p0)!=l->p1){ ! 293: cut(t, t->front, 1); ! 294: return; /* it may now be locked */ ! 295: } ! 296: while(!backspacing && (c=kbdchar())>0 && c!=ESC) ! 297: switch(c&=0x7F){ ! 298: case '\027': ! 299: case '\b': ! 300: backspacing=1; ! 301: break; ! 302: case '\r': ! 303: c='\n'; ! 304: default: ! 305: *p++=c; ! 306: break; ! 307: } ! 308: if(p>buf){ ! 309: if(typeaddr<0) ! 310: typeaddr=a; ! 311: *p=0; ! 312: hgrow(t->tag, a, (long)(p-buf), 0); ! 313: t->lock++; /* pretend we Trequest'ed */ ! 314: hdata(t->tag, a, buf, (int)(p-buf)); ! 315: if(t==&cmd && a+(p-buf)==t->rasp.nbytes && p[-1]=='\n'){ ! 316: setlock(); ! 317: outcmd(); ! 318: outTslS(Ttype, t->tag, a, buf); ! 319: typeaddr= -1; ! 320: }else ! 321: outTslS(Ttype, t->tag, a, buf); ! 322: l->p0=l->p1=(a+=p-buf); ! 323: center(l, a); ! 324: } ! 325: if(!lock && backspacing && l->f.p0>0){ ! 326: l->p1=a; ! 327: l->p0=c=='\b'? a-1 : ctlw(&t->rasp, l->origin, a); ! 328: cut(t, t->front, 0); ! 329: if(typeaddr>=l->p0) ! 330: typeaddr=l->p0; ! 331: }else{ ! 332: if(c==ESC && typeaddr>=0){ ! 333: l->p0=typeaddr, l->p1=a; ! 334: typeaddr= -1; ! 335: } ! 336: for(l=t->l; l<&t->l[NL]; l++) ! 337: if(l->textfn) ! 338: flsetselect(l, l->p0, l->p1); ! 339: } ! 340: } ! 341: center(l, a) ! 342: register Flayer *l; ! 343: register long a; ! 344: { ! 345: register Text *t=(Text *)l->user1; ! 346: if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){ ! 347: if(a>t->rasp.nbytes) ! 348: a=t->rasp.nbytes; ! 349: outTsll(Torigin, t->tag, a, 2L); ! 350: outTs(Tunlockfile, t->tag); ! 351: t->lock++; ! 352: return 1; ! 353: } ! 354: return 0; ! 355: } ! 356: outcmd(){ ! 357: if(work) ! 358: outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1); ! 359: } ! 360: panic(s) ! 361: char *s; ! 362: { ! 363: rectf(D, Drect, F_XOR); ! 364: string(&defont, s, D, add(Drect.origin, Pt(4, 4)), F_STORE); ! 365: sleep(30); ! 366: exit(1); ! 367: } ! 368: ! 369: strgrow(s, n, want) /* can always toss the old data when called */ ! 370: uchar **s; ! 371: long *n; ! 372: { ! 373: if(*n>=want) ! 374: return; ! 375: gcfree(*s); ! 376: GCALLOC(want, s); ! 377: *n=want; ! 378: } ! 379: uchar ** ! 380: gettext(l, n) ! 381: register Flayer *l; ! 382: long n; ! 383: { ! 384: register Text *t=(Text *)l->user1; ! 385: rload(&t->rasp, l->origin, l->origin+n); ! 386: return &scratch; ! 387: } ! 388: long ! 389: scrtotal(l) ! 390: Flayer *l; ! 391: { ! 392: return ((Text *)l->user1)->rasp.nbytes; ! 393: } ! 394: uchar * ! 395: ALLOC(n) ! 396: { ! 397: register uchar *p=(uchar *)alloc(n); ! 398: if(p==0) ! 399: panic("ALLOC"); ! 400: return p; ! 401: } ! 402: GCALLOC(n, w) ! 403: uchar **w; ! 404: { ! 405: register i, j; ! 406: register Text *t; ! 407: register Flayer *l; ! 408: if(gcalloc((unsigned long)n, (char **)w)==0){ ! 409: for(i=0; i<nname; i++) ! 410: if(t=text[i]){ ! 411: /*raspcleanup(t); - uncache worthless stuff*/ ! 412: /*rclean(&t->rasp); (Can we do this if !t->lock?) */ ! 413: for(j=0,l= &t->l[0]; j<NL; j++,l++) ! 414: if(l->textfn && l->visible==Some && l->f.b){ ! 415: bfree(l->f.b); ! 416: l->f.b=0; ! 417: } ! 418: } ! 419: if(gcalloc((unsigned long)n, w)==0) ! 420: panic("GCALLOC"); ! 421: } ! 422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.