|
|
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.