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