File:  [Research Unix] / researchv9 / jerq / src / sam / term / mesg.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#include "samterm.h"

#define	HSIZE	3	/* Type + short count */
Header	h;
uchar	indata[DATASIZE];
uchar	outdata[DATASIZE];
short	outcount;
long	inlong();
Text	*sweeptext();
rcv(){
	register c;
	static state=0;
	static count=0;
	static i=0;
	while((c=rcvchar())!=-1)
		switch(state){
		case 0:
			h.type=c;
			state++;
			break;
		case 1:
			h.count0=c;
			state++;
			break;
		case 2:
			h.count1=c;
			count=h.count0|(h.count1<<8);
			i=0;
			if(count>DATASIZE)
				panic("count>DATASIZE");
			if(count==0)
				goto zerocount;
			state++;
			break;
		case 3:
			indata[i++]=c;
			if(i==count){
		zerocount:
				inmesg(h.type, count);
				state=count=0;
				continue;
			}
			break;
		}
}
Text *
whichtext(tg)
	register tg;
{
	register i;
	for(i=0; i<nname; i++)
		if(tag[i]==tg)
			return text[i];
	panic("whichtext");
	return 0;
}
inmesg(type, count)
	Hmesg type;
{
	register Text *t;
	register i, m;
	register long l;
	register Flayer *lp;
	m=inshort(0);
	l=inlong(2);
	switch(type){
	case -1:
		panic("rcv error");
	default:
		panic("rcv unknown");
	case Hnewname:
		menuins(0, (uchar *)"", (Text *)0, ' ', m);
		break;
	case Hdelname:
		if((m=whichmenu(m))>=0)
			menudel(m);
		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{
			for(m=nname>0 && text[0]==&cmd; m<nname; m++)
				if(strcmp(indata+2, name[m]+1)<0)
					break;
		}
		menuins(m, indata+2, t, i, (int)l);
		break;
	case Hbindname:
		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)
				close(&((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 Hgrow:
		if(whichmenu(m)>=0)
			hgrow(m, l, inlong(6), 1);
		break;
	case Hdata:
		if(whichmenu(m)>=0)
			hdata(m, l, indata+6, count-7);
	Checkscroll:
		if(m==cmd.tag)
			for(i=0; i<NL; i++){
				lp=&cmd.l[i];
				if(lp->textfn && lp->user0)
					center(lp, l+1);
			}
		break;
	case Hgrowdata:
		if(whichmenu(m)<0)
			break;
		hgrow(m, l, inlong(6), 0);
		whichtext(m)->lock++;	/* fake the request */
		hdata(m, l, indata+10, count-11);
		goto Checkscroll;
	case Hcut:
		if(whichmenu(m)>=0)
			hcut(m, l, inlong(6));
		break;
	case Hclean:
		if((m=whichmenu(m))>=0)
			name[m][0]=' ';
		break;
	case Hdirty:
		if((m=whichmenu(m))>=0)
			name[m][0]='\'';
		break;
	case Hcheck0:
		if(whichmenu(m)>=0)
			outTs(Tcheck, m);
		break;
	case Hcheck:
		if(whichmenu(m)>=0)
			hcheck(m);
		break;
	case Hmoveto:
		if(whichmenu(m)>=0)
			hmoveto(m, l);
		break;
	case Hsetdot:
		if(whichmenu(m)>=0)
			hsetdot(m, l, inlong(6));
		break;
	case Horigin:
		if(whichmenu(m)>=0)
			horigin(m, l);
		break;
	case Hclose:
		if(whichmenu(m)<0 || (t=whichtext(m))==0)
			break;
		for(i=0,lp=t->l; i<NL; i++,lp++)
			if(lp->textfn)
				close(lp);
		break;
	case Hunlock:
		clrlock();
		break;
	case Hsetpat:
		setpat((char *)indata);
		break;
	case Hunlockfile:
		if(whichmenu(m)>=0 && (t=whichtext(m))->lock)
			--t->lock;
		break;
	case Hsetsnarf:
		hsetsnarf(m);
		break;
	case Hsnarflen:
		snarflen=inlong(0);
		break;
	case Hexit:
		outT0(Texit);
		break;
	}
}
setlock(){
	lock++;
	cursswitch(cursor=&lockarrow);
}
clrlock(){
	lock=0;
	cursswitch(cursor=(Texture *)0);
}
startfile(t)
	Text *t;
{
	outTsl(Tstartfile, t->tag, (long)t);
	outTs(Tunlockfile, t->tag);
	t->lock++;
}
startnewfile(type, t)
	Text *t;
{
	t->tag=Untagged;
	outTl(type, (long)t);
}
inshort(n)
{
	return indata[n]|(indata[n+1]<<8);
}
long
inlong(n)
{
	return indata[n]|(indata[n+1]<<8)|
		((long)indata[n+2]<<16)|((long)indata[n+3]<<24);
}
outT0(type)
	Tmesg type;
{
	outstart(type);
	outsend();
}
outTl(type, l)
	Tmesg type;
	long l;
{
	outstart(type);
	outlong(l);
	outsend();
}
outTs(type, s)
	Tmesg type;
{
	outstart(type);
	outshort(s);
	outsend();
}
outTss(type, s1, s2)
	Tmesg type;
{
	outstart(type);
	outshort(s1);
	outshort(s2);
	outsend();
}
outTsll(type, s1, l1, l2)
	Tmesg type;
	long l1, l2;
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outlong(l2);
	outsend();
}
outTsl(type, s1, l1)
	Tmesg type;
	long l1;
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outsend();
}
outTslS(type, s1, l1, s)
	Tmesg type;
	long l1;
	uchar *s;
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outcopy(strlen(s)+1, s);
	outsend();
}
outTsls(type, s1, l1, s2)
	Tmesg type;
	long l1;
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outshort(s2);
	outsend();
}
outstart(type)
	Tmesg type;
{
	outdata[0]=type;
	outcount=0;
}
outcopy(count, data)
	register uchar *data;
{
	while(count--)
		outdata[HSIZE+outcount++]=*data++;	
}
outshort(s)
{
	uchar buf[2];
	buf[0]=s;
	buf[1]=s>>8;
	outcopy(2, buf);
}
outlong(l)
	long l;
{
	uchar buf[4];
	buf[0]=l;
	buf[1]=l>>8;
	buf[2]=l>>16;
	buf[3]=l>>24;
	outcopy(4, buf);
}
outsend()
{
	if(outcount>sizeof outdata-HSIZE)
		panic("outcount>sizeof outdata");
	outdata[1]=outcount;
	outdata[2]=outcount>>8;
	sendnchars(outcount+HSIZE, (char *)outdata);
}
hsetdot(m, p0, p1)
	register long p0, p1;
{
	register Text *t=whichtext(m);
	register Flayer *l=&t->l[t->front];
	flsetselect(l, p0, p1);
}
horigin(m, p0)
	register long p0;
{
	register Text *t=whichtext(m);
	register Flayer *l=&t->l[t->front];
	register long a;
	if(!flprepare(l)){
		l->origin=p0;
		return;
	}
	a=p0-l->origin;
	if(a>=0 && a<l->f.nchars)
		frdelete(&l->f, (Posn)0, (Posn)a);
	else if(a<0 && -a<l->f.nchars)
		frinsert(&l->f, rload(&t->rasp, p0, l->origin), 0);
	else
		frdelete(&l->f, (Posn)0, l->f.nchars);
	l->origin=p0;
	scrdraw(l, t->rasp.nbytes);
	if(l->visible==Some)
		flrefresh(l, l->entire, 0);
	hcheck(m);
}
hmoveto(m, p0)
	register long p0;
{
	register Text *t=whichtext(m);
	register Flayer *l=&t->l[t->front];
	if(p0<l->origin || p0-l->origin>muldiv(l->f.nchars, 9, 10))
		outTsll(Torigin, m, p0, 2L);
}
hcheck(m)
{
	register Flayer *l;
	register Text *t;
	register reqd=0, i;
	register long n, a;
	if(m==Untagged)
		return;
	t=whichtext(m);
	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.nlines==l->f.maxlines && /* BUG: lastlinefull!! */
		   		ptofchar(&l->f, l->f.nchars).y>=
				  l->f.r.origin.y+l->f.maxlines*l->f.font->height)
				goto Checksel;	/* all's well */
			a=t->l[i].origin+l->f.nchars;
			n=t->rasp.nbytes-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);
				n=l->f.nchars;
				flinsert(l, &scratch, l->origin+n);
				if(n==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++;
			reqd++;
		}
	    Checksel:
		flsetselect(l, l->p0, l->p1);
	}
}
flnewlyvisible(l)
	register Flayer *l;
{
	hcheck(((Text *)l->user1)->tag);
}
hsetsnarf(m){
	struct{
		uchar *s;
		short n;
		short size;
	}s1, s2;
	register c, i;
	cursswitch(&deadmouse);
	s1.s=0;
	s1.n=s1.size=0;
	getmuxbuf(&s1);
	s2.n=s2.size=m;
	GCALLOC(m, &s2.s);
	for(i=0; i<m; i++){
		while((c=rcvchar())<0)
			wait(RCV);
		s2.s[i]=c;
	}
	setmuxbuf(&s2);
	gcfree(s2.s);
	snarflen=s1.n;
	outTs(Tsetsnarf, s1.n);
	sendnchars(s1.n, s1.s);
	gcfree(s1.s);
	cursswitch(cursor);
}
hgrow(m, a, new, req)
	register long a, new;
{
	register i;
	register Flayer *l;
	register Text *t=whichtext(m);
	register long o, b;
	if(new<=0)
		panic("hgrow");
	rresize(&t->rasp, a, 0L, new);
	for(l=&t->l[0], i=0; i<NL; i++, l++){
		if(l->textfn==0)
			continue;
		o=l->origin;
		b=a-o-rmissing(&t->rasp, o, a);
		if(a<o)
			l->origin+=new;
		if(a<l->p0)
			l->p0+=new;
		if(a<l->p1)
			l->p1+=new;
		if(!req || a<o || b>(long)l->f.nchars ||
		    (l->f.nchars==0 && a-o>0))
			continue;
		if(new>TBLOCKSIZE)
			new=TBLOCKSIZE;
		outTsls(Trequest, m, a, (int)new);
		t->lock++;
		req=0;
	}
}
hdata(m, a, s, len)
	register long a;
	uchar *s;
{
	register i;
	register Flayer *l;
	register Text *t=whichtext(m);
	register long o, b;
	if(t->lock)
		--t->lock;
	for(l=&t->l[0], i=0; i<NL; i++, l++){
		if(l->textfn==0)
			continue;
		o=l->origin;
		b=a-o-rmissing(&t->rasp, o, a);
		if(a<o || b>(long)l->f.nchars)
			continue;
		flinsert(l, &s, o+b);
	}
	rdata(&t->rasp, a, a+len, s);
	rclean(&t->rasp);
}
#define	a	A	/* need this line or get 'redeclaration of a' error! */
hcut(m, a, old)
	register long a, old;
{
	register Flayer *l;
	register Text *t=whichtext(m);
	register i;
	register long o, b;
	if(t->lock)
		--t->lock;
	for(l=&t->l[0], i=0; i<NL; i++, l++){
		if(l->textfn==0)
			continue;
		o=l->origin;
		b=a-o-rmissing(&t->rasp, o, a);
		if(b<(long)l->f.nchars && a+old>=o)
			fldelete(l, b<0? o : o+b,
			    a+old-rmissing(&t->rasp, o, a+old));
		if(a+old<o)
			l->origin-=old;
		else if(a<=o)
			l->origin=a;
		if(a+old<l->p0)
			l->p0-=old;
		else if(a<=l->p0)
			l->p0=a;
		if(a+old<l->p1)
			l->p1-=old;
		else if(a<=l->p1)
			l->p1=a;
	}
	rresize(&t->rasp, a, old, 0L);
	rclean(&t->rasp);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.