xref: /plan9/sys/src/cmd/samterm/rasp.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*7dd7cddfSDavid du Colombier #include <draw.h>
4*7dd7cddfSDavid du Colombier #include <thread.h>
5*7dd7cddfSDavid du Colombier #include <mouse.h>
6*7dd7cddfSDavid du Colombier #include <keyboard.h>
73e12c5d1SDavid du Colombier #include <frame.h>
83e12c5d1SDavid du Colombier #include "flayer.h"
93e12c5d1SDavid du Colombier #include "samterm.h"
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier void
rinit(Rasp * r)123e12c5d1SDavid du Colombier rinit(Rasp *r)
133e12c5d1SDavid du Colombier {
143e12c5d1SDavid du Colombier 	r->nrunes=0;
153e12c5d1SDavid du Colombier 	r->sect=0;
163e12c5d1SDavid du Colombier }
173e12c5d1SDavid du Colombier 
183e12c5d1SDavid du Colombier void
rclear(Rasp * r)193e12c5d1SDavid du Colombier rclear(Rasp *r)
203e12c5d1SDavid du Colombier {
213e12c5d1SDavid du Colombier 	Section *s, *ns;
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier 	for(s=r->sect; s; s=ns){
243e12c5d1SDavid du Colombier 		ns = s->next;
253e12c5d1SDavid du Colombier 		free(s->text);
263e12c5d1SDavid du Colombier 		free(s);
273e12c5d1SDavid du Colombier 	}
283e12c5d1SDavid du Colombier 	r->sect = 0;
293e12c5d1SDavid du Colombier }
303e12c5d1SDavid du Colombier 
313e12c5d1SDavid du Colombier Section*
rsinsert(Rasp * r,Section * s)323e12c5d1SDavid du Colombier rsinsert(Rasp *r, Section *s)	/* insert before s */
333e12c5d1SDavid du Colombier {
343e12c5d1SDavid du Colombier 	Section *t;
353e12c5d1SDavid du Colombier 	Section *u;
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier 	t = alloc(sizeof(Section));
383e12c5d1SDavid du Colombier 	if(r->sect == s){	/* includes empty list case: r->sect==s==0 */
393e12c5d1SDavid du Colombier 		r->sect = t;
403e12c5d1SDavid du Colombier 		t->next = s;
413e12c5d1SDavid du Colombier 	}else{
423e12c5d1SDavid du Colombier 		u = r->sect;
433e12c5d1SDavid du Colombier 		if(u == 0)
443e12c5d1SDavid du Colombier 			panic("rsinsert 1");
453e12c5d1SDavid du Colombier 		do{
463e12c5d1SDavid du Colombier 			if(u->next == s){
473e12c5d1SDavid du Colombier 				t->next = s;
483e12c5d1SDavid du Colombier 				u->next = t;
493e12c5d1SDavid du Colombier 				goto Return;
503e12c5d1SDavid du Colombier 			}
513e12c5d1SDavid du Colombier 			u=u->next;
523e12c5d1SDavid du Colombier 		}while(u);
533e12c5d1SDavid du Colombier 		panic("rsinsert 2");
543e12c5d1SDavid du Colombier 	}
553e12c5d1SDavid du Colombier     Return:
563e12c5d1SDavid du Colombier 	return t;
573e12c5d1SDavid du Colombier }
583e12c5d1SDavid du Colombier 
593e12c5d1SDavid du Colombier void
rsdelete(Rasp * r,Section * s)603e12c5d1SDavid du Colombier rsdelete(Rasp *r, Section *s)
613e12c5d1SDavid du Colombier {
623e12c5d1SDavid du Colombier 	Section *t;
633e12c5d1SDavid du Colombier 
643e12c5d1SDavid du Colombier 	if(s == 0)
653e12c5d1SDavid du Colombier 		panic("rsdelete");
663e12c5d1SDavid du Colombier 	if(r->sect == s){
673e12c5d1SDavid du Colombier 		r->sect = s->next;
683e12c5d1SDavid du Colombier 		goto Free;
693e12c5d1SDavid du Colombier 	}
703e12c5d1SDavid du Colombier 	for(t=r->sect; t; t=t->next)
713e12c5d1SDavid du Colombier 		if(t->next == s){
723e12c5d1SDavid du Colombier 			t->next = s->next;
733e12c5d1SDavid du Colombier 	Free:
743e12c5d1SDavid du Colombier 			if(s->text)
753e12c5d1SDavid du Colombier 				free(s->text);
763e12c5d1SDavid du Colombier 			free(s);
773e12c5d1SDavid du Colombier 			return;
783e12c5d1SDavid du Colombier 		}
793e12c5d1SDavid du Colombier 	panic("rsdelete 2");
803e12c5d1SDavid du Colombier }
813e12c5d1SDavid du Colombier 
823e12c5d1SDavid du Colombier void
splitsect(Rasp * r,Section * s,long n0)833e12c5d1SDavid du Colombier splitsect(Rasp *r, Section *s, long n0)
843e12c5d1SDavid du Colombier {
853e12c5d1SDavid du Colombier 	if(s == 0)
863e12c5d1SDavid du Colombier 		panic("splitsect");
873e12c5d1SDavid du Colombier 	rsinsert(r, s->next);
883e12c5d1SDavid du Colombier 	if(s->text == 0)
893e12c5d1SDavid du Colombier 		s->next->text = 0;
903e12c5d1SDavid du Colombier 	else{
913e12c5d1SDavid du Colombier 		s->next->text = alloc(RUNESIZE*(TBLOCKSIZE+1));
923e12c5d1SDavid du Colombier 		Strcpy(s->next->text, s->text+n0);
933e12c5d1SDavid du Colombier 		s->text[n0] = 0;
943e12c5d1SDavid du Colombier 	}
953e12c5d1SDavid du Colombier 	s->next->nrunes = s->nrunes-n0;
963e12c5d1SDavid du Colombier 	s->nrunes = n0;
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier 
993e12c5d1SDavid du Colombier Section *
findsect(Rasp * r,Section * s,long p,long q)1003e12c5d1SDavid du Colombier findsect(Rasp *r, Section *s, long p, long q)	/* find sect containing q and put q on a sect boundary */
1013e12c5d1SDavid du Colombier {
1023e12c5d1SDavid du Colombier 	if(s==0 && p!=q)
1033e12c5d1SDavid du Colombier 		panic("findsect");
1043e12c5d1SDavid du Colombier 	for(; s && p+s->nrunes<=q; s=s->next)
1053e12c5d1SDavid du Colombier 		p += s->nrunes;
1063e12c5d1SDavid du Colombier 	if(p != q){
1073e12c5d1SDavid du Colombier 		splitsect(r, s, q-p);
1083e12c5d1SDavid du Colombier 		s = s->next;
1093e12c5d1SDavid du Colombier 	}
1103e12c5d1SDavid du Colombier 	return s;
1113e12c5d1SDavid du Colombier }
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier void
rresize(Rasp * r,long a,long old,long new)1143e12c5d1SDavid du Colombier rresize(Rasp *r, long a, long old, long new)
1153e12c5d1SDavid du Colombier {
1163e12c5d1SDavid du Colombier 	Section *s, *t, *ns;
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier 	s = findsect(r, r->sect, 0L, a);
1193e12c5d1SDavid du Colombier 	t = findsect(r, s, a, a+old);
1203e12c5d1SDavid du Colombier 	for(; s!=t; s=ns){
1213e12c5d1SDavid du Colombier 		ns=s->next;
1223e12c5d1SDavid du Colombier 		rsdelete(r, s);
1233e12c5d1SDavid du Colombier 	}
1243e12c5d1SDavid du Colombier 	/* now insert the new piece before t */
1253e12c5d1SDavid du Colombier 	if(new > 0){
1263e12c5d1SDavid du Colombier 		ns=rsinsert(r, t);
1273e12c5d1SDavid du Colombier 		ns->nrunes=new;
1283e12c5d1SDavid du Colombier 		ns->text=0;
1293e12c5d1SDavid du Colombier 	}
1303e12c5d1SDavid du Colombier 	r->nrunes += new-old;
1313e12c5d1SDavid du Colombier }
1323e12c5d1SDavid du Colombier 
1333e12c5d1SDavid du Colombier void
rdata(Rasp * r,long p0,long p1,Rune * cp)1343e12c5d1SDavid du Colombier rdata(Rasp *r, long p0, long p1, Rune *cp)
1353e12c5d1SDavid du Colombier {
1363e12c5d1SDavid du Colombier 	Section *s, *t, *ns;
1373e12c5d1SDavid du Colombier 
1383e12c5d1SDavid du Colombier 	s = findsect(r, r->sect, 0L, p0);
1393e12c5d1SDavid du Colombier 	t = findsect(r, s, p0, p1);
1403e12c5d1SDavid du Colombier 	for(; s!=t; s=ns){
1413e12c5d1SDavid du Colombier 		ns=s->next;
1423e12c5d1SDavid du Colombier 		if(s->text)
1433e12c5d1SDavid du Colombier 			panic("rdata");
1443e12c5d1SDavid du Colombier 		rsdelete(r, s);
1453e12c5d1SDavid du Colombier 	}
1463e12c5d1SDavid du Colombier 	p1 -= p0;
1473e12c5d1SDavid du Colombier 	s = rsinsert(r, t);
1483e12c5d1SDavid du Colombier 	s->text = alloc(RUNESIZE*(TBLOCKSIZE+1));
1493e12c5d1SDavid du Colombier 	memmove(s->text, cp, RUNESIZE*p1);
1503e12c5d1SDavid du Colombier 	s->text[p1] = 0;
1513e12c5d1SDavid du Colombier 	s->nrunes = p1;
1523e12c5d1SDavid du Colombier }
1533e12c5d1SDavid du Colombier 
1543e12c5d1SDavid du Colombier void
rclean(Rasp * r)1553e12c5d1SDavid du Colombier rclean(Rasp *r)
1563e12c5d1SDavid du Colombier {
1573e12c5d1SDavid du Colombier 	Section *s;
1583e12c5d1SDavid du Colombier 
1593e12c5d1SDavid du Colombier 	for(s=r->sect; s; s=s->next)
1603e12c5d1SDavid du Colombier 		while(s->next && (s->text!=0)==(s->next->text!=0)){
1613e12c5d1SDavid du Colombier 			if(s->text){
1623e12c5d1SDavid du Colombier 				if(s->nrunes+s->next->nrunes>TBLOCKSIZE)
1633e12c5d1SDavid du Colombier 					break;
1643e12c5d1SDavid du Colombier 				Strcpy(s->text+s->nrunes, s->next->text);
1653e12c5d1SDavid du Colombier 			}
1663e12c5d1SDavid du Colombier 			s->nrunes += s->next->nrunes;
1673e12c5d1SDavid du Colombier 			rsdelete(r, s->next);
1683e12c5d1SDavid du Colombier 		}
1693e12c5d1SDavid du Colombier }
1703e12c5d1SDavid du Colombier 
1713e12c5d1SDavid du Colombier void
Strcpy(Rune * to,Rune * from)1723e12c5d1SDavid du Colombier Strcpy(Rune *to, Rune *from)
1733e12c5d1SDavid du Colombier {
1743e12c5d1SDavid du Colombier 	do; while(*to++ = *from++);
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier Rune*
rload(Rasp * r,ulong p0,ulong p1,ulong * nrp)1783e12c5d1SDavid du Colombier rload(Rasp *r, ulong p0, ulong p1, ulong *nrp)
1793e12c5d1SDavid du Colombier {
1803e12c5d1SDavid du Colombier 	Section *s;
1813e12c5d1SDavid du Colombier 	long p;
1823e12c5d1SDavid du Colombier 	int n, nb;
1833e12c5d1SDavid du Colombier 
1843e12c5d1SDavid du Colombier 	nb = 0;
1853e12c5d1SDavid du Colombier 	Strgrow(&scratch, &nscralloc, p1-p0+1);
1863e12c5d1SDavid du Colombier 	scratch[0] = 0;
1873e12c5d1SDavid du Colombier 	for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
1883e12c5d1SDavid du Colombier 		p += s->nrunes;
1893e12c5d1SDavid du Colombier 	while(p<p1 && s){
1903e12c5d1SDavid du Colombier 		/*
1913e12c5d1SDavid du Colombier 		 * Subtle and important.  If we are preparing to handle an 'rdata'
1923e12c5d1SDavid du Colombier 		 * call, it's because we have an 'rresize' hole here, so the
1933e12c5d1SDavid du Colombier 		 * screen doesn't have data for that space anyway (it got cut
1943e12c5d1SDavid du Colombier 		 * first).  So pretend it isn't there.
1953e12c5d1SDavid du Colombier 		 */
1963e12c5d1SDavid du Colombier 		if(s->text){
1973e12c5d1SDavid du Colombier 			n = s->nrunes-(p0-p);
1983e12c5d1SDavid du Colombier 			if(n>p1-p0)	/* all in this section */
1993e12c5d1SDavid du Colombier 				n = p1-p0;
2003e12c5d1SDavid du Colombier 			memmove(scratch+nb, s->text+(p0-p), n*RUNESIZE);
2013e12c5d1SDavid du Colombier 			nb += n;
2023e12c5d1SDavid du Colombier 			scratch[nb] = 0;
2033e12c5d1SDavid du Colombier 		}
2043e12c5d1SDavid du Colombier 		p += s->nrunes;
2053e12c5d1SDavid du Colombier 		p0 = p;
2063e12c5d1SDavid du Colombier 		s = s->next;
2073e12c5d1SDavid du Colombier 	}
2083e12c5d1SDavid du Colombier 	if(nrp)
2093e12c5d1SDavid du Colombier 		*nrp = nb;
2103e12c5d1SDavid du Colombier 	return scratch;
2113e12c5d1SDavid du Colombier }
2123e12c5d1SDavid du Colombier 
2133e12c5d1SDavid du Colombier int
rmissing(Rasp * r,ulong p0,ulong p1)2143e12c5d1SDavid du Colombier rmissing(Rasp *r, ulong p0, ulong p1)
2153e12c5d1SDavid du Colombier {
2163e12c5d1SDavid du Colombier 	Section *s;
2173e12c5d1SDavid du Colombier 	long p;
2183e12c5d1SDavid du Colombier 	int n, nm=0;
2193e12c5d1SDavid du Colombier 
2203e12c5d1SDavid du Colombier 	for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
2213e12c5d1SDavid du Colombier 		p += s->nrunes;
2223e12c5d1SDavid du Colombier 	while(p<p1 && s){
2233e12c5d1SDavid du Colombier 		if(s->text == 0){
2243e12c5d1SDavid du Colombier 			n = s->nrunes-(p0-p);
2253e12c5d1SDavid du Colombier 			if(n > p1-p0)	/* all in this section */
2263e12c5d1SDavid du Colombier 				n = p1-p0;
2273e12c5d1SDavid du Colombier 			nm += n;
2283e12c5d1SDavid du Colombier 		}
2293e12c5d1SDavid du Colombier 		p += s->nrunes;
2303e12c5d1SDavid du Colombier 		p0 = p;
2313e12c5d1SDavid du Colombier 		s = s->next;
2323e12c5d1SDavid du Colombier 	}
2333e12c5d1SDavid du Colombier 	return nm;
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier 
2363e12c5d1SDavid du Colombier int
rcontig(Rasp * r,ulong p0,ulong p1,int text)2373e12c5d1SDavid du Colombier rcontig(Rasp *r, ulong p0, ulong p1, int text)
2383e12c5d1SDavid du Colombier {
2393e12c5d1SDavid du Colombier 	Section *s;
2403e12c5d1SDavid du Colombier 	long p, n;
2413e12c5d1SDavid du Colombier 	int np=0;
2423e12c5d1SDavid du Colombier 
2433e12c5d1SDavid du Colombier 	for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
2443e12c5d1SDavid du Colombier 		p += s->nrunes;
2453e12c5d1SDavid du Colombier 	while(p<p1 && s && (text? (s->text!=0) : (s->text==0))){
2463e12c5d1SDavid du Colombier 		n = s->nrunes-(p0-p);
2473e12c5d1SDavid du Colombier 		if(n > p1-p0)	/* all in this section */
2483e12c5d1SDavid du Colombier 			n = p1-p0;
2493e12c5d1SDavid du Colombier 		np += n;
2503e12c5d1SDavid du Colombier 		p += s->nrunes;
2513e12c5d1SDavid du Colombier 		p0 = p;
2523e12c5d1SDavid du Colombier 		s = s->next;
2533e12c5d1SDavid du Colombier 	}
2543e12c5d1SDavid du Colombier 	return np;
2553e12c5d1SDavid du Colombier }
2563e12c5d1SDavid du Colombier 
2573e12c5d1SDavid du Colombier void
Strgrow(Rune ** s,long * n,int want)2583e12c5d1SDavid du Colombier Strgrow(Rune **s, long *n, int want)	/* can always toss the old data when called */
2593e12c5d1SDavid du Colombier {
2603e12c5d1SDavid du Colombier 	if(*n >= want)
2613e12c5d1SDavid du Colombier 		return;
2623e12c5d1SDavid du Colombier 	free(*s);
2633e12c5d1SDavid du Colombier 	*s = alloc(RUNESIZE*want);
2643e12c5d1SDavid du Colombier 	*n = want;
2653e12c5d1SDavid du Colombier }
266