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