xref: /plan9/sys/src/cmd/samterm/mesg.c (revision f7db61556a577f91350f05658e9c0724969b02c3)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <cursor.h>
67dd7cddfSDavid du Colombier #include <mouse.h>
77dd7cddfSDavid du Colombier #include <keyboard.h>
83e12c5d1SDavid du Colombier #include <frame.h>
97dd7cddfSDavid du Colombier #include <plumb.h>
103e12c5d1SDavid du Colombier #include "flayer.h"
113e12c5d1SDavid du Colombier #include "samterm.h"
123e12c5d1SDavid du Colombier 
133e12c5d1SDavid du Colombier #define	HSIZE	3	/* Type + short count */
143e12c5d1SDavid du Colombier Header	h;
153e12c5d1SDavid du Colombier uchar	indata[DATASIZE+1];	/* room for NUL */
163e12c5d1SDavid du Colombier uchar	outdata[DATASIZE];
173e12c5d1SDavid du Colombier short	outcount;
183e12c5d1SDavid du Colombier int	hversion;
19cc81b63cSDavid du Colombier int	exiting;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier void	inmesg(Hmesg, int);
223e12c5d1SDavid du Colombier int	inshort(int);
233e12c5d1SDavid du Colombier long	inlong(int);
2473e742d7SDavid du Colombier vlong	invlong(int);
253e12c5d1SDavid du Colombier void	hsetdot(int, long, long);
263e12c5d1SDavid du Colombier void	hmoveto(int, long);
273e12c5d1SDavid du Colombier void	hsetsnarf(int);
287dd7cddfSDavid du Colombier void	hplumb(int);
293e12c5d1SDavid du Colombier void	clrlock(void);
303e12c5d1SDavid du Colombier int	snarfswap(char*, int, char**);
313e12c5d1SDavid du Colombier 
323e12c5d1SDavid du Colombier void
rcv(void)333e12c5d1SDavid du Colombier rcv(void)
343e12c5d1SDavid du Colombier {
353e12c5d1SDavid du Colombier 	int c;
36*f7db6155SDavid du Colombier 	static int count = 0, errs = 0, i = 0, state = 0;
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier 	while((c=rcvchar()) != -1)
393e12c5d1SDavid du Colombier 		switch(state){
403e12c5d1SDavid du Colombier 		case 0:
413e12c5d1SDavid du Colombier 			h.type = c;
423e12c5d1SDavid du Colombier 			state++;
433e12c5d1SDavid du Colombier 			break;
443e12c5d1SDavid du Colombier 
453e12c5d1SDavid du Colombier 		case 1:
463e12c5d1SDavid du Colombier 			h.count0 = c;
473e12c5d1SDavid du Colombier 			state++;
483e12c5d1SDavid du Colombier 			break;
493e12c5d1SDavid du Colombier 
503e12c5d1SDavid du Colombier 		case 2:
513e12c5d1SDavid du Colombier 			h.count1 = c;
523e12c5d1SDavid du Colombier 			count = h.count0|(h.count1<<8);
533e12c5d1SDavid du Colombier 			i = 0;
543e12c5d1SDavid du Colombier 			if(count > DATASIZE){
553e12c5d1SDavid du Colombier 				if(++errs < 5){
563e12c5d1SDavid du Colombier 					dumperrmsg(count, h.type, h.count0, c);
573e12c5d1SDavid du Colombier 					state = 0;
583e12c5d1SDavid du Colombier 					continue;
593e12c5d1SDavid du Colombier 				}
603e12c5d1SDavid du Colombier 				fprint(2, "type %d count %d\n", h.type, count);
613e12c5d1SDavid du Colombier 				panic("count>DATASIZE");
623e12c5d1SDavid du Colombier 			}
633e12c5d1SDavid du Colombier 			if(count == 0)
643e12c5d1SDavid du Colombier 				goto zerocount;
653e12c5d1SDavid du Colombier 			state++;
663e12c5d1SDavid du Colombier 			break;
673e12c5d1SDavid du Colombier 
683e12c5d1SDavid du Colombier 		case 3:
693e12c5d1SDavid du Colombier 			indata[i++] = c;
703e12c5d1SDavid du Colombier 			if(i == count){
713e12c5d1SDavid du Colombier 		zerocount:
723e12c5d1SDavid du Colombier 				indata[i] = 0;
733e12c5d1SDavid du Colombier 				inmesg(h.type, count);
743e12c5d1SDavid du Colombier 				state = count = 0;
753e12c5d1SDavid du Colombier 				continue;
763e12c5d1SDavid du Colombier 			}
773e12c5d1SDavid du Colombier 			break;
783e12c5d1SDavid du Colombier 		}
793e12c5d1SDavid du Colombier }
803e12c5d1SDavid du Colombier 
813e12c5d1SDavid du Colombier Text *
whichtext(int tg)823e12c5d1SDavid du Colombier whichtext(int tg)
833e12c5d1SDavid du Colombier {
843e12c5d1SDavid du Colombier 	int i;
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier 	for(i=0; i<nname; i++)
873e12c5d1SDavid du Colombier 		if(tag[i] == tg)
883e12c5d1SDavid du Colombier 			return text[i];
893e12c5d1SDavid du Colombier 	panic("whichtext");
903e12c5d1SDavid du Colombier 	return 0;
913e12c5d1SDavid du Colombier }
923e12c5d1SDavid du Colombier 
933e12c5d1SDavid du Colombier void
inmesg(Hmesg type,int count)943e12c5d1SDavid du Colombier inmesg(Hmesg type, int count)
953e12c5d1SDavid du Colombier {
963e12c5d1SDavid du Colombier 	Text *t;
973e12c5d1SDavid du Colombier 	int i, m;
983e12c5d1SDavid du Colombier 	long l;
993e12c5d1SDavid du Colombier 	Flayer *lp;
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier 	m = inshort(0);
1023e12c5d1SDavid du Colombier 	l = inlong(2);
1033e12c5d1SDavid du Colombier 	switch(type){
1043e12c5d1SDavid du Colombier 	case -1:
1053e12c5d1SDavid du Colombier 		panic("rcv error");
1063e12c5d1SDavid du Colombier 	default:
1073e12c5d1SDavid du Colombier 		fprint(2, "type %d\n", type);
1083e12c5d1SDavid du Colombier 		panic("rcv unknown");
1093e12c5d1SDavid du Colombier 
1103e12c5d1SDavid du Colombier 	case Hversion:
1113e12c5d1SDavid du Colombier 		hversion = m;
1123e12c5d1SDavid du Colombier 		break;
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier 	case Hbindname:
115219b2ee8SDavid du Colombier 		l = invlong(2);		/* for 64-bit pointers */
1163e12c5d1SDavid du Colombier 		if((i=whichmenu(m)) < 0)
1173e12c5d1SDavid du Colombier 			break;
1183e12c5d1SDavid du Colombier 		/* in case of a race, a bindname may already have occurred */
1193e12c5d1SDavid du Colombier 		if((t=whichtext(m)) == 0)
1203e12c5d1SDavid du Colombier 			t=(Text *)l;
1213e12c5d1SDavid du Colombier 		else	/* let the old one win; clean up the new one */
1223e12c5d1SDavid du Colombier 			while(((Text *)l)->nwin>0)
1233e12c5d1SDavid du Colombier 				closeup(&((Text *)l)->l[((Text *)l)->front]);
1243e12c5d1SDavid du Colombier 		text[i] = t;
1253e12c5d1SDavid du Colombier 		text[i]->tag = m;
1263e12c5d1SDavid du Colombier 		break;
1273e12c5d1SDavid du Colombier 
1283e12c5d1SDavid du Colombier 	case Hcurrent:
1293e12c5d1SDavid du Colombier 		if(whichmenu(m)<0)
1303e12c5d1SDavid du Colombier 			break;
1313e12c5d1SDavid du Colombier 		t = whichtext(m);
1323e12c5d1SDavid du Colombier 		i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag;
1333e12c5d1SDavid du Colombier 		if(t==0 && (t = sweeptext(0, m))==0)
1343e12c5d1SDavid du Colombier 			break;
1353e12c5d1SDavid du Colombier 		if(t->l[t->front].textfn==0)
1363e12c5d1SDavid du Colombier 			panic("Hcurrent");
1373e12c5d1SDavid du Colombier 		lp = &t->l[t->front];
1383e12c5d1SDavid du Colombier 		if(i){
1393e12c5d1SDavid du Colombier 			flupfront(lp);
1403e12c5d1SDavid du Colombier 			flborder(lp, 0);
1413e12c5d1SDavid du Colombier 			work = lp;
1423e12c5d1SDavid du Colombier 		}else
1433e12c5d1SDavid du Colombier 			current(lp);
1443e12c5d1SDavid du Colombier 		break;
1453e12c5d1SDavid du Colombier 
1463e12c5d1SDavid du Colombier 	case Hmovname:
1473e12c5d1SDavid du Colombier 		if((m=whichmenu(m)) < 0)
1483e12c5d1SDavid du Colombier 			break;
1493e12c5d1SDavid du Colombier 		t = text[m];
1503e12c5d1SDavid du Colombier 		l = tag[m];
1513e12c5d1SDavid du Colombier 		i = name[m][0];
1523e12c5d1SDavid du Colombier 		text[m] = 0;	/* suppress panic in menudel */
1533e12c5d1SDavid du Colombier 		menudel(m);
1543e12c5d1SDavid du Colombier 		if(t == &cmd)
1553e12c5d1SDavid du Colombier 			m = 0;
1563e12c5d1SDavid du Colombier 		else{
1573e12c5d1SDavid du Colombier 			if (nname>0 && text[0]==&cmd)
1583e12c5d1SDavid du Colombier 				m = 1;
1593e12c5d1SDavid du Colombier 			else m = 0;
1603e12c5d1SDavid du Colombier 			for(; m<nname; m++)
1613e12c5d1SDavid du Colombier 				if(strcmp((char*)indata+2, (char*)name[m]+1)<0)
1623e12c5d1SDavid du Colombier 					break;
1633e12c5d1SDavid du Colombier 		}
1643e12c5d1SDavid du Colombier 		menuins(m, indata+2, t, i, (int)l);
1653e12c5d1SDavid du Colombier 		break;
1663e12c5d1SDavid du Colombier 
1673e12c5d1SDavid du Colombier 	case Hgrow:
1683e12c5d1SDavid du Colombier 		if(whichmenu(m) >= 0)
1693e12c5d1SDavid du Colombier 			hgrow(m, l, inlong(6), 1);
1703e12c5d1SDavid du Colombier 		break;
1713e12c5d1SDavid du Colombier 
1723e12c5d1SDavid du Colombier 	case Hnewname:
1733e12c5d1SDavid du Colombier 		menuins(0, (uchar *)"", (Text *)0, ' ', m);
1743e12c5d1SDavid du Colombier 		break;
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier 	case Hcheck0:
177219b2ee8SDavid du Colombier 		i = whichmenu(m);
178219b2ee8SDavid du Colombier 		if(i>=0) {
179219b2ee8SDavid du Colombier 			t = text[i];
180219b2ee8SDavid du Colombier 			if(t)
181219b2ee8SDavid du Colombier 				t->lock++;
1823e12c5d1SDavid du Colombier 			outTs(Tcheck, m);
183219b2ee8SDavid du Colombier 		}
1843e12c5d1SDavid du Colombier 		break;
1853e12c5d1SDavid du Colombier 
1863e12c5d1SDavid du Colombier 	case Hcheck:
187219b2ee8SDavid du Colombier 		i = whichmenu(m);
188219b2ee8SDavid du Colombier 		if(i>=0) {
189219b2ee8SDavid du Colombier 			t = text[i];
190219b2ee8SDavid du Colombier 			if(t && t->lock)
191219b2ee8SDavid du Colombier 				t->lock--;
1923e12c5d1SDavid du Colombier 			hcheck(m);
193219b2ee8SDavid du Colombier 		}
1943e12c5d1SDavid du Colombier 		break;
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier 	case Hunlock:
1973e12c5d1SDavid du Colombier 		clrlock();
1983e12c5d1SDavid du Colombier 		break;
1993e12c5d1SDavid du Colombier 
2003e12c5d1SDavid du Colombier 	case Hdata:
2013e12c5d1SDavid du Colombier 		if(whichmenu(m) >= 0)
2023e12c5d1SDavid du Colombier 			l += hdata(m, l, indata+6, count-6);
2033e12c5d1SDavid du Colombier 	Checkscroll:
2043e12c5d1SDavid du Colombier 		if(m == cmd.tag){
2053e12c5d1SDavid du Colombier 			for(i=0; i<NL; i++){
2063e12c5d1SDavid du Colombier 				lp = &cmd.l[i];
2073e12c5d1SDavid du Colombier 				if(lp->textfn)
2083e12c5d1SDavid du Colombier 					center(lp, l>=0? l : lp->p1);
2093e12c5d1SDavid du Colombier 			}
2103e12c5d1SDavid du Colombier 		}
2113e12c5d1SDavid du Colombier 		break;
2123e12c5d1SDavid du Colombier 
2133e12c5d1SDavid du Colombier 	case Horigin:
2143e12c5d1SDavid du Colombier 		if(whichmenu(m) >= 0)
2153e12c5d1SDavid du Colombier 			horigin(m, l);
2163e12c5d1SDavid du Colombier 		break;
2173e12c5d1SDavid du Colombier 
2183e12c5d1SDavid du Colombier 	case Hunlockfile:
2193e12c5d1SDavid du Colombier 		if(whichmenu(m)>=0 && (t = whichtext(m))->lock){
2203e12c5d1SDavid du Colombier 			--t->lock;
2213e12c5d1SDavid du Colombier 			l = -1;
2223e12c5d1SDavid du Colombier 			goto Checkscroll;
2233e12c5d1SDavid du Colombier 		}
2243e12c5d1SDavid du Colombier 		break;
2253e12c5d1SDavid du Colombier 
2263e12c5d1SDavid du Colombier 	case Hsetdot:
2273e12c5d1SDavid du Colombier 		if(whichmenu(m) >= 0)
2283e12c5d1SDavid du Colombier 			hsetdot(m, l, inlong(6));
2293e12c5d1SDavid du Colombier 		break;
2303e12c5d1SDavid du Colombier 
2313e12c5d1SDavid du Colombier 	case Hgrowdata:
2323e12c5d1SDavid du Colombier 		if(whichmenu(m)<0)
2333e12c5d1SDavid du Colombier 			break;
2343e12c5d1SDavid du Colombier 		hgrow(m, l, inlong(6), 0);
2353e12c5d1SDavid du Colombier 		whichtext(m)->lock++;	/* fake the request */
2363e12c5d1SDavid du Colombier 		l += hdata(m, l, indata+10, count-10);
2373e12c5d1SDavid du Colombier 		goto Checkscroll;
2383e12c5d1SDavid du Colombier 
2393e12c5d1SDavid du Colombier 	case Hmoveto:
2403e12c5d1SDavid du Colombier 		if(whichmenu(m)>=0)
2413e12c5d1SDavid du Colombier 			hmoveto(m, l);
2423e12c5d1SDavid du Colombier 		break;
2433e12c5d1SDavid du Colombier 
2443e12c5d1SDavid du Colombier 	case Hclean:
2453e12c5d1SDavid du Colombier 		if((m = whichmenu(m)) >= 0)
2463e12c5d1SDavid du Colombier 			name[m][0] = ' ';
2473e12c5d1SDavid du Colombier 		break;
2483e12c5d1SDavid du Colombier 
2493e12c5d1SDavid du Colombier 	case Hdirty:
2503e12c5d1SDavid du Colombier 		if((m = whichmenu(m))>=0)
2513e12c5d1SDavid du Colombier 			name[m][0] = '\'';
2523e12c5d1SDavid du Colombier 		break;
2533e12c5d1SDavid du Colombier 
2543e12c5d1SDavid du Colombier 	case Hdelname:
2553e12c5d1SDavid du Colombier 		if((m=whichmenu(m)) >= 0)
2563e12c5d1SDavid du Colombier 			menudel(m);
2573e12c5d1SDavid du Colombier 		break;
2583e12c5d1SDavid du Colombier 
2593e12c5d1SDavid du Colombier 	case Hcut:
2603e12c5d1SDavid du Colombier 		if(whichmenu(m) >= 0)
2613e12c5d1SDavid du Colombier 			hcut(m, l, inlong(6));
2623e12c5d1SDavid du Colombier 		break;
2633e12c5d1SDavid du Colombier 
2643e12c5d1SDavid du Colombier 	case Hclose:
2653e12c5d1SDavid du Colombier 		if(whichmenu(m)<0 || (t = whichtext(m))==0)
2663e12c5d1SDavid du Colombier 			break;
267bd389b36SDavid du Colombier 		l = t->nwin;
268bd389b36SDavid du Colombier 		for(i = 0,lp = t->l; l>0 && i<NL; i++,lp++)
269bd389b36SDavid du Colombier 			if(lp->textfn){
2703e12c5d1SDavid du Colombier 				closeup(lp);
271bd389b36SDavid du Colombier 				--l;
272bd389b36SDavid du Colombier 			}
2733e12c5d1SDavid du Colombier 		break;
2743e12c5d1SDavid du Colombier 
2753e12c5d1SDavid du Colombier 	case Hsetpat:
2763e12c5d1SDavid du Colombier 		setpat((char *)indata);
2773e12c5d1SDavid du Colombier 		break;
2783e12c5d1SDavid du Colombier 
2793e12c5d1SDavid du Colombier 	case Hsetsnarf:
2803e12c5d1SDavid du Colombier 		hsetsnarf(m);
2813e12c5d1SDavid du Colombier 		break;
2823e12c5d1SDavid du Colombier 
2833e12c5d1SDavid du Colombier 	case Hsnarflen:
2843e12c5d1SDavid du Colombier 		snarflen = inlong(0);
2853e12c5d1SDavid du Colombier 		break;
2863e12c5d1SDavid du Colombier 
2873e12c5d1SDavid du Colombier 	case Hack:
2883e12c5d1SDavid du Colombier 		outT0(Tack);
2893e12c5d1SDavid du Colombier 		break;
2903e12c5d1SDavid du Colombier 
2913e12c5d1SDavid du Colombier 	case Hexit:
292cc81b63cSDavid du Colombier 		exiting = 1;
2933e12c5d1SDavid du Colombier 		outT0(Texit);
2947dd7cddfSDavid du Colombier 		threadexitsall(nil);
2957dd7cddfSDavid du Colombier 		break;
2967dd7cddfSDavid du Colombier 
2977dd7cddfSDavid du Colombier 	case Hplumb:
2987dd7cddfSDavid du Colombier 		hplumb(m);
2993e12c5d1SDavid du Colombier 		break;
3003e12c5d1SDavid du Colombier 	}
3013e12c5d1SDavid du Colombier }
3023e12c5d1SDavid du Colombier 
3033e12c5d1SDavid du Colombier void
setlock(void)3043e12c5d1SDavid du Colombier setlock(void)
3053e12c5d1SDavid du Colombier {
3067dd7cddfSDavid du Colombier 	hostlock++;
3077dd7cddfSDavid du Colombier 	setcursor(mousectl, cursor = &lockarrow);
3083e12c5d1SDavid du Colombier }
3093e12c5d1SDavid du Colombier 
3103e12c5d1SDavid du Colombier void
clrlock(void)3113e12c5d1SDavid du Colombier clrlock(void)
3123e12c5d1SDavid du Colombier {
3133e12c5d1SDavid du Colombier 	hasunlocked = 1;
3147dd7cddfSDavid du Colombier 	if(hostlock > 0)
3157dd7cddfSDavid du Colombier 		hostlock--;
3167dd7cddfSDavid du Colombier 	if(hostlock == 0)
3177dd7cddfSDavid du Colombier 		setcursor(mousectl, cursor=(Cursor *)0);
3183e12c5d1SDavid du Colombier }
3193e12c5d1SDavid du Colombier 
3203e12c5d1SDavid du Colombier void
startfile(Text * t)3213e12c5d1SDavid du Colombier startfile(Text *t)
3223e12c5d1SDavid du Colombier {
32373e742d7SDavid du Colombier 	outTsv(Tstartfile, t->tag, (vlong)t);	/* for 64-bit pointers */
3243e12c5d1SDavid du Colombier 	setlock();
3253e12c5d1SDavid du Colombier }
3263e12c5d1SDavid du Colombier 
3273e12c5d1SDavid du Colombier void
startnewfile(int type,Text * t)3283e12c5d1SDavid du Colombier startnewfile(int type, Text *t)
3293e12c5d1SDavid du Colombier {
3303e12c5d1SDavid du Colombier 	t->tag = Untagged;
33173e742d7SDavid du Colombier 	outTv(type, (vlong)t);			/* for 64-bit pointers */
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier 
3343e12c5d1SDavid du Colombier int
inshort(int n)3353e12c5d1SDavid du Colombier inshort(int n)
3363e12c5d1SDavid du Colombier {
3373e12c5d1SDavid du Colombier 	return indata[n]|(indata[n+1]<<8);
3383e12c5d1SDavid du Colombier }
3393e12c5d1SDavid du Colombier 
3403e12c5d1SDavid du Colombier long
inlong(int n)3413e12c5d1SDavid du Colombier inlong(int n)
3423e12c5d1SDavid du Colombier {
3433e12c5d1SDavid du Colombier 	return indata[n]|(indata[n+1]<<8)|
3443e12c5d1SDavid du Colombier 		((long)indata[n+2]<<16)|((long)indata[n+3]<<24);
3453e12c5d1SDavid du Colombier }
3463e12c5d1SDavid du Colombier 
34773e742d7SDavid du Colombier vlong
invlong(int n)348219b2ee8SDavid du Colombier invlong(int n)
349219b2ee8SDavid du Colombier {
35073e742d7SDavid du Colombier 	vlong v;
351219b2ee8SDavid du Colombier 
35273e742d7SDavid du Colombier 	v = (indata[n+7]<<24) | (indata[n+6]<<16) | (indata[n+5]<<8) | indata[n+4];
35373e742d7SDavid du Colombier 	v = (v<<16) | (indata[n+3]<<8) | indata[n+2];
35473e742d7SDavid du Colombier 	v = (v<<16) | (indata[n+1]<<8) | indata[n];
35573e742d7SDavid du Colombier 	return v;
356219b2ee8SDavid du Colombier }
357219b2ee8SDavid du Colombier 
3583e12c5d1SDavid du Colombier void
outT0(Tmesg type)3593e12c5d1SDavid du Colombier outT0(Tmesg type)
3603e12c5d1SDavid du Colombier {
3613e12c5d1SDavid du Colombier 	outstart(type);
3623e12c5d1SDavid du Colombier 	outsend();
3633e12c5d1SDavid du Colombier }
3643e12c5d1SDavid du Colombier 
3653e12c5d1SDavid du Colombier void
outTl(Tmesg type,long l)3663e12c5d1SDavid du Colombier outTl(Tmesg type, long l)
3673e12c5d1SDavid du Colombier {
3683e12c5d1SDavid du Colombier 	outstart(type);
3693e12c5d1SDavid du Colombier 	outlong(l);
3703e12c5d1SDavid du Colombier 	outsend();
3713e12c5d1SDavid du Colombier }
3723e12c5d1SDavid du Colombier 
3733e12c5d1SDavid du Colombier void
outTs(Tmesg type,int s)3743e12c5d1SDavid du Colombier outTs(Tmesg type, int s)
3753e12c5d1SDavid du Colombier {
3763e12c5d1SDavid du Colombier 	outstart(type);
3773e12c5d1SDavid du Colombier 	outshort(s);
3783e12c5d1SDavid du Colombier 	outsend();
3793e12c5d1SDavid du Colombier }
3803e12c5d1SDavid du Colombier 
3813e12c5d1SDavid du Colombier void
outTss(Tmesg type,int s1,int s2)3823e12c5d1SDavid du Colombier outTss(Tmesg type, int s1, int s2)
3833e12c5d1SDavid du Colombier {
3843e12c5d1SDavid du Colombier 	outstart(type);
3853e12c5d1SDavid du Colombier 	outshort(s1);
3863e12c5d1SDavid du Colombier 	outshort(s2);
3873e12c5d1SDavid du Colombier 	outsend();
3883e12c5d1SDavid du Colombier }
3893e12c5d1SDavid du Colombier 
3903e12c5d1SDavid du Colombier void
outTsll(Tmesg type,int s1,long l1,long l2)3913e12c5d1SDavid du Colombier outTsll(Tmesg type, int s1, long l1, long l2)
3923e12c5d1SDavid du Colombier {
3933e12c5d1SDavid du Colombier 	outstart(type);
3943e12c5d1SDavid du Colombier 	outshort(s1);
3953e12c5d1SDavid du Colombier 	outlong(l1);
3963e12c5d1SDavid du Colombier 	outlong(l2);
3973e12c5d1SDavid du Colombier 	outsend();
3983e12c5d1SDavid du Colombier }
3993e12c5d1SDavid du Colombier 
4003e12c5d1SDavid du Colombier void
outTsl(Tmesg type,int s1,long l1)4013e12c5d1SDavid du Colombier outTsl(Tmesg type, int s1, long l1)
4023e12c5d1SDavid du Colombier {
4033e12c5d1SDavid du Colombier 	outstart(type);
4043e12c5d1SDavid du Colombier 	outshort(s1);
4053e12c5d1SDavid du Colombier 	outlong(l1);
4063e12c5d1SDavid du Colombier 	outsend();
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier void
outTsv(Tmesg type,int s1,vlong v1)41073e742d7SDavid du Colombier outTsv(Tmesg type, int s1, vlong v1)
411219b2ee8SDavid du Colombier {
412219b2ee8SDavid du Colombier 	outstart(type);
413219b2ee8SDavid du Colombier 	outshort(s1);
41473e742d7SDavid du Colombier 	outvlong(v1);
415219b2ee8SDavid du Colombier 	outsend();
416219b2ee8SDavid du Colombier }
417219b2ee8SDavid du Colombier 
418219b2ee8SDavid du Colombier void
outTv(Tmesg type,vlong v1)41973e742d7SDavid du Colombier outTv(Tmesg type, vlong v1)
420219b2ee8SDavid du Colombier {
421219b2ee8SDavid du Colombier 	outstart(type);
42273e742d7SDavid du Colombier 	outvlong(v1);
423219b2ee8SDavid du Colombier 	outsend();
424219b2ee8SDavid du Colombier }
425219b2ee8SDavid du Colombier 
426219b2ee8SDavid du Colombier void
outTslS(Tmesg type,int s1,long l1,Rune * s)4273e12c5d1SDavid du Colombier outTslS(Tmesg type, int s1, long l1, Rune *s)
4283e12c5d1SDavid du Colombier {
4293e12c5d1SDavid du Colombier 	char buf[DATASIZE*3+1];
4303e12c5d1SDavid du Colombier 	char *c;
4313e12c5d1SDavid du Colombier 
4323e12c5d1SDavid du Colombier 	outstart(type);
4333e12c5d1SDavid du Colombier 	outshort(s1);
4343e12c5d1SDavid du Colombier 	outlong(l1);
4353e12c5d1SDavid du Colombier 	c = buf;
4363e12c5d1SDavid du Colombier 	while(*s)
4373e12c5d1SDavid du Colombier 		c += runetochar(c, s++);
4383e12c5d1SDavid du Colombier 	*c++ = 0;
4393e12c5d1SDavid du Colombier 	outcopy(c-buf, (uchar *)buf);
4403e12c5d1SDavid du Colombier 	outsend();
4413e12c5d1SDavid du Colombier }
4423e12c5d1SDavid du Colombier 
4433e12c5d1SDavid du Colombier void
outTsls(Tmesg type,int s1,long l1,int s2)4443e12c5d1SDavid du Colombier outTsls(Tmesg type, int s1, long l1, int s2)
4453e12c5d1SDavid du Colombier {
4463e12c5d1SDavid du Colombier 	outstart(type);
4473e12c5d1SDavid du Colombier 	outshort(s1);
4483e12c5d1SDavid du Colombier 	outlong(l1);
4493e12c5d1SDavid du Colombier 	outshort(s2);
4503e12c5d1SDavid du Colombier 	outsend();
4513e12c5d1SDavid du Colombier }
4523e12c5d1SDavid du Colombier 
4533e12c5d1SDavid du Colombier void
outstart(Tmesg type)4543e12c5d1SDavid du Colombier outstart(Tmesg type)
4553e12c5d1SDavid du Colombier {
4563e12c5d1SDavid du Colombier 	outdata[0] = type;
4573e12c5d1SDavid du Colombier 	outcount = 0;
4583e12c5d1SDavid du Colombier }
4593e12c5d1SDavid du Colombier 
4603e12c5d1SDavid du Colombier void
outcopy(int count,uchar * data)4613e12c5d1SDavid du Colombier outcopy(int count, uchar *data)
4623e12c5d1SDavid du Colombier {
4633e12c5d1SDavid du Colombier 	while(count--)
4643e12c5d1SDavid du Colombier 		outdata[HSIZE+outcount++] = *data++;
4653e12c5d1SDavid du Colombier }
4663e12c5d1SDavid du Colombier 
4673e12c5d1SDavid du Colombier void
outshort(int s)4683e12c5d1SDavid du Colombier outshort(int s)
4693e12c5d1SDavid du Colombier {
4703e12c5d1SDavid du Colombier 	uchar buf[2];
4713e12c5d1SDavid du Colombier 
4723e12c5d1SDavid du Colombier 	buf[0]=s;
4733e12c5d1SDavid du Colombier 	buf[1]=s>>8;
4743e12c5d1SDavid du Colombier 	outcopy(2, buf);
4753e12c5d1SDavid du Colombier }
4763e12c5d1SDavid du Colombier 
4773e12c5d1SDavid du Colombier void
outlong(long l)4783e12c5d1SDavid du Colombier outlong(long l)
4793e12c5d1SDavid du Colombier {
4803e12c5d1SDavid du Colombier 	uchar buf[4];
4813e12c5d1SDavid du Colombier 
4823e12c5d1SDavid du Colombier 	buf[0]=l;
4833e12c5d1SDavid du Colombier 	buf[1]=l>>8;
4843e12c5d1SDavid du Colombier 	buf[2]=l>>16;
4853e12c5d1SDavid du Colombier 	buf[3]=l>>24;
4863e12c5d1SDavid du Colombier 	outcopy(4, buf);
4873e12c5d1SDavid du Colombier }
4883e12c5d1SDavid du Colombier 
4893e12c5d1SDavid du Colombier void
outvlong(vlong v)49073e742d7SDavid du Colombier outvlong(vlong v)
491219b2ee8SDavid du Colombier {
492219b2ee8SDavid du Colombier 	int i;
493219b2ee8SDavid du Colombier 	uchar buf[8];
494219b2ee8SDavid du Colombier 
49573e742d7SDavid du Colombier 	for(i = 0; i < sizeof(buf); i++){
49673e742d7SDavid du Colombier 		buf[i] = v;
49773e742d7SDavid du Colombier 		v >>= 8;
49873e742d7SDavid du Colombier 	}
499219b2ee8SDavid du Colombier 
500219b2ee8SDavid du Colombier 	outcopy(8, buf);
501219b2ee8SDavid du Colombier }
502219b2ee8SDavid du Colombier 
503219b2ee8SDavid du Colombier void
outsend(void)5043e12c5d1SDavid du Colombier outsend(void)
5053e12c5d1SDavid du Colombier {
5063e12c5d1SDavid du Colombier 	if(outcount>DATASIZE-HSIZE)
5073e12c5d1SDavid du Colombier 		panic("outcount>sizeof outdata");
5083e12c5d1SDavid du Colombier 	outdata[1]=outcount;
5093e12c5d1SDavid du Colombier 	outdata[2]=outcount>>8;
5103e12c5d1SDavid du Colombier 	if(write(1, (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)
5117dd7cddfSDavid du Colombier 		panic("write error");
5123e12c5d1SDavid du Colombier }
5133e12c5d1SDavid du Colombier 
5143e12c5d1SDavid du Colombier 
5153e12c5d1SDavid du Colombier void
hsetdot(int m,long p0,long p1)5163e12c5d1SDavid du Colombier hsetdot(int m, long p0, long p1)
5173e12c5d1SDavid du Colombier {
5183e12c5d1SDavid du Colombier 	Text *t = whichtext(m);
5193e12c5d1SDavid du Colombier 	Flayer *l = &t->l[t->front];
5203e12c5d1SDavid du Colombier 
5213e12c5d1SDavid du Colombier 	flushtyping(1);
5223e12c5d1SDavid du Colombier 	flsetselect(l, p0, p1);
5233e12c5d1SDavid du Colombier }
5243e12c5d1SDavid du Colombier 
5253e12c5d1SDavid du Colombier void
horigin(int m,long p0)5263e12c5d1SDavid du Colombier horigin(int m, long p0)
5273e12c5d1SDavid du Colombier {
5283e12c5d1SDavid du Colombier 	Text *t = whichtext(m);
5293e12c5d1SDavid du Colombier 	Flayer *l = &t->l[t->front];
5303e12c5d1SDavid du Colombier 	long a;
5313e12c5d1SDavid du Colombier 	ulong n;
5323e12c5d1SDavid du Colombier 	Rune *r;
5333e12c5d1SDavid du Colombier 
5343e12c5d1SDavid du Colombier 	if(!flprepare(l)){
5353e12c5d1SDavid du Colombier 		l->origin = p0;
5363e12c5d1SDavid du Colombier 		return;
5373e12c5d1SDavid du Colombier 	}
5383e12c5d1SDavid du Colombier 	a = p0-l->origin;
5393e12c5d1SDavid du Colombier 	if(a>=0 && a<l->f.nchars)
5403e12c5d1SDavid du Colombier 		frdelete(&l->f, 0, a);
5413e12c5d1SDavid du Colombier 	else if(a<0 && -a<l->f.nchars){
5423e12c5d1SDavid du Colombier 		r = rload(&t->rasp, p0, l->origin, &n);
5433e12c5d1SDavid du Colombier 		frinsert(&l->f, r, r+n, 0);
5443e12c5d1SDavid du Colombier 	}else
5453e12c5d1SDavid du Colombier 		frdelete(&l->f, 0, l->f.nchars);
5463e12c5d1SDavid du Colombier 	l->origin = p0;
5473e12c5d1SDavid du Colombier 	scrdraw(l, t->rasp.nrunes);
5483e12c5d1SDavid du Colombier 	if(l->visible==Some)
5493e12c5d1SDavid du Colombier 		flrefresh(l, l->entire, 0);
5503e12c5d1SDavid du Colombier 	hcheck(m);
5513e12c5d1SDavid du Colombier }
5523e12c5d1SDavid du Colombier 
5533e12c5d1SDavid du Colombier void
hmoveto(int m,long p0)5543e12c5d1SDavid du Colombier hmoveto(int m, long p0)
5553e12c5d1SDavid du Colombier {
5563e12c5d1SDavid du Colombier 	Text *t = whichtext(m);
5573e12c5d1SDavid du Colombier 	Flayer *l = &t->l[t->front];
5583e12c5d1SDavid du Colombier 
5593e12c5d1SDavid du Colombier 	if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)
5603e12c5d1SDavid du Colombier 		outTsll(Torigin, m, p0, 2L);
5613e12c5d1SDavid du Colombier }
5623e12c5d1SDavid du Colombier 
5633e12c5d1SDavid du Colombier void
hcheck(int m)5643e12c5d1SDavid du Colombier hcheck(int m)
5653e12c5d1SDavid du Colombier {
5663e12c5d1SDavid du Colombier 	Flayer *l;
5673e12c5d1SDavid du Colombier 	Text *t;
5683e12c5d1SDavid du Colombier 	int reqd = 0, i;
5693e12c5d1SDavid du Colombier 	long n, nl, a;
5703e12c5d1SDavid du Colombier 	Rune *r;
5713e12c5d1SDavid du Colombier 
5723e12c5d1SDavid du Colombier 	if(m == Untagged)
5733e12c5d1SDavid du Colombier 		return;
5743e12c5d1SDavid du Colombier 	t = whichtext(m);
5753e12c5d1SDavid du Colombier 	if(t == 0)		/* possible in a half-built window */
5763e12c5d1SDavid du Colombier 		return;
5773e12c5d1SDavid du Colombier 	for(l = &t->l[0], i = 0; i<NL; i++, l++){
5783e12c5d1SDavid du Colombier 		if(l->textfn==0 || !flprepare(l))	/* BUG: don't
5793e12c5d1SDavid du Colombier 							   need this if BUG below
5803e12c5d1SDavid du Colombier 							   is fixed */
5813e12c5d1SDavid du Colombier 			continue;
5823e12c5d1SDavid du Colombier 		a = t->l[i].origin;
5833e12c5d1SDavid du Colombier 		n = rcontig(&t->rasp, a, a+l->f.nchars, 1);
5843e12c5d1SDavid du Colombier 		if(n<l->f.nchars)	/* text missing in middle of screen */
5853e12c5d1SDavid du Colombier 			a+=n;
5863e12c5d1SDavid du Colombier 		else{			/* text missing at end of screen? */
5873e12c5d1SDavid du Colombier         Again:
5883e12c5d1SDavid du Colombier 		 	if(l->f.lastlinefull)
5893e12c5d1SDavid du Colombier 				goto Checksel;	/* all's well */
5903e12c5d1SDavid du Colombier 			a = t->l[i].origin+l->f.nchars;
5913e12c5d1SDavid du Colombier 			n = t->rasp.nrunes-a;
5923e12c5d1SDavid du Colombier 			if(n==0)
5933e12c5d1SDavid du Colombier 				goto Checksel;
5943e12c5d1SDavid du Colombier 			if(n>TBLOCKSIZE)
5953e12c5d1SDavid du Colombier 				n = TBLOCKSIZE;
5963e12c5d1SDavid du Colombier 			n = rcontig(&t->rasp, a, a+n, 1);
5973e12c5d1SDavid du Colombier 			if(n>0){
5983e12c5d1SDavid du Colombier 				rload(&t->rasp, a, a+n, 0);
5993e12c5d1SDavid du Colombier 				nl = l->f.nchars;
6003e12c5d1SDavid du Colombier 				r = scratch;
6013e12c5d1SDavid du Colombier 				flinsert(l, r, r+n, l->origin+nl);
6023e12c5d1SDavid du Colombier 				if(nl == l->f.nchars)	/* made no progress */
6033e12c5d1SDavid du Colombier 					goto Checksel;
6043e12c5d1SDavid du Colombier 				goto Again;
6053e12c5d1SDavid du Colombier 			}
6063e12c5d1SDavid du Colombier 		}
6073e12c5d1SDavid du Colombier 		if(!reqd){
6083e12c5d1SDavid du Colombier 			n = rcontig(&t->rasp, a, a+TBLOCKSIZE, 0);
6093e12c5d1SDavid du Colombier 			if(n <= 0)
6103e12c5d1SDavid du Colombier 				panic("hcheck request==0");
6113e12c5d1SDavid du Colombier 			outTsls(Trequest, m, a, (int)n);
6123e12c5d1SDavid du Colombier 			outTs(Tcheck, m);
613219b2ee8SDavid du Colombier 			t->lock++;	/* for the Trequest */
614219b2ee8SDavid du Colombier 			t->lock++;	/* for the Tcheck */
6153e12c5d1SDavid du Colombier 			reqd++;
6163e12c5d1SDavid du Colombier 		}
6173e12c5d1SDavid du Colombier 	    Checksel:
6183e12c5d1SDavid du Colombier 		flsetselect(l, l->p0, l->p1);
6193e12c5d1SDavid du Colombier 	}
6203e12c5d1SDavid du Colombier }
6213e12c5d1SDavid du Colombier 
6223e12c5d1SDavid du Colombier void
flnewlyvisible(Flayer * l)6233e12c5d1SDavid du Colombier flnewlyvisible(Flayer *l)
6243e12c5d1SDavid du Colombier {
6253e12c5d1SDavid du Colombier 	hcheck(((Text *)l->user1)->tag);
6263e12c5d1SDavid du Colombier }
6273e12c5d1SDavid du Colombier 
6283e12c5d1SDavid du Colombier void
hsetsnarf(int nc)6293e12c5d1SDavid du Colombier hsetsnarf(int nc)
6303e12c5d1SDavid du Colombier {
6313e12c5d1SDavid du Colombier 	char *s2;
6323e12c5d1SDavid du Colombier 	char *s1;
6333e12c5d1SDavid du Colombier 	int i;
6343e12c5d1SDavid du Colombier 	int n;
6353e12c5d1SDavid du Colombier 
6367dd7cddfSDavid du Colombier 	setcursor(mousectl, &deadmouse);
6373e12c5d1SDavid du Colombier 	s2 = alloc(nc+1);
6383e12c5d1SDavid du Colombier 	for(i=0; i<nc; i++)
6393e12c5d1SDavid du Colombier 		s2[i] = getch();
6403e12c5d1SDavid du Colombier 	s2[nc] = 0;
6413e12c5d1SDavid du Colombier 	n = snarfswap(s2, nc, &s1);
6423e12c5d1SDavid du Colombier 	if(n >= 0){
6433e12c5d1SDavid du Colombier 		if(!s1)
6443e12c5d1SDavid du Colombier 			n = 0;
645*f7db6155SDavid du Colombier 		if(n > SNARFSIZE){
646*f7db6155SDavid du Colombier 			s1 = strdup("<snarf too long>");
647*f7db6155SDavid du Colombier 			if (!s1)
648*f7db6155SDavid du Colombier 				panic("strdup");
649*f7db6155SDavid du Colombier 			n = strlen(s1);
650*f7db6155SDavid du Colombier 		}else{
651bd389b36SDavid du Colombier 			s1 = realloc(s1, n+1);
652219b2ee8SDavid du Colombier 			if (!s1)
6537dd7cddfSDavid du Colombier 				panic("realloc");
654bd389b36SDavid du Colombier 			s1[n] = 0;
655*f7db6155SDavid du Colombier 		}
6563e12c5d1SDavid du Colombier 		snarflen = n;
6573e12c5d1SDavid du Colombier 		outTs(Tsetsnarf, n);
6583e12c5d1SDavid du Colombier 		if(n>0 && write(1, s1, n)!=n)
6597dd7cddfSDavid du Colombier 			panic("snarf write error");
6603e12c5d1SDavid du Colombier 		free(s1);
661219b2ee8SDavid du Colombier 	}else
662219b2ee8SDavid du Colombier 		outTs(Tsetsnarf, 0);
6633e12c5d1SDavid du Colombier 	free(s2);
6647dd7cddfSDavid du Colombier 	setcursor(mousectl, cursor);
6657dd7cddfSDavid du Colombier }
6667dd7cddfSDavid du Colombier 
6677dd7cddfSDavid du Colombier void
hplumb(int nc)6687dd7cddfSDavid du Colombier hplumb(int nc)
6697dd7cddfSDavid du Colombier {
6707dd7cddfSDavid du Colombier 	int i;
6717dd7cddfSDavid du Colombier 	char *s;
6727dd7cddfSDavid du Colombier 	Plumbmsg *m;
6737dd7cddfSDavid du Colombier 
6747dd7cddfSDavid du Colombier 	s = alloc(nc);
6757dd7cddfSDavid du Colombier 	for(i=0; i<nc; i++)
6767dd7cddfSDavid du Colombier 		s[i] = getch();
6777dd7cddfSDavid du Colombier 	if(plumbfd > 0){
6787dd7cddfSDavid du Colombier 		m = plumbunpack(s, nc);
6797dd7cddfSDavid du Colombier 		if(m != 0)
6807dd7cddfSDavid du Colombier 			plumbsend(plumbfd, m);
6817dd7cddfSDavid du Colombier 		plumbfree(m);
6827dd7cddfSDavid du Colombier 	}
6837dd7cddfSDavid du Colombier 	free(s);
6843e12c5d1SDavid du Colombier }
6853e12c5d1SDavid du Colombier 
6863e12c5d1SDavid du Colombier void
hgrow(int m,long a,long new,int req)6873e12c5d1SDavid du Colombier hgrow(int m, long a, long new, int req)
6883e12c5d1SDavid du Colombier {
6893e12c5d1SDavid du Colombier 	int i;
6903e12c5d1SDavid du Colombier 	Flayer *l;
6913e12c5d1SDavid du Colombier 	Text *t = whichtext(m);
6923e12c5d1SDavid du Colombier 	long o, b;
6933e12c5d1SDavid du Colombier 
6943e12c5d1SDavid du Colombier 	if(new <= 0)
6953e12c5d1SDavid du Colombier 		panic("hgrow");
6963e12c5d1SDavid du Colombier 	rresize(&t->rasp, a, 0L, new);
6973e12c5d1SDavid du Colombier 	for(l = &t->l[0], i = 0; i<NL; i++, l++){
6983e12c5d1SDavid du Colombier 		if(l->textfn == 0)
6993e12c5d1SDavid du Colombier 			continue;
7003e12c5d1SDavid du Colombier 		o = l->origin;
7013e12c5d1SDavid du Colombier 		b = a-o-rmissing(&t->rasp, o, a);
7023e12c5d1SDavid du Colombier 		if(a < o)
7033e12c5d1SDavid du Colombier 			l->origin+=new;
7043e12c5d1SDavid du Colombier 		if(a < l->p0)
7053e12c5d1SDavid du Colombier 			l->p0+=new;
7063e12c5d1SDavid du Colombier 		if(a < l->p1)
7073e12c5d1SDavid du Colombier 			l->p1+=new;
7083e12c5d1SDavid du Colombier 		/* must prevent b temporarily becoming unsigned */
7093e12c5d1SDavid du Colombier 		if(!req || a<o || (b>0 && b>l->f.nchars) ||
7103e12c5d1SDavid du Colombier 		    (l->f.nchars==0 && a-o>0))
7113e12c5d1SDavid du Colombier 			continue;
7123e12c5d1SDavid du Colombier 		if(new>TBLOCKSIZE)
7133e12c5d1SDavid du Colombier 			new = TBLOCKSIZE;
7143e12c5d1SDavid du Colombier 		outTsls(Trequest, m, a, (int)new);
7153e12c5d1SDavid du Colombier 		t->lock++;
7163e12c5d1SDavid du Colombier 		req = 0;
7173e12c5d1SDavid du Colombier 	}
7183e12c5d1SDavid du Colombier }
7193e12c5d1SDavid du Colombier 
7203e12c5d1SDavid du Colombier int
hdata1(Text * t,long a,Rune * r,int len)7213e12c5d1SDavid du Colombier hdata1(Text *t, long a, Rune *r, int len)
7223e12c5d1SDavid du Colombier {
7233e12c5d1SDavid du Colombier 	int i;
7243e12c5d1SDavid du Colombier 	Flayer *l;
7253e12c5d1SDavid du Colombier 	long o, b;
7263e12c5d1SDavid du Colombier 
7273e12c5d1SDavid du Colombier 	for(l = &t->l[0], i=0; i<NL; i++, l++){
7283e12c5d1SDavid du Colombier 		if(l->textfn==0)
7293e12c5d1SDavid du Colombier 			continue;
7303e12c5d1SDavid du Colombier 		o = l->origin;
7313e12c5d1SDavid du Colombier 		b = a-o-rmissing(&t->rasp, o, a);
7323e12c5d1SDavid du Colombier 		/* must prevent b temporarily becoming unsigned */
7333e12c5d1SDavid du Colombier 		if(a<o || (b>0 && b>l->f.nchars))
7343e12c5d1SDavid du Colombier 			continue;
7353e12c5d1SDavid du Colombier 		flinsert(l, r, r+len, o+b);
7363e12c5d1SDavid du Colombier 	}
7373e12c5d1SDavid du Colombier 	rdata(&t->rasp, a, a+len, r);
7383e12c5d1SDavid du Colombier 	rclean(&t->rasp);
7393e12c5d1SDavid du Colombier 	return len;
7403e12c5d1SDavid du Colombier }
7413e12c5d1SDavid du Colombier 
7423e12c5d1SDavid du Colombier int
hdata(int m,long a,uchar * s,int len)7433e12c5d1SDavid du Colombier hdata(int m, long a, uchar *s, int len)
7443e12c5d1SDavid du Colombier {
7453e12c5d1SDavid du Colombier 	int i, w;
7463e12c5d1SDavid du Colombier 	Text *t = whichtext(m);
7473e12c5d1SDavid du Colombier 	Rune buf[DATASIZE], *r;
7483e12c5d1SDavid du Colombier 
7493e12c5d1SDavid du Colombier 	if(t->lock)
7503e12c5d1SDavid du Colombier 		--t->lock;
7513e12c5d1SDavid du Colombier 	if(len == 0)
7523e12c5d1SDavid du Colombier 		return 0;
7533e12c5d1SDavid du Colombier 	r = buf;
7543e12c5d1SDavid du Colombier 	for(i=0; i<len; i+=w,s+=w)
7553e12c5d1SDavid du Colombier 		w = chartorune(r++, (char*)s);
7563e12c5d1SDavid du Colombier 	return hdata1(t, a, buf, r-buf);
7573e12c5d1SDavid du Colombier }
7583e12c5d1SDavid du Colombier 
7593e12c5d1SDavid du Colombier int
hdatarune(int m,long a,Rune * r,int len)7603e12c5d1SDavid du Colombier hdatarune(int m, long a, Rune *r, int len)
7613e12c5d1SDavid du Colombier {
7623e12c5d1SDavid du Colombier 	Text *t = whichtext(m);
7633e12c5d1SDavid du Colombier 
7643e12c5d1SDavid du Colombier 	if(t->lock)
7653e12c5d1SDavid du Colombier 		--t->lock;
7663e12c5d1SDavid du Colombier 	if(len == 0)
7673e12c5d1SDavid du Colombier 		return 0;
7683e12c5d1SDavid du Colombier 	return hdata1(t, a, r, len);
7693e12c5d1SDavid du Colombier }
7703e12c5d1SDavid du Colombier 
7713e12c5d1SDavid du Colombier void
hcut(int m,long a,long old)7723e12c5d1SDavid du Colombier hcut(int m, long a, long old)
7733e12c5d1SDavid du Colombier {
7743e12c5d1SDavid du Colombier 	Flayer *l;
7753e12c5d1SDavid du Colombier 	Text *t = whichtext(m);
7763e12c5d1SDavid du Colombier 	int i;
7773e12c5d1SDavid du Colombier 	long o, b;
7783e12c5d1SDavid du Colombier 
7793e12c5d1SDavid du Colombier 	if(t->lock)
7803e12c5d1SDavid du Colombier 		--t->lock;
7813e12c5d1SDavid du Colombier 	for(l = &t->l[0], i = 0; i<NL; i++, l++){
7823e12c5d1SDavid du Colombier 		if(l->textfn == 0)
7833e12c5d1SDavid du Colombier 			continue;
7843e12c5d1SDavid du Colombier 		o = l->origin;
7853e12c5d1SDavid du Colombier 		b = a-o-rmissing(&t->rasp, o, a);
7863e12c5d1SDavid du Colombier 		/* must prevent b temporarily becoming unsigned */
7873e12c5d1SDavid du Colombier 		if((b<0 || b<l->f.nchars) && a+old>=o){
7883e12c5d1SDavid du Colombier 			fldelete(l, b<0? o : o+b,
7893e12c5d1SDavid du Colombier 			    a+old-rmissing(&t->rasp, o, a+old));
7903e12c5d1SDavid du Colombier 		}
7913e12c5d1SDavid du Colombier 		if(a+old<o)
7923e12c5d1SDavid du Colombier 			l->origin-=old;
7933e12c5d1SDavid du Colombier 		else if(a<=o)
7943e12c5d1SDavid du Colombier 			l->origin = a;
7953e12c5d1SDavid du Colombier 		if(a+old<l->p0)
7963e12c5d1SDavid du Colombier 			l->p0-=old;
7973e12c5d1SDavid du Colombier 		else if(a<=l->p0)
7983e12c5d1SDavid du Colombier 			l->p0 = a;
7993e12c5d1SDavid du Colombier 		if(a+old<l->p1)
8003e12c5d1SDavid du Colombier 			l->p1-=old;
8013e12c5d1SDavid du Colombier 		else if(a<=l->p1)
8023e12c5d1SDavid du Colombier 			l->p1 = a;
8033e12c5d1SDavid du Colombier 	}
8043e12c5d1SDavid du Colombier 	rresize(&t->rasp, a, old, 0L);
8053e12c5d1SDavid du Colombier 	rclean(&t->rasp);
8063e12c5d1SDavid du Colombier }
807