|
|
1.1 ! root 1: #include <jerq.h> ! 2: #include <font.h> ! 3: #include <layer.h> ! 4: #include <queue.h> ! 5: #include <jerqproc.h> ! 6: #include <setup.h> ! 7: #include "../msgs.h" ! 8: #include "pconfig.h" ! 9: #include "proto.h" ! 10: #include "packets.h" ! 11: ! 12: struct Pchannel pconvs[16]; /* Should be NPROC!!! */ ! 13: extern struct Proc *debugger; ! 14: extern int recvchars(), sendpkt(); ! 15: extern boot(); ! 16: short usermouse=0; /* kbdproc (a USER proc) has the mouse under its paw */ ! 17: extern short second; ! 18: #define crecvchars recvchars ! 19: ! 20: struct Pconfig pconfig={ ! 21: sendpkt, ! 22: recvchars, ! 23: (void(*)())crecvchars ! 24: }; ! 25: ! 26: Texture cup = { ! 27: 0x0100, 0x00E0, 0x0010, 0x03E0, 0x0400, 0x0FE0, 0x123C, 0x1FE2, ! 28: 0x101A, 0x101A, 0x1002, 0x103C, 0x1810, 0x6FEC, 0x4004, 0x3FF8, ! 29: }; ! 30: Texture deadmouse = { ! 31: 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C, 0x0082, 0x0441, ! 32: 0xFFE1, 0x5FF1, 0x3FFE, 0x17F0, 0x03E0, 0x0000, 0x0000, 0x0000, ! 33: }; ! 34: Texture bullseye = { ! 35: 0x07E0, 0x1FF8, 0x399C, 0x63C6, 0x6FF6, 0xCDB3, 0xD99B, 0xFFFF, ! 36: 0xFFFF, 0xD99B, 0xCDB3, 0x6FF6, 0x63C6, 0x399C, 0x1FF8, 0x07E0, ! 37: }; ! 38: Texture boxcurs = { ! 39: 0x43FF, 0xE001, 0x7001, 0x3801, 0x1D01, 0x0F01, 0x8701, 0x8F01, ! 40: 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0xFFFF, ! 41: }; ! 42: Texture eightball = { ! 43: 0x07E0, 0x1FF8, 0x21FC, 0x4CFE, 0x52FE, 0xCCFF, 0xD2FF, 0xCCFF, ! 44: 0xE1FF, 0xFFFF, 0xFFFF, 0x7FFE, 0x7FFE, 0x3FFC, 0x1FF8, 0x07E0, ! 45: }; ! 46: ! 47: #define INSET 3 ! 48: Layer *whichlayer(); ! 49: struct Proc *kbdproc=0; ! 50: #define DEMUX 0 ! 51: #define CONTROL 1 ! 52: #define UP 0 ! 53: #define DOWN 1 ! 54: int control(), windowproc(), demux(); ! 55: struct Mouse mouse; ! 56: main(){ ! 57: register struct Proc *p; ! 58: *DADDR=0; ! 59: BonW(); ! 60: qinit(); ! 61: aciainit(baud_speeds[VALBAUD]); ! 62: binit(); ! 63: kbdinit(); ! 64: cursinit(); ! 65: if(VALMAXADDR){ /* 1024Kb */ ! 66: NPROC=16; ! 67: p=proctab+NPROC; ! 68: allocinit(((char *)p), ((char *)p)+256*1024L); ! 69: }else{ /* 256Kb */ ! 70: NPROC=7; ! 71: p=proctab+NPROC; ! 72: allocinit(((char *)p), ((char *)p)+25*1024L); ! 73: } ! 74: gcinit(); ! 75: bufinit(); ! 76: if(pinit(NPROC)==-1) ! 77: error("pinit", "-1"); ! 78: Lgrey(&display); ! 79: spl0(); ! 80: swinit(); ! 81: P=newproc(demux); /* process 0 */ ! 82: setrun(newproc(control)); /* process 1 */ ! 83: /* ! 84: * sw(0) will switch out of our local stack onto the control stack. ! 85: * we will never return to this stack ! 86: */ ! 87: sw(0); ! 88: /*NOTREACHED*/ ! 89: } ! 90: buttons(updown) ! 91: { ! 92: do; while((button123()!=0) != updown); ! 93: } ! 94: Sw() ! 95: { ! 96: if(second){ ! 97: second=0; ! 98: if(Ptflag) ! 99: ptimeout(); ! 100: } ! 101: sw(P!=&proctab[CONTROL]); /* if control, clock will restart us */ ! 102: } ! 103: control(){ ! 104: register Layer *lp; ! 105: register struct Proc *p, *pp; ! 106: for(;;){ ! 107: pp=0; ! 108: lp=whichlayer(); ! 109: for(p=&proctab[CONTROL+1]; p<&proctab[NPROC]; p++){ ! 110: if(p->state&WAKEUP){ ! 111: p->state&=~WAKEUP; ! 112: setrun(p); ! 113: } ! 114: if((p->state&KBDLOCAL)==0 && p->kbdqueue.c_cc>0 ! 115: && p->text!=(char *)boot){ ! 116: register c=qpeekc(&p->kbdqueue); ! 117: if(c==0x80){ /* BREAKKEY */ ! 118: if(muxkill(2, p)!=-1) ! 119: (void)qgetc(&p->kbdqueue); ! 120: }else if(muxsendchar(c, p)!=-1) ! 121: (void)qgetc(&p->kbdqueue); ! 122: } ! 123: if(lp && p->layer==lp) ! 124: pp=p; /* pp pointed at by mouse */ ! 125: } ! 126: if(usermouse && (pp!=kbdproc || (pp->state&GOTMOUSE)==0)){ ! 127: usermouse=0; ! 128: cursswitch((Texture *)0); ! 129: cursallow(); ! 130: }else if(!usermouse && pp){ ! 131: Check_mouse: if(pp==kbdproc && (pp->state&GOTMOUSE)){ ! 132: usermouse=1; ! 133: cursswitch(pp->cursor); ! 134: if(pp->inhibited) ! 135: cursinhibit(); ! 136: } ! 137: } ! 138: if(button123()){ ! 139: if(lp==0 || (pp->state&GOTMOUSE)==0){ ! 140: dobutton(whichbutton()); ! 141: /* make sure kbdproc doesn't think ! 142: buttons are down */ ! 143: if(kbdproc){ ! 144: givemouse(kbdproc); ! 145: goto Check_mouse; /* usermouse==0 */ ! 146: } ! 147: } ! 148: if(pp && pp->state&GOTMOUSE) ! 149: givemouse(pp); ! 150: } ! 151: if(RCVQUEUE.c_cc) ! 152: setrun(&proctab[DEMUX]); ! 153: Sw(); ! 154: } ! 155: } ! 156: New(){ ! 157: newwindow(windowproc); ! 158: } ! 159: Psend(a, b, c, d) ! 160: char *b; ! 161: { ! 162: while(psend(a, b, c, d)==-1) ! 163: Sw(); ! 164: } ! 165: Delete(){ ! 166: delete(whichlayer()); ! 167: } ! 168: delete(l) ! 169: register Layer *l; ! 170: { ! 171: register struct Proc *p; ! 172: register w; ! 173: if(l){ ! 174: w=whichproc(l); ! 175: p= &proctab[w]; ! 176: muxmesg(w, C_DELETE); ! 177: delproc(p); ! 178: dellayer(l); ! 179: if(kbdproc==p) ! 180: kbdproc=0; ! 181: } ! 182: } ! 183: delproc(p) ! 184: register struct Proc *p; ! 185: { ! 186: p->state=0; /* exit(w) */ ! 187: p->nticks=0; ! 188: p->inhibited=0; ! 189: qclear(&p->kbdqueue); ! 190: freemem(p); ! 191: p->layer=0; /* sigh */ ! 192: } ! 193: Top(){ ! 194: upfront(whichlayer()); ! 195: } ! 196: Bottom(){ ! 197: downback(whichlayer()); ! 198: } ! 199: Current(){ ! 200: register Layer *l; ! 201: l=whichlayer(); ! 202: if(l) ! 203: tolayer(l); ! 204: } ! 205: Rectangle ! 206: canon(p1, p2) ! 207: Point p1, p2; ! 208: { ! 209: Rectangle r; ! 210: r.origin.x = min(p1.x, p2.x); ! 211: r.origin.y = min(p1.y, p2.y); ! 212: r.corner.x = max(p1.x, p2.x); ! 213: r.corner.y = max(p1.y, p2.y); ! 214: return(r); ! 215: } ! 216: Rectangle ! 217: getrectb(n) ! 218: int n; ! 219: { ! 220: Rectangle r; ! 221: Point p1, p2; ! 222: cursswitch(&boxcurs); ! 223: buttons(UP); ! 224: buttons(DOWN); ! 225: if(!(mouse.buttons&n)){ ! 226: r.origin.x=r.origin.y=r.corner.x=r.corner.y=0; ! 227: buttons(UP); ! 228: goto Return; ! 229: } ! 230: p1=mouse.xy; ! 231: p2=p1; ! 232: r=canon(p1, p2); ! 233: outline(r); ! 234: for(; mouse.buttons&n; nap(2)){ ! 235: outline(r); ! 236: p2=mouse.xy; ! 237: r=canon(p1, p2); ! 238: outline(r); ! 239: } ! 240: outline(r); /* undraw for the last time */ ! 241: Return: ! 242: cursswitch((P->state&USER)? P->cursor : (Texture *)0); ! 243: return r; ! 244: } ! 245: Rectangle ! 246: getrect(n) ! 247: { ! 248: return getrectb(8>>n); ! 249: } ! 250: Reshape(){ ! 251: register Layer *l; ! 252: register struct Proc *p; ! 253: Rectangle r; ! 254: Point save; /*SFBOTCH*/ ! 255: l=whichlayer(); ! 256: if(l==0) ! 257: return; ! 258: p= &proctab[whichproc(l)]; ! 259: r=getrect3(); ! 260: if(r.corner.x-r.origin.x>100 && r.corner.y-r.origin.y>40){ ! 261: /*SFBOTCHPoint save;*/ ! 262: save=l->rect.origin; ! 263: dellayer(l); ! 264: p->state&=~MOVED; ! 265: p->state|=RESHAPED; ! 266: l=newlayer(r); ! 267: if(l==0){ ! 268: r.origin=save; ! 269: r.corner=add(save, Pt(100, 50)); ! 270: l=newlayer(r); ! 271: if(l==0){ /* oh shit */ ! 272: delproc(p); ! 273: muxmesg((int)(p-proctab), C_DELETE); ! 274: return; ! 275: } ! 276: } ! 277: p->layer=l; ! 278: p->rect=inset(r, INSET); ! 279: setborder(p); ! 280: } ! 281: if(p->state&USER) ! 282: setdata(p); ! 283: muxnewwind(p, C_RESHAPE); ! 284: } ! 285: Move(){ ! 286: register Layer *l, *nl; ! 287: register struct Proc *procp; ! 288: Point p, op, dp; ! 289: l=whichlayer(); ! 290: if(l==0) ! 291: return; ! 292: procp= &proctab[whichproc(l)]; ! 293: dp=sub(l->rect.corner, l->rect.origin); ! 294: cursset(l->rect.origin); ! 295: cursswitch(&boxcurs); ! 296: p=l->rect.origin; ! 297: while(button3()){ ! 298: if(button12()) ! 299: goto Return; ! 300: outline(Rpt(p, add(p, dp))); ! 301: nap(2); ! 302: op=p; ! 303: p=mouse.xy; ! 304: /* using boxcurs, can't get off top or left! */ ! 305: if(p.x+dp.x >= XMAX-9) ! 306: p.x=XMAX-9-dp.x; ! 307: if(p.y+dp.y >= YMAX-9) ! 308: p.y=YMAX-9-dp.y; ! 309: outline(Rpt(op, add(op, dp))); ! 310: cursset(p); ! 311: } ! 312: cursswitch(&deadmouse); ! 313: nl=newlayer(Rpt(p, add(p, dp))); ! 314: if(nl==0) ! 315: goto Return; ! 316: Ubitblt(l, l->rect, nl, p, F_STORE); ! 317: procp->layer=nl; ! 318: procp->rect=inset(nl->rect, INSET); ! 319: dellayer(l); ! 320: if(procp->state&USER) ! 321: setdata(procp); ! 322: if((procp->state&RESHAPED) == 0) ! 323: procp->state|=MOVED|RESHAPED; /* turn on RESHAPED for old progs */ ! 324: l=nl; ! 325: setborder(procp); ! 326: Return: ! 327: cursset(div(add(l->rect.origin, l->rect.corner), 2)); ! 328: cursswitch((Texture *)0); ! 329: /* No C_RESHAPE required */ ! 330: } ! 331: ! 332: /* button hit to indicate which process, invoked by debugger */ ! 333: struct Proc * ! 334: debug(){ ! 335: debugger=P; ! 336: } ! 337: struct Proc * ! 338: getproc(){ ! 339: register Layer *l; ! 340: struct Proc *z=0; ! 341: cursswitch(&bullseye); ! 342: buttons(DOWN); ! 343: if(button3() && (l=whichlayer())) ! 344: z=&proctab[whichproc(l)]; ! 345: buttons(UP); ! 346: return z; ! 347: } ! 348: struct Proc * ! 349: getproctab(){ ! 350: return proctab; ! 351: } ! 352: char *menutext[]={ ! 353: "New", "Reshape", "Move", "Top", "Bottom", "Current", ! 354: "Delete", 0 ! 355: }; ! 356: int (*menufn[])()={ ! 357: New, Reshape,Move, Top, Bottom, Current, ! 358: Delete, 0, ! 359: }; ! 360: Menu windowmenu={ menutext }; ! 361: dobutton(b) ! 362: { ! 363: register hit; ! 364: register Layer *l; ! 365: switch(b){ ! 366: case 1: ! 367: if(l=whichlayer()){ ! 368: upfront(l); ! 369: tolayer(l); ! 370: } ! 371: break; ! 372: case 2: ! 373: break; /* dunno... */ ! 374: case 3: ! 375: if((hit=menuhit(&windowmenu, 3))>=0){ ! 376: if(hit==0) /* a little different because of getrect */ ! 377: New(); ! 378: else{ ! 379: cursswitch(&bullseye); ! 380: buttons(DOWN); ! 381: if(button3()) ! 382: (*menufn[hit])(); ! 383: cursswitch((Texture *)0); ! 384: } ! 385: } ! 386: break; ! 387: default: ! 388: break; ! 389: } ! 390: buttons(UP); ! 391: } ! 392: whichproc(l) ! 393: register Layer *l; ! 394: { ! 395: register struct Proc *p; ! 396: for(p=proctab+CONTROL+1; p<proctab+NPROC; p++) ! 397: if(p->layer==l && (p->state&BUSY)) ! 398: return((int)(p-proctab)); ! 399: return(CONTROL+1); /* HELP?? */ ! 400: } ! 401: whichbutton() ! 402: { ! 403: static int which[]={0, 3, 2, 2, 1, 1, 2, 2, }; ! 404: return which[mouse.buttons&7]; ! 405: } ! 406: newwindow(fn) ! 407: int (*fn)(); ! 408: { ! 409: register struct Proc *p; ! 410: Rectangle r; ! 411: ! 412: r=getrect3(); ! 413: cursswitch(&deadmouse); ! 414: if(r.corner.x-r.origin.x>100 && r.corner.y-r.origin.y>40){ ! 415: if(p=newproc(fn)){ /* Assignment = */ ! 416: p->rect=inset(r, INSET); ! 417: if(p->layer=newlayer(r)){ ! 418: muxnewwind(p, C_NEW); ! 419: tolayer(p->layer); ! 420: setrun(p); ! 421: }else ! 422: p->state=0; ! 423: } ! 424: } ! 425: cursswitch((Texture *)0); ! 426: } ! 427: ! 428: void ! 429: sendnchars(n, p) ! 430: int n; char * p; ! 431: { ! 432: register int cc; ! 433: ! 434: do{ ! 435: if((cc=n)>MAXPKTDSIZE-1) ! 436: cc=MAXPKTDSIZE-1; ! 437: Psend((int)(P-proctab), p, cc, C_SENDNCHARS); ! 438: }while(p+=cc, (n-=cc)>0); ! 439: } ! 440: void ! 441: sendwithdelim(n, p) ! 442: int n; char * p; ! 443: { ! 444: register int cc; ! 445: sendnchars(n, p); ! 446: delim(); ! 447: } ! 448: delim(){ ! 449: Psend((int)(P-proctab), (char *)0, 0, C_DELIM); ! 450: } ! 451: short sendbusy; ! 452: ! 453: int ! 454: sendpkt(p, n) ! 455: register char * p; ! 456: register int n; ! 457: { ! 458: register int sr; ! 459: ! 460: static Rectangle r={0, 0, 50, 50}; ! 461: ! 462: while(sendbusy) ! 463: sw(1); ! 464: sendbusy=1; ! 465: while(OUTQUEUE.c_cc>CBSIZE/2) ! 466: sw(1); ! 467: if (*p & P_CNTL) ! 468: OUTQUEUE.state |= QPRIORITY; ! 469: do ! 470: if (!qputc(&OUTQUEUE, *(unsigned char *)p++)) { ! 471: rectf(&display, r, F_XOR); ! 472: if ((r.origin.y += 50) >= 1000) ! 473: r.origin.y = 0; ! 474: r.corner.y = r.origin.y + 50; ! 475: } ! 476: while(--n); ! 477: OUTQUEUE.state &= ~QPRIORITY; ! 478: sendbusy=0; ! 479: aciatrint(); ! 480: return 0; ! 481: } ! 482: ! 483: muxnewwind(p, c) ! 484: register struct Proc *p; ! 485: char c; ! 486: { ! 487: char mesg[6]; ! 488: register int dx, dy; ! 489: register char * cp = mesg; ! 490: ! 491: dx=p->rect.corner.x-p->rect.origin.x; ! 492: dy=p->rect.corner.y-p->rect.origin.y; ! 493: *cp++=(dx-6)/p->defaultfont->info['0'].width; ! 494: *cp++=(dy-6)/p->defaultfont->height; ! 495: *cp++=dx; ! 496: *cp++=(dx>>8); ! 497: *cp++=dy; ! 498: *cp++=(dy>>8); ! 499: Psend((int)(p-proctab), mesg, sizeof mesg, c); ! 500: } ! 501: int ! 502: muxsendchar(c, p) ! 503: char c; ! 504: struct Proc *p; ! 505: { ! 506: if(sendbusy || (OUTQUEUE.c_cc >= (CBSIZE/2))) ! 507: return -1; /* avoid "sw" in "sendpkt" */ ! 508: return psend((int)(p-proctab), &c, 1, C_SENDCHAR); ! 509: } ! 510: int ! 511: muxkill(s, p) ! 512: char s; ! 513: struct Proc *p; ! 514: { ! 515: Psend((int)(p-proctab), &s, 1, C_KILL); ! 516: } ! 517: muxmesg(w, m){ ! 518: Psend(w, (char *)0, 0, m); ! 519: } ! 520: muxublk(p) ! 521: register struct Proc *p; ! 522: { ! 523: register int l = p-proctab; ! 524: ! 525: while(pconvs[l].user > 0){ ! 526: pconvs[l].user--; ! 527: Psend(l, (char *)0, 0, C_UNBLK); ! 528: } ! 529: } ! 530: Point ! 531: jline(p, dp) ! 532: Point p, dp; ! 533: { ! 534: dp.x+=p.x; ! 535: dp.y+=p.y; ! 536: segment(&display, p, dp, F_XOR); ! 537: return dp; ! 538: } ! 539: outline(r) ! 540: Rectangle r; ! 541: { ! 542: register dx=r.corner.x-r.origin.x-1, dy=r.corner.y-r.origin.y-1; ! 543: Point p; ! 544: p=jline(r.origin, Pt(dx, 0)); ! 545: p=jline(p, Pt(0, dy)); ! 546: p=jline(p, Pt(-dx,0)); ! 547: (void)jline(p, Pt(0,-dy)); ! 548: } ! 549: min(a, b){ ! 550: return(a<b? a : b); ! 551: } ! 552: max(a, b){ ! 553: return(a>b? a : b); ! 554: } ! 555: Layer * ! 556: whichlayer() ! 557: { ! 558: register Layer *lp; ! 559: for(lp=lfront; lp; lp=lp->back) ! 560: if(ptinrect(mouse.xy, lp->rect)) ! 561: return(lp); ! 562: return(0); ! 563: } ! 564: tolayer(l) ! 565: register Layer *l; ! 566: { ! 567: register struct Proc *p, *okbdproc; ! 568: for(p=proctab; p<&proctab[NPROC]; p++) ! 569: if((p->state&BUSY) && l==p->layer){ ! 570: if(kbdproc!=p){ ! 571: okbdproc=kbdproc; ! 572: kbdproc=p; ! 573: if(okbdproc){ ! 574: setborder(okbdproc); ! 575: okbdproc->state&=~GOTMOUSE; ! 576: } ! 577: setborder(p); ! 578: } ! 579: if(p->state&MOUSELOCAL){ ! 580: p->state|=GOTMOUSE; ! 581: setrun(p); ! 582: } ! 583: break; ! 584: } ! 585: } ! 586: clear(r, inh) ! 587: Rectangle r; ! 588: { ! 589: if(inh) ! 590: cursinhibit(); ! 591: lrectf(P->layer, r, F_CLR); ! 592: if(inh) ! 593: cursallow(); ! 594: } ! 595: border(l, r, i, c) /* no flashing! */ ! 596: register Layer *l; ! 597: Rectangle r; ! 598: register i; ! 599: Code c; ! 600: { ! 601: Urectf(l, Rect(r.origin.x, r.origin.y, r.corner.x, r.origin.y+i), c); ! 602: Urectf(l, Rect(r.origin.x, r.corner.y-i, r.corner.x, r.corner.y), c); ! 603: Urectf(l, Rect(r.origin.x, r.origin.y+i, r.origin.x+i, r.corner.y-i), c); ! 604: Urectf(l, Rect(r.corner.x-i, r.origin.y+i, r.corner.x, r.corner.y-i), c); ! 605: } ! 606: setborder(p) ! 607: register struct Proc *p; ! 608: { ! 609: border(p->layer, p->layer->rect, INSET, F_OR); ! 610: if(p!=kbdproc) ! 611: border(p->layer, inset(p->layer->rect, 1), INSET-1, F_XOR); ! 612: } ! 613: cansend(channel) ! 614: { ! 615: register i; ! 616: register Pch_p pcp=&pconvs[channel]; ! 617: register Pks_p psp; ! 618: for(psp=pcp->nextpkt,i=NPCBUFS; i--;){ ! 619: if(psp->state!=PX_WAIT) ! 620: return SEND; ! 621: if(++psp>=&pcp->pkts[NPCBUFS]) ! 622: psp=pcp->pkts; ! 623: } ! 624: return 0; ! 625: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.