#define HSIZE 3 /* Type + short count */
Header h;
uchar indata[DATASIZE+1]; /* room for NUL */
uchar outdata[DATASIZE];
short outcount;
int hversion;
int exiting;
void inmesg(Hmesg, int);
int inshort(int);
long inlong(int);
vlong invlong(int);
void hsetdot(int, long, long);
void hmoveto(int, long);
void hsetsnarf(int);
void hplumb(int);
void clrlock(void);
int snarfswap(char*, int, char**);
void
rcv(void)
{
int c;
static state = 0;
static count = 0;
static i = 0;
static int errs = 0;
void
inmesg(Hmesg type, int count)
{
Text *t;
int i, m;
long l;
Flayer *lp;
m = inshort(0);
l = inlong(2);
switch(type){
case -1:
panic("rcv error");
default:
fprint(2, "type %d\n", type);
panic("rcv unknown");
case Hversion:
hversion = m;
break;
case Hbindname:
l = invlong(2); /* for 64-bit pointers */
if((i=whichmenu(m)) < 0)
break;
/* in case of a race, a bindname may already have occurred */
if((t=whichtext(m)) == 0)
t=(Text *)l;
else /* let the old one win; clean up the new one */
while(((Text *)l)->nwin>0)
closeup(&((Text *)l)->l[((Text *)l)->front]);
text[i] = t;
text[i]->tag = m;
break;
case Hcurrent:
if(whichmenu(m)<0)
break;
t = whichtext(m);
i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag;
if(t==0 && (t = sweeptext(0, m))==0)
break;
if(t->l[t->front].textfn==0)
panic("Hcurrent");
lp = &t->l[t->front];
if(i){
flupfront(lp);
flborder(lp, 0);
work = lp;
}else
current(lp);
break;
case Hmovname:
if((m=whichmenu(m)) < 0)
break;
t = text[m];
l = tag[m];
i = name[m][0];
text[m] = 0; /* suppress panic in menudel */
menudel(m);
if(t == &cmd)
m = 0;
else{
if (nname>0 && text[0]==&cmd)
m = 1;
else m = 0;
for(; m<nname; m++)
if(strcmp((char*)indata+2, (char*)name[m]+1)<0)
break;
}
menuins(m, indata+2, t, i, (int)l);
break;
case Hgrow:
if(whichmenu(m) >= 0)
hgrow(m, l, inlong(6), 1);
break;
void
hmoveto(int m, long p0)
{
Text *t = whichtext(m);
Flayer *l = &t->l[t->front];
if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)
outTsll(Torigin, m, p0, 2L);
}
void
hcheck(int m)
{
Flayer *l;
Text *t;
int reqd = 0, i;
long n, nl, a;
Rune *r;
if(m == Untagged)
return;
t = whichtext(m);
if(t == 0) /* possible in a half-built window */
return;
for(l = &t->l[0], i = 0; i<NL; i++, l++){
if(l->textfn==0 || !flprepare(l)) /* BUG: don't
need this if BUG below
is fixed */
continue;
a = t->l[i].origin;
n = rcontig(&t->rasp, a, a+l->f.nchars, 1);
if(n<l->f.nchars) /* text missing in middle of screen */
a+=n;
else{ /* text missing at end of screen? */
Again:
if(l->f.lastlinefull)
goto Checksel; /* all's well */
a = t->l[i].origin+l->f.nchars;
n = t->rasp.nrunes-a;
if(n==0)
goto Checksel;
if(n>TBLOCKSIZE)
n = TBLOCKSIZE;
n = rcontig(&t->rasp, a, a+n, 1);
if(n>0){
rload(&t->rasp, a, a+n, 0);
nl = l->f.nchars;
r = scratch;
flinsert(l, r, r+n, l->origin+nl);
if(nl == l->f.nchars) /* made no progress */
goto Checksel;
goto Again;
}
}
if(!reqd){
n = rcontig(&t->rasp, a, a+TBLOCKSIZE, 0);
if(n <= 0)
panic("hcheck request==0");
outTsls(Trequest, m, a, (int)n);
outTs(Tcheck, m);
t->lock++; /* for the Trequest */
t->lock++; /* for the Tcheck */
reqd++;
}
Checksel:
flsetselect(l, l->p0, l->p1);
}
}