|
|
researchv9-SUN3(old)
#include <jerq.h>
#include <font.h>
#include <layer.h>
#include <queue.h>
#include <jerqproc.h>
#include <setup.h>
#include "../msgs.h"
#include "pconfig.h"
#include "proto.h"
#include "packets.h"
struct Pchannel pconvs[16]; /* Should be NPROC!!! */
extern struct Proc *debugger;
extern int recvchars(), sendpkt();
extern boot();
short usermouse=0; /* kbdproc (a USER proc) has the mouse under its paw */
extern short second;
#define crecvchars recvchars
struct Pconfig pconfig={
sendpkt,
recvchars,
(void(*)())crecvchars
};
Texture cup = {
0x0100, 0x00E0, 0x0010, 0x03E0, 0x0400, 0x0FE0, 0x123C, 0x1FE2,
0x101A, 0x101A, 0x1002, 0x103C, 0x1810, 0x6FEC, 0x4004, 0x3FF8,
};
Texture deadmouse = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C, 0x0082, 0x0441,
0xFFE1, 0x5FF1, 0x3FFE, 0x17F0, 0x03E0, 0x0000, 0x0000, 0x0000,
};
Texture bullseye = {
0x07E0, 0x1FF8, 0x399C, 0x63C6, 0x6FF6, 0xCDB3, 0xD99B, 0xFFFF,
0xFFFF, 0xD99B, 0xCDB3, 0x6FF6, 0x63C6, 0x399C, 0x1FF8, 0x07E0,
};
Texture boxcurs = {
0x43FF, 0xE001, 0x7001, 0x3801, 0x1D01, 0x0F01, 0x8701, 0x8F01,
0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0xFFFF,
};
Texture eightball = {
0x07E0, 0x1FF8, 0x21FC, 0x4CFE, 0x52FE, 0xCCFF, 0xD2FF, 0xCCFF,
0xE1FF, 0xFFFF, 0xFFFF, 0x7FFE, 0x7FFE, 0x3FFC, 0x1FF8, 0x07E0,
};
#define INSET 3
Layer *whichlayer();
struct Proc *kbdproc=0;
#define DEMUX 0
#define CONTROL 1
#define UP 0
#define DOWN 1
int control(), windowproc(), demux();
struct Mouse mouse;
main(){
register struct Proc *p;
*DADDR=0;
BonW();
qinit();
aciainit(baud_speeds[VALBAUD]);
binit();
kbdinit();
cursinit();
if(VALMAXADDR){ /* 1024Kb */
NPROC=16;
p=proctab+NPROC;
allocinit(((char *)p), ((char *)p)+256*1024L);
}else{ /* 256Kb */
NPROC=7;
p=proctab+NPROC;
allocinit(((char *)p), ((char *)p)+25*1024L);
}
gcinit();
bufinit();
if(pinit(NPROC)==-1)
error("pinit", "-1");
Lgrey(&display);
spl0();
swinit();
P=newproc(demux); /* process 0 */
setrun(newproc(control)); /* process 1 */
/*
* sw(0) will switch out of our local stack onto the control stack.
* we will never return to this stack
*/
sw(0);
/*NOTREACHED*/
}
buttons(updown)
{
do; while((button123()!=0) != updown);
}
Sw()
{
if(second){
second=0;
if(Ptflag)
ptimeout();
}
sw(P!=&proctab[CONTROL]); /* if control, clock will restart us */
}
control(){
register Layer *lp;
register struct Proc *p, *pp;
for(;;){
pp=0;
lp=whichlayer();
for(p=&proctab[CONTROL+1]; p<&proctab[NPROC]; p++){
if(p->state&WAKEUP){
p->state&=~WAKEUP;
setrun(p);
}
if((p->state&KBDLOCAL)==0 && p->kbdqueue.c_cc>0
&& p->text!=(char *)boot){
register c=qpeekc(&p->kbdqueue);
if(c==0x80){ /* BREAKKEY */
if(muxkill(2, p)!=-1)
(void)qgetc(&p->kbdqueue);
}else if(muxsendchar(c, p)!=-1)
(void)qgetc(&p->kbdqueue);
}
if(lp && p->layer==lp)
pp=p; /* pp pointed at by mouse */
}
if(usermouse && (pp!=kbdproc || (pp->state&GOTMOUSE)==0)){
usermouse=0;
cursswitch((Texture *)0);
cursallow();
}else if(!usermouse && pp){
Check_mouse: if(pp==kbdproc && (pp->state&GOTMOUSE)){
usermouse=1;
cursswitch(pp->cursor);
if(pp->inhibited)
cursinhibit();
}
}
if(button123()){
if(lp==0 || (pp->state&GOTMOUSE)==0){
dobutton(whichbutton());
/* make sure kbdproc doesn't think
buttons are down */
if(kbdproc){
givemouse(kbdproc);
goto Check_mouse; /* usermouse==0 */
}
}
if(pp && pp->state&GOTMOUSE)
givemouse(pp);
}
if(RCVQUEUE.c_cc)
setrun(&proctab[DEMUX]);
Sw();
}
}
New(){
newwindow(windowproc);
}
Psend(a, b, c, d)
char *b;
{
while(psend(a, b, c, d)==-1)
Sw();
}
Delete(){
delete(whichlayer());
}
delete(l)
register Layer *l;
{
register struct Proc *p;
register w;
if(l){
w=whichproc(l);
p= &proctab[w];
muxmesg(w, C_DELETE);
delproc(p);
dellayer(l);
if(kbdproc==p)
kbdproc=0;
}
}
delproc(p)
register struct Proc *p;
{
p->state=0; /* exit(w) */
p->nticks=0;
p->inhibited=0;
qclear(&p->kbdqueue);
freemem(p);
p->layer=0; /* sigh */
}
Top(){
upfront(whichlayer());
}
Bottom(){
downback(whichlayer());
}
Current(){
register Layer *l;
l=whichlayer();
if(l)
tolayer(l);
}
Rectangle
canon(p1, p2)
Point p1, p2;
{
Rectangle r;
r.origin.x = min(p1.x, p2.x);
r.origin.y = min(p1.y, p2.y);
r.corner.x = max(p1.x, p2.x);
r.corner.y = max(p1.y, p2.y);
return(r);
}
Rectangle
getrectb(n)
int n;
{
Rectangle r;
Point p1, p2;
cursswitch(&boxcurs);
buttons(UP);
buttons(DOWN);
if(!(mouse.buttons&n)){
r.origin.x=r.origin.y=r.corner.x=r.corner.y=0;
buttons(UP);
goto Return;
}
p1=mouse.xy;
p2=p1;
r=canon(p1, p2);
outline(r);
for(; mouse.buttons&n; nap(2)){
outline(r);
p2=mouse.xy;
r=canon(p1, p2);
outline(r);
}
outline(r); /* undraw for the last time */
Return:
cursswitch((P->state&USER)? P->cursor : (Texture *)0);
return r;
}
Rectangle
getrect(n)
{
return getrectb(8>>n);
}
Reshape(){
register Layer *l;
register struct Proc *p;
Rectangle r;
Point save; /*SFBOTCH*/
l=whichlayer();
if(l==0)
return;
p= &proctab[whichproc(l)];
r=getrect3();
if(r.corner.x-r.origin.x>100 && r.corner.y-r.origin.y>40){
/*SFBOTCHPoint save;*/
save=l->rect.origin;
dellayer(l);
p->state&=~MOVED;
p->state|=RESHAPED;
l=newlayer(r);
if(l==0){
r.origin=save;
r.corner=add(save, Pt(100, 50));
l=newlayer(r);
if(l==0){ /* oh shit */
delproc(p);
muxmesg((int)(p-proctab), C_DELETE);
return;
}
}
p->layer=l;
p->rect=inset(r, INSET);
setborder(p);
}
if(p->state&USER)
setdata(p);
muxnewwind(p, C_RESHAPE);
}
Move(){
register Layer *l, *nl;
register struct Proc *procp;
Point p, op, dp;
l=whichlayer();
if(l==0)
return;
procp= &proctab[whichproc(l)];
dp=sub(l->rect.corner, l->rect.origin);
cursset(l->rect.origin);
cursswitch(&boxcurs);
p=l->rect.origin;
while(button3()){
if(button12())
goto Return;
outline(Rpt(p, add(p, dp)));
nap(2);
op=p;
p=mouse.xy;
/* using boxcurs, can't get off top or left! */
if(p.x+dp.x >= XMAX-9)
p.x=XMAX-9-dp.x;
if(p.y+dp.y >= YMAX-9)
p.y=YMAX-9-dp.y;
outline(Rpt(op, add(op, dp)));
cursset(p);
}
cursswitch(&deadmouse);
nl=newlayer(Rpt(p, add(p, dp)));
if(nl==0)
goto Return;
Ubitblt(l, l->rect, nl, p, F_STORE);
procp->layer=nl;
procp->rect=inset(nl->rect, INSET);
dellayer(l);
if(procp->state&USER)
setdata(procp);
if((procp->state&RESHAPED) == 0)
procp->state|=MOVED|RESHAPED; /* turn on RESHAPED for old progs */
l=nl;
setborder(procp);
Return:
cursset(div(add(l->rect.origin, l->rect.corner), 2));
cursswitch((Texture *)0);
/* No C_RESHAPE required */
}
/* button hit to indicate which process, invoked by debugger */
struct Proc *
debug(){
debugger=P;
}
struct Proc *
getproc(){
register Layer *l;
struct Proc *z=0;
cursswitch(&bullseye);
buttons(DOWN);
if(button3() && (l=whichlayer()))
z=&proctab[whichproc(l)];
buttons(UP);
return z;
}
struct Proc *
getproctab(){
return proctab;
}
char *menutext[]={
"New", "Reshape", "Move", "Top", "Bottom", "Current",
"Delete", 0
};
int (*menufn[])()={
New, Reshape,Move, Top, Bottom, Current,
Delete, 0,
};
Menu windowmenu={ menutext };
dobutton(b)
{
register hit;
register Layer *l;
switch(b){
case 1:
if(l=whichlayer()){
upfront(l);
tolayer(l);
}
break;
case 2:
break; /* dunno... */
case 3:
if((hit=menuhit(&windowmenu, 3))>=0){
if(hit==0) /* a little different because of getrect */
New();
else{
cursswitch(&bullseye);
buttons(DOWN);
if(button3())
(*menufn[hit])();
cursswitch((Texture *)0);
}
}
break;
default:
break;
}
buttons(UP);
}
whichproc(l)
register Layer *l;
{
register struct Proc *p;
for(p=proctab+CONTROL+1; p<proctab+NPROC; p++)
if(p->layer==l && (p->state&BUSY))
return((int)(p-proctab));
return(CONTROL+1); /* HELP?? */
}
whichbutton()
{
static int which[]={0, 3, 2, 2, 1, 1, 2, 2, };
return which[mouse.buttons&7];
}
newwindow(fn)
int (*fn)();
{
register struct Proc *p;
Rectangle r;
r=getrect3();
cursswitch(&deadmouse);
if(r.corner.x-r.origin.x>100 && r.corner.y-r.origin.y>40){
if(p=newproc(fn)){ /* Assignment = */
p->rect=inset(r, INSET);
if(p->layer=newlayer(r)){
muxnewwind(p, C_NEW);
tolayer(p->layer);
setrun(p);
}else
p->state=0;
}
}
cursswitch((Texture *)0);
}
void
sendnchars(n, p)
int n; char * p;
{
register int cc;
do{
if((cc=n)>MAXPKTDSIZE-1)
cc=MAXPKTDSIZE-1;
Psend((int)(P-proctab), p, cc, C_SENDNCHARS);
}while(p+=cc, (n-=cc)>0);
}
void
sendwithdelim(n, p)
int n; char * p;
{
register int cc;
sendnchars(n, p);
delim();
}
delim(){
Psend((int)(P-proctab), (char *)0, 0, C_DELIM);
}
short sendbusy;
int
sendpkt(p, n)
register char * p;
register int n;
{
register int sr;
static Rectangle r={0, 0, 50, 50};
while(sendbusy)
sw(1);
sendbusy=1;
while(OUTQUEUE.c_cc>CBSIZE/2)
sw(1);
if (*p & P_CNTL)
OUTQUEUE.state |= QPRIORITY;
do
if (!qputc(&OUTQUEUE, *(unsigned char *)p++)) {
rectf(&display, r, F_XOR);
if ((r.origin.y += 50) >= 1000)
r.origin.y = 0;
r.corner.y = r.origin.y + 50;
}
while(--n);
OUTQUEUE.state &= ~QPRIORITY;
sendbusy=0;
aciatrint();
return 0;
}
muxnewwind(p, c)
register struct Proc *p;
char c;
{
char mesg[6];
register int dx, dy;
register char * cp = mesg;
dx=p->rect.corner.x-p->rect.origin.x;
dy=p->rect.corner.y-p->rect.origin.y;
*cp++=(dx-6)/p->defaultfont->info['0'].width;
*cp++=(dy-6)/p->defaultfont->height;
*cp++=dx;
*cp++=(dx>>8);
*cp++=dy;
*cp++=(dy>>8);
Psend((int)(p-proctab), mesg, sizeof mesg, c);
}
int
muxsendchar(c, p)
char c;
struct Proc *p;
{
if(sendbusy || (OUTQUEUE.c_cc >= (CBSIZE/2)))
return -1; /* avoid "sw" in "sendpkt" */
return psend((int)(p-proctab), &c, 1, C_SENDCHAR);
}
int
muxkill(s, p)
char s;
struct Proc *p;
{
Psend((int)(p-proctab), &s, 1, C_KILL);
}
muxmesg(w, m){
Psend(w, (char *)0, 0, m);
}
muxublk(p)
register struct Proc *p;
{
register int l = p-proctab;
while(pconvs[l].user > 0){
pconvs[l].user--;
Psend(l, (char *)0, 0, C_UNBLK);
}
}
Point
jline(p, dp)
Point p, dp;
{
dp.x+=p.x;
dp.y+=p.y;
segment(&display, p, dp, F_XOR);
return dp;
}
outline(r)
Rectangle r;
{
register dx=r.corner.x-r.origin.x-1, dy=r.corner.y-r.origin.y-1;
Point p;
p=jline(r.origin, Pt(dx, 0));
p=jline(p, Pt(0, dy));
p=jline(p, Pt(-dx,0));
(void)jline(p, Pt(0,-dy));
}
min(a, b){
return(a<b? a : b);
}
max(a, b){
return(a>b? a : b);
}
Layer *
whichlayer()
{
register Layer *lp;
for(lp=lfront; lp; lp=lp->back)
if(ptinrect(mouse.xy, lp->rect))
return(lp);
return(0);
}
tolayer(l)
register Layer *l;
{
register struct Proc *p, *okbdproc;
for(p=proctab; p<&proctab[NPROC]; p++)
if((p->state&BUSY) && l==p->layer){
if(kbdproc!=p){
okbdproc=kbdproc;
kbdproc=p;
if(okbdproc){
setborder(okbdproc);
okbdproc->state&=~GOTMOUSE;
}
setborder(p);
}
if(p->state&MOUSELOCAL){
p->state|=GOTMOUSE;
setrun(p);
}
break;
}
}
clear(r, inh)
Rectangle r;
{
if(inh)
cursinhibit();
lrectf(P->layer, r, F_CLR);
if(inh)
cursallow();
}
border(l, r, i, c) /* no flashing! */
register Layer *l;
Rectangle r;
register i;
Code c;
{
Urectf(l, Rect(r.origin.x, r.origin.y, r.corner.x, r.origin.y+i), c);
Urectf(l, Rect(r.origin.x, r.corner.y-i, r.corner.x, r.corner.y), c);
Urectf(l, Rect(r.origin.x, r.origin.y+i, r.origin.x+i, r.corner.y-i), c);
Urectf(l, Rect(r.corner.x-i, r.origin.y+i, r.corner.x, r.corner.y-i), c);
}
setborder(p)
register struct Proc *p;
{
border(p->layer, p->layer->rect, INSET, F_OR);
if(p!=kbdproc)
border(p->layer, inset(p->layer->rect, 1), INSET-1, F_XOR);
}
cansend(channel)
{
register i;
register Pch_p pcp=&pconvs[channel];
register Pks_p psp;
for(psp=pcp->nextpkt,i=NPCBUFS; i--;){
if(psp->state!=PX_WAIT)
return SEND;
if(++psp>=&pcp->pkts[NPCBUFS])
psp=pcp->pkts;
}
return 0;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.