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> 93e12c5d1SDavid du Colombier #include "flayer.h" 103e12c5d1SDavid du Colombier #include "samterm.h" 113e12c5d1SDavid du Colombier 123e12c5d1SDavid du Colombier Text cmd; 133e12c5d1SDavid du Colombier Rune *scratch; 143e12c5d1SDavid du Colombier long nscralloc; 153e12c5d1SDavid du Colombier Cursor *cursor; 163e12c5d1SDavid du Colombier Flayer *which = 0; 173e12c5d1SDavid du Colombier Flayer *work = 0; 183e12c5d1SDavid du Colombier long snarflen; 193e12c5d1SDavid du Colombier long typestart = -1; 203e12c5d1SDavid du Colombier long typeend = -1; 213e12c5d1SDavid du Colombier long typeesc = -1; 223e12c5d1SDavid du Colombier long modified = 0; /* strange lookahead for menus */ 237dd7cddfSDavid du Colombier char hostlock = 1; 243e12c5d1SDavid du Colombier char hasunlocked = 0; 257dd7cddfSDavid du Colombier int maxtab = 8; 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier void 287dd7cddfSDavid du Colombier threadmain(int argc, char *argv[]) 293e12c5d1SDavid du Colombier { 30bd389b36SDavid du Colombier int i, got, scr; 313e12c5d1SDavid du Colombier Text *t; 323e12c5d1SDavid du Colombier Rectangle r; 333e12c5d1SDavid du Colombier Flayer *nwhich; 343e12c5d1SDavid du Colombier 353e12c5d1SDavid du Colombier getscreen(argc, argv); 363e12c5d1SDavid du Colombier iconinit(); 373e12c5d1SDavid du Colombier initio(); 383e12c5d1SDavid du Colombier scratch = alloc(100*RUNESIZE); 393e12c5d1SDavid du Colombier nscralloc = 100; 407dd7cddfSDavid du Colombier r = screen->r; 413e12c5d1SDavid du Colombier r.max.y = r.min.y+Dy(r)/5; 427dd7cddfSDavid du Colombier flstart(screen->clipr); 433e12c5d1SDavid du Colombier rinit(&cmd.rasp); 443e12c5d1SDavid du Colombier flnew(&cmd.l[0], gettext, 1, &cmd); 457dd7cddfSDavid du Colombier flinit(&cmd.l[0], r, font, cmdcols); 463e12c5d1SDavid du Colombier cmd.nwin = 1; 473e12c5d1SDavid du Colombier which = &cmd.l[0]; 483e12c5d1SDavid du Colombier cmd.tag = Untagged; 493e12c5d1SDavid du Colombier outTs(Tversion, VERSION); 503e12c5d1SDavid du Colombier startnewfile(Tstartcmdfile, &cmd); 513e12c5d1SDavid du Colombier 523e12c5d1SDavid du Colombier got = 0; 533e12c5d1SDavid du Colombier for(;;got = waitforio()){ 547dd7cddfSDavid du Colombier if(hasunlocked && RESIZED()) 557dd7cddfSDavid du Colombier resize(); 567dd7cddfSDavid du Colombier if(got&(1<<RHost)) 573e12c5d1SDavid du Colombier rcv(); 587dd7cddfSDavid du Colombier if(got&(1<<RPlumb)){ 59bd389b36SDavid du Colombier for(i=0; cmd.l[i].textfn==0; i++) 60bd389b36SDavid du Colombier ; 61bd389b36SDavid du Colombier current(&cmd.l[i]); 62bd389b36SDavid du Colombier flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes); 637dd7cddfSDavid du Colombier type(which, RPlumb); 64bd389b36SDavid du Colombier } 657dd7cddfSDavid du Colombier if(got&(1<<RKeyboard)) 663e12c5d1SDavid du Colombier if(which) 67bd389b36SDavid du Colombier type(which, RKeyboard); 683e12c5d1SDavid du Colombier else 693e12c5d1SDavid du Colombier kbdblock(); 707dd7cddfSDavid du Colombier if(got&(1<<RMouse)){ 717dd7cddfSDavid du Colombier if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){ 723e12c5d1SDavid du Colombier mouseunblock(); 733e12c5d1SDavid du Colombier continue; 743e12c5d1SDavid du Colombier } 757dd7cddfSDavid du Colombier nwhich = flwhich(mousep->xy); 767dd7cddfSDavid du Colombier scr = which && ptinrect(mousep->xy, which->scroll); 777dd7cddfSDavid du Colombier if(mousep->buttons) 783e12c5d1SDavid du Colombier flushtyping(1); 797dd7cddfSDavid du Colombier if(mousep->buttons&1){ 803e12c5d1SDavid du Colombier if(nwhich){ 813e12c5d1SDavid du Colombier if(nwhich!=which) 823e12c5d1SDavid du Colombier current(nwhich); 833e12c5d1SDavid du Colombier else if(scr) 843e12c5d1SDavid du Colombier scroll(which, 1); 853e12c5d1SDavid du Colombier else{ 863e12c5d1SDavid du Colombier t=(Text *)which->user1; 873e12c5d1SDavid du Colombier if(flselect(which)){ 883e12c5d1SDavid du Colombier outTsl(Tdclick, t->tag, which->p0); 893e12c5d1SDavid du Colombier t->lock++; 903e12c5d1SDavid du Colombier }else if(t!=&cmd) 913e12c5d1SDavid du Colombier outcmd(); 923e12c5d1SDavid du Colombier } 933e12c5d1SDavid du Colombier } 947dd7cddfSDavid du Colombier }else if((mousep->buttons&2) && which){ 953e12c5d1SDavid du Colombier if(scr) 963e12c5d1SDavid du Colombier scroll(which, 2); 973e12c5d1SDavid du Colombier else 983e12c5d1SDavid du Colombier menu2hit(); 997dd7cddfSDavid du Colombier }else if((mousep->buttons&4)){ 1003e12c5d1SDavid du Colombier if(scr) 1013e12c5d1SDavid du Colombier scroll(which, 3); 1023e12c5d1SDavid du Colombier else 1033e12c5d1SDavid du Colombier menu3hit(); 1043e12c5d1SDavid du Colombier } 1053e12c5d1SDavid du Colombier mouseunblock(); 1063e12c5d1SDavid du Colombier } 1073e12c5d1SDavid du Colombier } 1083e12c5d1SDavid du Colombier } 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier 1113e12c5d1SDavid du Colombier void 1127dd7cddfSDavid du Colombier resize(void){ 1133e12c5d1SDavid du Colombier int i; 1143e12c5d1SDavid du Colombier 1157dd7cddfSDavid du Colombier flresize(screen->clipr); 1163e12c5d1SDavid du Colombier for(i = 0; i<nname; i++) 1173e12c5d1SDavid du Colombier if(text[i]) 1183e12c5d1SDavid du Colombier hcheck(text[i]->tag); 1193e12c5d1SDavid du Colombier } 1203e12c5d1SDavid du Colombier 1213e12c5d1SDavid du Colombier void 1223e12c5d1SDavid du Colombier current(Flayer *nw) 1233e12c5d1SDavid du Colombier { 1243e12c5d1SDavid du Colombier Text *t; 1253e12c5d1SDavid du Colombier 1263e12c5d1SDavid du Colombier if(which) 1273e12c5d1SDavid du Colombier flborder(which, 0); 1283e12c5d1SDavid du Colombier if(nw){ 1293e12c5d1SDavid du Colombier flushtyping(1); 1303e12c5d1SDavid du Colombier flupfront(nw); 1313e12c5d1SDavid du Colombier flborder(nw, 1); 1323e12c5d1SDavid du Colombier buttons(Up); 1333e12c5d1SDavid du Colombier t = (Text *)nw->user1; 1343e12c5d1SDavid du Colombier t->front = nw-&t->l[0]; 1353e12c5d1SDavid du Colombier if(t != &cmd) 1363e12c5d1SDavid du Colombier work = nw; 1373e12c5d1SDavid du Colombier } 1383e12c5d1SDavid du Colombier which = nw; 1393e12c5d1SDavid du Colombier } 1403e12c5d1SDavid du Colombier 1413e12c5d1SDavid du Colombier void 1423e12c5d1SDavid du Colombier closeup(Flayer *l) 1433e12c5d1SDavid du Colombier { 1443e12c5d1SDavid du Colombier Text *t=(Text *)l->user1; 1453e12c5d1SDavid du Colombier int m; 1463e12c5d1SDavid du Colombier 1473e12c5d1SDavid du Colombier m = whichmenu(t->tag); 1483e12c5d1SDavid du Colombier if(m < 0) 1493e12c5d1SDavid du Colombier return; 1503e12c5d1SDavid du Colombier flclose(l); 1513e12c5d1SDavid du Colombier if(l == which){ 1523e12c5d1SDavid du Colombier which = 0; 1533e12c5d1SDavid du Colombier current(flwhich(Pt(0, 0))); 1543e12c5d1SDavid du Colombier } 1553e12c5d1SDavid du Colombier if(l == work) 1563e12c5d1SDavid du Colombier work = 0; 1573e12c5d1SDavid du Colombier if(--t->nwin == 0){ 1583e12c5d1SDavid du Colombier rclear(&t->rasp); 1593e12c5d1SDavid du Colombier free((uchar *)t); 1603e12c5d1SDavid du Colombier text[m] = 0; 1613e12c5d1SDavid du Colombier }else if(l == &t->l[t->front]){ 1623e12c5d1SDavid du Colombier for(m=0; m<NL; m++) /* find one; any one will do */ 1633e12c5d1SDavid du Colombier if(t->l[m].textfn){ 1643e12c5d1SDavid du Colombier t->front = m; 1653e12c5d1SDavid du Colombier return; 1663e12c5d1SDavid du Colombier } 1673e12c5d1SDavid du Colombier panic("close"); 1683e12c5d1SDavid du Colombier } 1693e12c5d1SDavid du Colombier } 1703e12c5d1SDavid du Colombier 1713e12c5d1SDavid du Colombier Flayer * 1723e12c5d1SDavid du Colombier findl(Text *t) 1733e12c5d1SDavid du Colombier { 1743e12c5d1SDavid du Colombier int i; 1753e12c5d1SDavid du Colombier for(i = 0; i<NL; i++) 1763e12c5d1SDavid du Colombier if(t->l[i].textfn==0) 1773e12c5d1SDavid du Colombier return &t->l[i]; 1783e12c5d1SDavid du Colombier return 0; 1793e12c5d1SDavid du Colombier } 1803e12c5d1SDavid du Colombier 1813e12c5d1SDavid du Colombier void 1823e12c5d1SDavid du Colombier duplicate(Flayer *l, Rectangle r, Font *f, int close) 1833e12c5d1SDavid du Colombier { 1843e12c5d1SDavid du Colombier Text *t=(Text *)l->user1; 1853e12c5d1SDavid du Colombier Flayer *nl = findl(t); 1863e12c5d1SDavid du Colombier Rune *rp; 1873e12c5d1SDavid du Colombier ulong n; 1883e12c5d1SDavid du Colombier 1893e12c5d1SDavid du Colombier if(nl){ 1903e12c5d1SDavid du Colombier flnew(nl, gettext, l->user0, (char *)t); 1917dd7cddfSDavid du Colombier flinit(nl, r, f, l->f.cols); 1923e12c5d1SDavid du Colombier nl->origin = l->origin; 1933e12c5d1SDavid du Colombier rp = (*l->textfn)(l, l->f.nchars, &n); 1943e12c5d1SDavid du Colombier flinsert(nl, rp, rp+n, l->origin); 1953e12c5d1SDavid du Colombier flsetselect(nl, l->p0, l->p1); 1963e12c5d1SDavid du Colombier if(close){ 1973e12c5d1SDavid du Colombier flclose(l); 1983e12c5d1SDavid du Colombier if(l==which) 1993e12c5d1SDavid du Colombier which = 0; 2003e12c5d1SDavid du Colombier }else 2013e12c5d1SDavid du Colombier t->nwin++; 2023e12c5d1SDavid du Colombier current(nl); 2033e12c5d1SDavid du Colombier hcheck(t->tag); 2043e12c5d1SDavid du Colombier } 2057dd7cddfSDavid du Colombier setcursor(mousectl, cursor); 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier 2083e12c5d1SDavid du Colombier void 2093e12c5d1SDavid du Colombier buttons(int updown) 2103e12c5d1SDavid du Colombier { 2117dd7cddfSDavid du Colombier while(((mousep->buttons&7)!=0) != updown) 2127dd7cddfSDavid du Colombier getmouse(); 2133e12c5d1SDavid du Colombier } 2143e12c5d1SDavid du Colombier 2153e12c5d1SDavid du Colombier int 2163e12c5d1SDavid du Colombier getr(Rectangle *rp) 2173e12c5d1SDavid du Colombier { 2183e12c5d1SDavid du Colombier Point p; 2193e12c5d1SDavid du Colombier Rectangle r; 2203e12c5d1SDavid du Colombier 2217dd7cddfSDavid du Colombier *rp = getrect(3, mousectl); 2223e12c5d1SDavid du Colombier if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){ 2233e12c5d1SDavid du Colombier p = rp->min; 2243e12c5d1SDavid du Colombier r = cmd.l[cmd.front].entire; 2257dd7cddfSDavid du Colombier *rp = screen->r; 2263e12c5d1SDavid du Colombier if(cmd.nwin==1){ 2273e12c5d1SDavid du Colombier if (p.y <= r.min.y) 2283e12c5d1SDavid du Colombier rp->max.y = r.min.y; 2293e12c5d1SDavid du Colombier else if (p.y >= r.max.y) 2303e12c5d1SDavid du Colombier rp->min.y = r.max.y; 2313e12c5d1SDavid du Colombier if (p.x <= r.min.x) 2323e12c5d1SDavid du Colombier rp->max.x = r.min.x; 2333e12c5d1SDavid du Colombier else if (p.x >= r.max.x) 2343e12c5d1SDavid du Colombier rp->min.x = r.max.x; 2353e12c5d1SDavid du Colombier } 2363e12c5d1SDavid du Colombier } 2377dd7cddfSDavid du Colombier return rectclip(rp, screen->r) && 2383e12c5d1SDavid du Colombier rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40; 2393e12c5d1SDavid du Colombier } 2403e12c5d1SDavid du Colombier 2413e12c5d1SDavid du Colombier void 2423e12c5d1SDavid du Colombier snarf(Text *t, int w) 2433e12c5d1SDavid du Colombier { 2443e12c5d1SDavid du Colombier Flayer *l = &t->l[w]; 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier if(l->p1>l->p0){ 2473e12c5d1SDavid du Colombier snarflen = l->p1-l->p0; 2483e12c5d1SDavid du Colombier outTsll(Tsnarf, t->tag, l->p0, l->p1); 2493e12c5d1SDavid du Colombier } 2503e12c5d1SDavid du Colombier } 2513e12c5d1SDavid du Colombier 2523e12c5d1SDavid du Colombier void 2533e12c5d1SDavid du Colombier cut(Text *t, int w, int save, int check) 2543e12c5d1SDavid du Colombier { 2553e12c5d1SDavid du Colombier long p0, p1; 256bd389b36SDavid du Colombier Flayer *l; 2573e12c5d1SDavid du Colombier 258bd389b36SDavid du Colombier l = &t->l[w]; 259bd389b36SDavid du Colombier p0 = l->p0; 260bd389b36SDavid du Colombier p1 = l->p1; 261bd389b36SDavid du Colombier if(p0 == p1) 2623e12c5d1SDavid du Colombier return; 2633e12c5d1SDavid du Colombier if(p0 < 0) 2643e12c5d1SDavid du Colombier panic("cut"); 2653e12c5d1SDavid du Colombier if(save) 2663e12c5d1SDavid du Colombier snarf(t, w); 2673e12c5d1SDavid du Colombier outTsll(Tcut, t->tag, p0, p1); 268bd389b36SDavid du Colombier flsetselect(l, p0, p0); 2693e12c5d1SDavid du Colombier t->lock++; 2703e12c5d1SDavid du Colombier hcut(t->tag, p0, p1-p0); 2713e12c5d1SDavid du Colombier if(check) 2723e12c5d1SDavid du Colombier hcheck(t->tag); 2733e12c5d1SDavid du Colombier } 2743e12c5d1SDavid du Colombier 2753e12c5d1SDavid du Colombier void 2763e12c5d1SDavid du Colombier paste(Text *t, int w) 2773e12c5d1SDavid du Colombier { 2783e12c5d1SDavid du Colombier if(snarflen){ 2793e12c5d1SDavid du Colombier cut(t, w, 0, 0); 2803e12c5d1SDavid du Colombier t->lock++; 2813e12c5d1SDavid du Colombier outTsl(Tpaste, t->tag, t->l[w].p0); 2823e12c5d1SDavid du Colombier } 2833e12c5d1SDavid du Colombier } 2843e12c5d1SDavid du Colombier 2853e12c5d1SDavid du Colombier void 2863e12c5d1SDavid du Colombier scrorigin(Flayer *l, int but, long p0) 2873e12c5d1SDavid du Colombier { 2883e12c5d1SDavid du Colombier Text *t=(Text *)l->user1; 2893e12c5d1SDavid du Colombier 2903e12c5d1SDavid du Colombier switch(but){ 2913e12c5d1SDavid du Colombier case 1: 2923e12c5d1SDavid du Colombier outTsll(Torigin, t->tag, l->origin, p0); 2933e12c5d1SDavid du Colombier break; 2943e12c5d1SDavid du Colombier case 2: 2953e12c5d1SDavid du Colombier outTsll(Torigin, t->tag, p0, 1L); 2963e12c5d1SDavid du Colombier break; 2973e12c5d1SDavid du Colombier case 3: 2983e12c5d1SDavid du Colombier horigin(t->tag,p0); 2993e12c5d1SDavid du Colombier } 3003e12c5d1SDavid du Colombier } 3013e12c5d1SDavid du Colombier 3023e12c5d1SDavid du Colombier int 3033e12c5d1SDavid du Colombier alnum(int c) 3043e12c5d1SDavid du Colombier { 3053e12c5d1SDavid du Colombier /* 3063e12c5d1SDavid du Colombier * Hard to get absolutely right. Use what we know about ASCII 3073e12c5d1SDavid du Colombier * and assume anything above the Latin control characters is 3083e12c5d1SDavid du Colombier * potentially an alphanumeric. 3093e12c5d1SDavid du Colombier */ 3103e12c5d1SDavid du Colombier if(c<=' ') 3113e12c5d1SDavid du Colombier return 0; 3123e12c5d1SDavid du Colombier if(0x7F<=c && c<=0xA0) 3133e12c5d1SDavid du Colombier return 0; 3143e12c5d1SDavid du Colombier if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c)) 3153e12c5d1SDavid du Colombier return 0; 3163e12c5d1SDavid du Colombier return 1; 3173e12c5d1SDavid du Colombier } 3183e12c5d1SDavid du Colombier 3193e12c5d1SDavid du Colombier int 3203e12c5d1SDavid du Colombier raspc(Rasp *r, long p) 3213e12c5d1SDavid du Colombier { 3223e12c5d1SDavid du Colombier ulong n; 3233e12c5d1SDavid du Colombier rload(r, p, p+1, &n); 3243e12c5d1SDavid du Colombier if(n) 3253e12c5d1SDavid du Colombier return scratch[0]; 3263e12c5d1SDavid du Colombier return 0; 3273e12c5d1SDavid du Colombier } 3283e12c5d1SDavid du Colombier 3293e12c5d1SDavid du Colombier long 3303e12c5d1SDavid du Colombier ctlw(Rasp *r, long o, long p) 3313e12c5d1SDavid du Colombier { 3323e12c5d1SDavid du Colombier int c; 3333e12c5d1SDavid du Colombier 3343e12c5d1SDavid du Colombier if(--p < o) 3353e12c5d1SDavid du Colombier return o; 3363e12c5d1SDavid du Colombier if(raspc(r, p)=='\n') 3373e12c5d1SDavid du Colombier return p; 3383e12c5d1SDavid du Colombier for(; p>=o && !alnum(c=raspc(r, p)); --p) 3393e12c5d1SDavid du Colombier if(c=='\n') 3403e12c5d1SDavid du Colombier return p+1; 3413e12c5d1SDavid du Colombier for(; p>o && alnum(raspc(r, p-1)); --p) 3423e12c5d1SDavid du Colombier ; 3433e12c5d1SDavid du Colombier return p>=o? p : o; 3443e12c5d1SDavid du Colombier } 3453e12c5d1SDavid du Colombier 3463e12c5d1SDavid du Colombier long 3473e12c5d1SDavid du Colombier ctlu(Rasp *r, long o, long p) 3483e12c5d1SDavid du Colombier { 349*f43e6a25SDavid du Colombier if(--p < o) 350*f43e6a25SDavid du Colombier return o; 351*f43e6a25SDavid du Colombier if(raspc(r, p)=='\n') 352*f43e6a25SDavid du Colombier return p; 3533e12c5d1SDavid du Colombier for(; p-1>=o && raspc(r, p-1)!='\n'; --p) 3543e12c5d1SDavid du Colombier ; 3553e12c5d1SDavid du Colombier return p>=o? p : o; 3563e12c5d1SDavid du Colombier } 3573e12c5d1SDavid du Colombier 3583e12c5d1SDavid du Colombier int 3593e12c5d1SDavid du Colombier center(Flayer *l, long a) 3603e12c5d1SDavid du Colombier { 3613e12c5d1SDavid du Colombier Text *t; 3623e12c5d1SDavid du Colombier 3633e12c5d1SDavid du Colombier t = l->user1; 3643e12c5d1SDavid du Colombier if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){ 3653e12c5d1SDavid du Colombier if(a > t->rasp.nrunes) 3663e12c5d1SDavid du Colombier a = t->rasp.nrunes; 3673e12c5d1SDavid du Colombier outTsll(Torigin, t->tag, a, 2L); 3683e12c5d1SDavid du Colombier return 1; 3693e12c5d1SDavid du Colombier } 3703e12c5d1SDavid du Colombier return 0; 3713e12c5d1SDavid du Colombier } 3723e12c5d1SDavid du Colombier 3733e12c5d1SDavid du Colombier int 3743e12c5d1SDavid du Colombier onethird(Flayer *l, long a) 3753e12c5d1SDavid du Colombier { 3763e12c5d1SDavid du Colombier Text *t; 3773e12c5d1SDavid du Colombier Rectangle s; 3783e12c5d1SDavid du Colombier long lines; 3793e12c5d1SDavid du Colombier 3803e12c5d1SDavid du Colombier t = l->user1; 3813e12c5d1SDavid du Colombier if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){ 3823e12c5d1SDavid du Colombier if(a > t->rasp.nrunes) 3833e12c5d1SDavid du Colombier a = t->rasp.nrunes; 3847dd7cddfSDavid du Colombier s = insetrect(l->scroll, 1); 3853e12c5d1SDavid du Colombier lines = ((s.max.y-s.min.y)/l->f.font->height+1)/3; 3863e12c5d1SDavid du Colombier if (lines < 2) 3873e12c5d1SDavid du Colombier lines = 2; 3883e12c5d1SDavid du Colombier outTsll(Torigin, t->tag, a, lines); 3893e12c5d1SDavid du Colombier return 1; 3903e12c5d1SDavid du Colombier } 3913e12c5d1SDavid du Colombier return 0; 3923e12c5d1SDavid du Colombier } 3933e12c5d1SDavid du Colombier 3943e12c5d1SDavid du Colombier void 3953e12c5d1SDavid du Colombier flushtyping(int clearesc) 3963e12c5d1SDavid du Colombier { 3973e12c5d1SDavid du Colombier Text *t; 3983e12c5d1SDavid du Colombier ulong n; 3993e12c5d1SDavid du Colombier 4003e12c5d1SDavid du Colombier if(clearesc) 4013e12c5d1SDavid du Colombier typeesc = -1; 4023e12c5d1SDavid du Colombier if(typestart == typeend) { 4033e12c5d1SDavid du Colombier modified = 0; 4043e12c5d1SDavid du Colombier return; 4053e12c5d1SDavid du Colombier } 4063e12c5d1SDavid du Colombier t = which->user1; 407219b2ee8SDavid du Colombier if(t != &cmd) 408219b2ee8SDavid du Colombier modified = 1; 4093e12c5d1SDavid du Colombier rload(&t->rasp, typestart, typeend, &n); 4103e12c5d1SDavid du Colombier scratch[n] = 0; 4113e12c5d1SDavid du Colombier if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){ 4123e12c5d1SDavid du Colombier setlock(); 4133e12c5d1SDavid du Colombier outcmd(); 4143e12c5d1SDavid du Colombier } 4153e12c5d1SDavid du Colombier outTslS(Ttype, t->tag, typestart, scratch); 4163e12c5d1SDavid du Colombier typestart = -1; 4173e12c5d1SDavid du Colombier typeend = -1; 4183e12c5d1SDavid du Colombier } 4193e12c5d1SDavid du Colombier 4207dd7cddfSDavid du Colombier #define SCROLLKEY Kdown 4217dd7cddfSDavid du Colombier #define BACKSCROLLKEY Kup 4223e12c5d1SDavid du Colombier #define ESC 0x1B 4233e12c5d1SDavid du Colombier 4243e12c5d1SDavid du Colombier void 425bd389b36SDavid du Colombier type(Flayer *l, int res) /* what a bloody mess this is */ 4263e12c5d1SDavid du Colombier { 4273e12c5d1SDavid du Colombier Text *t = (Text *)l->user1; 4283e12c5d1SDavid du Colombier Rune buf[100]; 4293e12c5d1SDavid du Colombier Rune *p = buf; 430bd389b36SDavid du Colombier int c, backspacing; 4317dd7cddfSDavid du Colombier long a, a0; 432bd389b36SDavid du Colombier int scrollkey; 433bd389b36SDavid du Colombier 434bd389b36SDavid du Colombier scrollkey = 0; 435bd389b36SDavid du Colombier if(res == RKeyboard) 4367dd7cddfSDavid du Colombier scrollkey = (qpeekc()==SCROLLKEY || qpeekc()==BACKSCROLLKEY); /* ICK */ 4373e12c5d1SDavid du Colombier 4387dd7cddfSDavid du Colombier if(hostlock || t->lock){ 4393e12c5d1SDavid du Colombier kbdblock(); 4403e12c5d1SDavid du Colombier return; 4413e12c5d1SDavid du Colombier } 4423e12c5d1SDavid du Colombier a = l->p0; 4433e12c5d1SDavid du Colombier if(a!=l->p1 && !scrollkey){ 4443e12c5d1SDavid du Colombier flushtyping(1); 4453e12c5d1SDavid du Colombier cut(t, t->front, 1, 1); 4463e12c5d1SDavid du Colombier return; /* it may now be locked */ 4473e12c5d1SDavid du Colombier } 448bd389b36SDavid du Colombier backspacing = 0; 449bd389b36SDavid du Colombier while((c = kbdchar())>0){ 450bd389b36SDavid du Colombier if(res == RKeyboard){ 4517dd7cddfSDavid du Colombier if(c==SCROLLKEY || c==BACKSCROLLKEY || c==ESC) 452bd389b36SDavid du Colombier break; 453bd389b36SDavid du Colombier /* backspace, ctrl-u, ctrl-w, del */ 454bd389b36SDavid du Colombier if(c=='\b' || c==0x15 || c==0x17 || c==0x7F){ 4553e12c5d1SDavid du Colombier backspacing = 1; 4563e12c5d1SDavid du Colombier break; 457bd389b36SDavid du Colombier } 458bd389b36SDavid du Colombier } 4593e12c5d1SDavid du Colombier *p++ = c; 460bd389b36SDavid du Colombier if(c == '\n' || p >= buf+sizeof(buf)/sizeof(buf[0])) 4613e12c5d1SDavid du Colombier break; 4623e12c5d1SDavid du Colombier } 4633e12c5d1SDavid du Colombier if(p > buf){ 4643e12c5d1SDavid du Colombier if(typestart < 0) 4653e12c5d1SDavid du Colombier typestart = a; 4663e12c5d1SDavid du Colombier if(typeesc < 0) 4673e12c5d1SDavid du Colombier typeesc = a; 4683e12c5d1SDavid du Colombier hgrow(t->tag, a, p-buf, 0); 4693e12c5d1SDavid du Colombier t->lock++; /* pretend we Trequest'ed for hdatarune*/ 4703e12c5d1SDavid du Colombier hdatarune(t->tag, a, buf, p-buf); 4713e12c5d1SDavid du Colombier a += p-buf; 4723e12c5d1SDavid du Colombier l->p0 = a; 4733e12c5d1SDavid du Colombier l->p1 = a; 4743e12c5d1SDavid du Colombier typeend = a; 4753e12c5d1SDavid du Colombier if(c=='\n' || typeend-typestart>100) 4763e12c5d1SDavid du Colombier flushtyping(0); 4773e12c5d1SDavid du Colombier onethird(l, a); 4783e12c5d1SDavid du Colombier } 4793e12c5d1SDavid du Colombier if(c == SCROLLKEY){ 4803e12c5d1SDavid du Colombier flushtyping(0); 4813e12c5d1SDavid du Colombier center(l, l->origin+l->f.nchars+1); 4823e12c5d1SDavid du Colombier /* backspacing immediately after outcmd(): sorry */ 4837dd7cddfSDavid du Colombier }else if(c == BACKSCROLLKEY){ 4847dd7cddfSDavid du Colombier flushtyping(0); 4857dd7cddfSDavid du Colombier a0 = l->origin-l->f.nchars; 4867dd7cddfSDavid du Colombier if(a0 < 0) 4877dd7cddfSDavid du Colombier a0 = 0; 4887dd7cddfSDavid du Colombier center(l, a0); 4897dd7cddfSDavid du Colombier }else if(backspacing && !hostlock){ 4903e12c5d1SDavid du Colombier if(l->f.p0>0 && a>0){ 4913e12c5d1SDavid du Colombier switch(c){ 4923e12c5d1SDavid du Colombier case '\b': 4933e12c5d1SDavid du Colombier case 0x7F: /* del */ 4943e12c5d1SDavid du Colombier l->p0 = a-1; 4953e12c5d1SDavid du Colombier break; 4963e12c5d1SDavid du Colombier case 0x15: /* ctrl-u */ 4973e12c5d1SDavid du Colombier l->p0 = ctlu(&t->rasp, l->origin, a); 4983e12c5d1SDavid du Colombier break; 4993e12c5d1SDavid du Colombier case 0x17: /* ctrl-w */ 5003e12c5d1SDavid du Colombier l->p0 = ctlw(&t->rasp, l->origin, a); 5013e12c5d1SDavid du Colombier break; 5023e12c5d1SDavid du Colombier } 5033e12c5d1SDavid du Colombier l->p1 = a; 5043e12c5d1SDavid du Colombier if(l->p1 != l->p0){ 5053e12c5d1SDavid du Colombier /* cut locally if possible */ 5063e12c5d1SDavid du Colombier if(typestart<=l->p0 && l->p1<=typeend){ 5073e12c5d1SDavid du Colombier t->lock++; /* to call hcut */ 5083e12c5d1SDavid du Colombier hcut(t->tag, l->p0, l->p1-l->p0); 5093e12c5d1SDavid du Colombier /* hcheck is local because we know rasp is contiguous */ 5103e12c5d1SDavid du Colombier hcheck(t->tag); 5113e12c5d1SDavid du Colombier }else{ 5123e12c5d1SDavid du Colombier flushtyping(0); 5133e12c5d1SDavid du Colombier cut(t, t->front, 0, 1); 5143e12c5d1SDavid du Colombier } 5153e12c5d1SDavid du Colombier } 5163e12c5d1SDavid du Colombier if(typeesc >= l->p0) 5173e12c5d1SDavid du Colombier typeesc = l->p0; 5183e12c5d1SDavid du Colombier if(typestart >= 0){ 5193e12c5d1SDavid du Colombier if(typestart >= l->p0) 5203e12c5d1SDavid du Colombier typestart = l->p0; 5213e12c5d1SDavid du Colombier typeend = l->p0; 5223e12c5d1SDavid du Colombier if(typestart == typeend){ 5233e12c5d1SDavid du Colombier typestart = -1; 5243e12c5d1SDavid du Colombier typeend = -1; 5253e12c5d1SDavid du Colombier modified = 0; 5263e12c5d1SDavid du Colombier } 5273e12c5d1SDavid du Colombier } 5283e12c5d1SDavid du Colombier } 5293e12c5d1SDavid du Colombier }else{ 5303e12c5d1SDavid du Colombier if(c==ESC && typeesc>=0){ 5313e12c5d1SDavid du Colombier l->p0 = typeesc; 5323e12c5d1SDavid du Colombier l->p1 = a; 5333e12c5d1SDavid du Colombier flushtyping(1); 5343e12c5d1SDavid du Colombier } 5353e12c5d1SDavid du Colombier for(l=t->l; l<&t->l[NL]; l++) 5363e12c5d1SDavid du Colombier if(l->textfn) 5373e12c5d1SDavid du Colombier flsetselect(l, l->p0, l->p1); 5383e12c5d1SDavid du Colombier } 5393e12c5d1SDavid du Colombier } 5403e12c5d1SDavid du Colombier 5413e12c5d1SDavid du Colombier 5423e12c5d1SDavid du Colombier void 5433e12c5d1SDavid du Colombier outcmd(void){ 5443e12c5d1SDavid du Colombier if(work) 5453e12c5d1SDavid du Colombier outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1); 5463e12c5d1SDavid du Colombier } 5473e12c5d1SDavid du Colombier 5483e12c5d1SDavid du Colombier void 5493e12c5d1SDavid du Colombier panic(char *s) 5503e12c5d1SDavid du Colombier { 5517dd7cddfSDavid du Colombier panic1(display, s); 5527dd7cddfSDavid du Colombier } 5537dd7cddfSDavid du Colombier 5547dd7cddfSDavid du Colombier void 5557dd7cddfSDavid du Colombier panic1(Display*, char *s) 5567dd7cddfSDavid du Colombier { 5573e12c5d1SDavid du Colombier fprint(2, "samterm:panic: "); 5583e12c5d1SDavid du Colombier perror(s); 5593e12c5d1SDavid du Colombier abort(); 5603e12c5d1SDavid du Colombier } 5613e12c5d1SDavid du Colombier 5623e12c5d1SDavid du Colombier Rune* 5633e12c5d1SDavid du Colombier gettext(Flayer *l, long n, ulong *np) 5643e12c5d1SDavid du Colombier { 5653e12c5d1SDavid du Colombier Text *t; 5663e12c5d1SDavid du Colombier 5673e12c5d1SDavid du Colombier t = l->user1; 5683e12c5d1SDavid du Colombier rload(&t->rasp, l->origin, l->origin+n, np); 5693e12c5d1SDavid du Colombier return scratch; 5703e12c5d1SDavid du Colombier } 5713e12c5d1SDavid du Colombier 5723e12c5d1SDavid du Colombier long 5733e12c5d1SDavid du Colombier scrtotal(Flayer *l) 5743e12c5d1SDavid du Colombier { 5753e12c5d1SDavid du Colombier return ((Text *)l->user1)->rasp.nrunes; 5763e12c5d1SDavid du Colombier } 5773e12c5d1SDavid du Colombier 5783e12c5d1SDavid du Colombier void* 5793e12c5d1SDavid du Colombier alloc(ulong n) 5803e12c5d1SDavid du Colombier { 5813e12c5d1SDavid du Colombier void *p; 5823e12c5d1SDavid du Colombier 5833e12c5d1SDavid du Colombier p = malloc(n); 5843e12c5d1SDavid du Colombier if(p == 0) 5853e12c5d1SDavid du Colombier panic("alloc"); 5863e12c5d1SDavid du Colombier memset(p, 0, n); 5873e12c5d1SDavid du Colombier return p; 5883e12c5d1SDavid du Colombier } 589