13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <libg.h> 43e12c5d1SDavid du Colombier #include <frame.h> 53e12c5d1SDavid du Colombier #include "flayer.h" 63e12c5d1SDavid du Colombier #include "samterm.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier uchar *name[MAXFILES]; /* first byte is ' ' or '\'': modified state */ 93e12c5d1SDavid du Colombier Text *text[MAXFILES]; /* pointer to Text associated with file */ 103e12c5d1SDavid du Colombier ushort tag[MAXFILES]; /* text[i].tag, even if text[i] not defined */ 113e12c5d1SDavid du Colombier int nname; 123e12c5d1SDavid du Colombier int mw; 133e12c5d1SDavid du Colombier 143e12c5d1SDavid du Colombier char *genmenu3(int); 153e12c5d1SDavid du Colombier char *genmenu2(int); 163e12c5d1SDavid du Colombier char *genmenu2c(int); 173e12c5d1SDavid du Colombier 183e12c5d1SDavid du Colombier enum Menu2 193e12c5d1SDavid du Colombier { 203e12c5d1SDavid du Colombier Cut, 213e12c5d1SDavid du Colombier Paste, 223e12c5d1SDavid du Colombier Snarf, 233e12c5d1SDavid du Colombier Look, 243e12c5d1SDavid du Colombier Exch, 253e12c5d1SDavid du Colombier Search, 263e12c5d1SDavid du Colombier NMENU2 = Search, 273e12c5d1SDavid du Colombier Send = Search, 283e12c5d1SDavid du Colombier NMENU2C 293e12c5d1SDavid du Colombier }; 303e12c5d1SDavid du Colombier 313e12c5d1SDavid du Colombier enum Menu3 323e12c5d1SDavid du Colombier { 333e12c5d1SDavid du Colombier New, 34*219b2ee8SDavid du Colombier Zerox, 353e12c5d1SDavid du Colombier Reshape, 363e12c5d1SDavid du Colombier Close, 373e12c5d1SDavid du Colombier Write, 383e12c5d1SDavid du Colombier NMENU3 393e12c5d1SDavid du Colombier }; 403e12c5d1SDavid du Colombier 413e12c5d1SDavid du Colombier char *menu2str[] = { 423e12c5d1SDavid du Colombier "cut", 433e12c5d1SDavid du Colombier "paste", 443e12c5d1SDavid du Colombier "snarf", 453e12c5d1SDavid du Colombier "look", 463e12c5d1SDavid du Colombier "<8½>", 473e12c5d1SDavid du Colombier 0, /* storage for last pattern */ 483e12c5d1SDavid du Colombier }; 493e12c5d1SDavid du Colombier 503e12c5d1SDavid du Colombier char *menu3str[] = { 513e12c5d1SDavid du Colombier "new", 52*219b2ee8SDavid du Colombier "zerox", 533e12c5d1SDavid du Colombier "reshape", 543e12c5d1SDavid du Colombier "close", 553e12c5d1SDavid du Colombier "write", 563e12c5d1SDavid du Colombier }; 573e12c5d1SDavid du Colombier 583e12c5d1SDavid du Colombier Menu menu2 = {0, genmenu2}; 593e12c5d1SDavid du Colombier Menu menu2c ={0, genmenu2c}; 603e12c5d1SDavid du Colombier Menu menu3 = {0, genmenu3}; 613e12c5d1SDavid du Colombier 623e12c5d1SDavid du Colombier void 633e12c5d1SDavid du Colombier menu2hit(void) 643e12c5d1SDavid du Colombier { 653e12c5d1SDavid du Colombier Text *t=(Text *)which->user1; 663e12c5d1SDavid du Colombier int w = which-t->l; 67bd389b36SDavid du Colombier int m; 683e12c5d1SDavid du Colombier 69bd389b36SDavid du Colombier m = menuhit(2, &mouse, t==&cmd? &menu2c : &menu2); 70bd389b36SDavid du Colombier if(lock || t->lock) 71bd389b36SDavid du Colombier return; 72bd389b36SDavid du Colombier 73bd389b36SDavid du Colombier switch(m){ 743e12c5d1SDavid du Colombier case Cut: 753e12c5d1SDavid du Colombier cut(t, w, 1, 1); 763e12c5d1SDavid du Colombier break; 773e12c5d1SDavid du Colombier 783e12c5d1SDavid du Colombier case Paste: 793e12c5d1SDavid du Colombier paste(t, w); 803e12c5d1SDavid du Colombier break; 813e12c5d1SDavid du Colombier 823e12c5d1SDavid du Colombier case Snarf: 833e12c5d1SDavid du Colombier snarf(t, w); 843e12c5d1SDavid du Colombier break; 853e12c5d1SDavid du Colombier 863e12c5d1SDavid du Colombier case Exch: 873e12c5d1SDavid du Colombier outT0(Tstartsnarf); 883e12c5d1SDavid du Colombier setlock(); 893e12c5d1SDavid du Colombier break; 903e12c5d1SDavid du Colombier 913e12c5d1SDavid du Colombier case Look: 923e12c5d1SDavid du Colombier outTsll(Tlook, t->tag, which->p0, which->p1); 933e12c5d1SDavid du Colombier setlock(); 943e12c5d1SDavid du Colombier break; 953e12c5d1SDavid du Colombier 963e12c5d1SDavid du Colombier case Search: 973e12c5d1SDavid du Colombier outcmd(); 983e12c5d1SDavid du Colombier if(t==&cmd) 993e12c5d1SDavid du Colombier outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1); 1003e12c5d1SDavid du Colombier else 1013e12c5d1SDavid du Colombier outT0(Tsearch); 1023e12c5d1SDavid du Colombier setlock(); 1033e12c5d1SDavid du Colombier break; 1043e12c5d1SDavid du Colombier } 1053e12c5d1SDavid du Colombier } 1063e12c5d1SDavid du Colombier 1073e12c5d1SDavid du Colombier void 1083e12c5d1SDavid du Colombier menu3hit(void) 1093e12c5d1SDavid du Colombier { 1103e12c5d1SDavid du Colombier Rectangle r; 1113e12c5d1SDavid du Colombier Flayer *l; 1123e12c5d1SDavid du Colombier int m, i; 1133e12c5d1SDavid du Colombier Text *t; 1143e12c5d1SDavid du Colombier 1153e12c5d1SDavid du Colombier mw = -1; 1163e12c5d1SDavid du Colombier switch(m = menuhit(3, &mouse, &menu3)){ 1173e12c5d1SDavid du Colombier case -1: 1183e12c5d1SDavid du Colombier break; 1193e12c5d1SDavid du Colombier 1203e12c5d1SDavid du Colombier case New: 1213e12c5d1SDavid du Colombier if(!lock) 1223e12c5d1SDavid du Colombier sweeptext(1, 0); 1233e12c5d1SDavid du Colombier break; 1243e12c5d1SDavid du Colombier 125*219b2ee8SDavid du Colombier case Zerox: 1263e12c5d1SDavid du Colombier case Reshape: 1273e12c5d1SDavid du Colombier if(!lock){ 1283e12c5d1SDavid du Colombier cursorswitch(&bullseye); 1293e12c5d1SDavid du Colombier buttons(Down); 1303e12c5d1SDavid du Colombier if((mouse.buttons&4) && (l = flwhich(mouse.xy)) && getr(&r)) 1313e12c5d1SDavid du Colombier duplicate(l, r, l->f.font, m==Reshape); 1323e12c5d1SDavid du Colombier else 1333e12c5d1SDavid du Colombier cursorswitch(cursor); 1343e12c5d1SDavid du Colombier buttons(Up); 1353e12c5d1SDavid du Colombier } 1363e12c5d1SDavid du Colombier break; 1373e12c5d1SDavid du Colombier 1383e12c5d1SDavid du Colombier case Close: 1393e12c5d1SDavid du Colombier if(!lock){ 1403e12c5d1SDavid du Colombier cursorswitch(&bullseye); 1413e12c5d1SDavid du Colombier buttons(Down); 1423e12c5d1SDavid du Colombier if((mouse.buttons&4) && (l = flwhich(mouse.xy)) && !lock){ 1433e12c5d1SDavid du Colombier t=(Text *)l->user1; 1443e12c5d1SDavid du Colombier if (t->nwin>1) 1453e12c5d1SDavid du Colombier closeup(l); 146*219b2ee8SDavid du Colombier else if(t!=&cmd) { 1473e12c5d1SDavid du Colombier outTs(Tclose, t->tag); 148*219b2ee8SDavid du Colombier setlock(); 1493e12c5d1SDavid du Colombier } 1503e12c5d1SDavid du Colombier } 1513e12c5d1SDavid du Colombier cursorswitch(cursor); 1523e12c5d1SDavid du Colombier buttons(Up); 1533e12c5d1SDavid du Colombier } 1543e12c5d1SDavid du Colombier break; 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier case Write: 1573e12c5d1SDavid du Colombier if(!lock){ 1583e12c5d1SDavid du Colombier cursorswitch(&bullseye); 1593e12c5d1SDavid du Colombier buttons(Down); 1603e12c5d1SDavid du Colombier if((mouse.buttons&4) && (l = flwhich(mouse.xy))){ 1613e12c5d1SDavid du Colombier outTs(Twrite, ((Text *)l->user1)->tag); 1623e12c5d1SDavid du Colombier setlock(); 1633e12c5d1SDavid du Colombier }else 1643e12c5d1SDavid du Colombier cursorswitch(cursor); 1653e12c5d1SDavid du Colombier buttons(Up); 1663e12c5d1SDavid du Colombier } 1673e12c5d1SDavid du Colombier break; 1683e12c5d1SDavid du Colombier 1693e12c5d1SDavid du Colombier default: 1703e12c5d1SDavid du Colombier if(t = text[m-NMENU3]){ 1713e12c5d1SDavid du Colombier i = t->front; 1723e12c5d1SDavid du Colombier if(t->nwin==0 || t->l[i].textfn==0) 1733e12c5d1SDavid du Colombier return; /* not ready yet; try again later */ 1743e12c5d1SDavid du Colombier if(t->nwin>1 && which==&t->l[i]) 1753e12c5d1SDavid du Colombier do 1763e12c5d1SDavid du Colombier if(++i==NL) 1773e12c5d1SDavid du Colombier i = 0; 1783e12c5d1SDavid du Colombier while(i!=t->front && t->l[i].textfn==0); 1793e12c5d1SDavid du Colombier current(&t->l[i]); 180bd389b36SDavid du Colombier }else if(!lock) 1813e12c5d1SDavid du Colombier sweeptext(0, tag[m-NMENU3]); 1823e12c5d1SDavid du Colombier break; 1833e12c5d1SDavid du Colombier } 1843e12c5d1SDavid du Colombier } 1853e12c5d1SDavid du Colombier 1863e12c5d1SDavid du Colombier 1873e12c5d1SDavid du Colombier Text * 1883e12c5d1SDavid du Colombier sweeptext(int new, int tag) 1893e12c5d1SDavid du Colombier { 1903e12c5d1SDavid du Colombier Rectangle r; 1913e12c5d1SDavid du Colombier Text *t; 1923e12c5d1SDavid du Colombier 1933e12c5d1SDavid du Colombier if(getr(&r) && (t = malloc(sizeof(Text)))){ 194*219b2ee8SDavid du Colombier memset((void*)t, 0, sizeof(Text)); 1953e12c5d1SDavid du Colombier current((Flayer *)0); 1963e12c5d1SDavid du Colombier flnew(&t->l[0], gettext, 0, (char *)t); 1973e12c5d1SDavid du Colombier flinit(&t->l[0], r, font); /*bnl*/ 1983e12c5d1SDavid du Colombier t->nwin = 1; 1993e12c5d1SDavid du Colombier rinit(&t->rasp); 2003e12c5d1SDavid du Colombier if(new) 2013e12c5d1SDavid du Colombier startnewfile(Tstartnewfile, t); 2023e12c5d1SDavid du Colombier else{ 2033e12c5d1SDavid du Colombier rinit(&t->rasp); 2043e12c5d1SDavid du Colombier t->tag = tag; 2053e12c5d1SDavid du Colombier startfile(t); 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier return t; 2083e12c5d1SDavid du Colombier } 2093e12c5d1SDavid du Colombier return 0; 2103e12c5d1SDavid du Colombier } 2113e12c5d1SDavid du Colombier 2123e12c5d1SDavid du Colombier int 2133e12c5d1SDavid du Colombier whichmenu(int tg) 2143e12c5d1SDavid du Colombier { 2153e12c5d1SDavid du Colombier int i; 2163e12c5d1SDavid du Colombier 2173e12c5d1SDavid du Colombier for(i=0; i<nname; i++) 2183e12c5d1SDavid du Colombier if(tag[i] == tg) 2193e12c5d1SDavid du Colombier return i; 2203e12c5d1SDavid du Colombier return -1; 2213e12c5d1SDavid du Colombier } 2223e12c5d1SDavid du Colombier 2233e12c5d1SDavid du Colombier void 2243e12c5d1SDavid du Colombier menuins(int n, uchar *s, Text *t, int m, int tg) 2253e12c5d1SDavid du Colombier { 2263e12c5d1SDavid du Colombier int i; 2273e12c5d1SDavid du Colombier 2283e12c5d1SDavid du Colombier if(nname == MAXFILES) 2293e12c5d1SDavid du Colombier panic("menuins"); 2303e12c5d1SDavid du Colombier for(i=nname; i>n; --i) 2313e12c5d1SDavid du Colombier name[i]=name[i-1], text[i]=text[i-1], tag[i]=tag[i-1]; 2323e12c5d1SDavid du Colombier text[n] = t; 2333e12c5d1SDavid du Colombier tag[n] = tg; 2343e12c5d1SDavid du Colombier name[n] = alloc(strlen((char*)s)+2); 2353e12c5d1SDavid du Colombier name[n][0] = m; 2363e12c5d1SDavid du Colombier strcpy((char*)name[n]+1, (char*)s); 2373e12c5d1SDavid du Colombier nname++; 238bd389b36SDavid du Colombier menu3.lasthit = n+NMENU3; 2393e12c5d1SDavid du Colombier } 2403e12c5d1SDavid du Colombier 2413e12c5d1SDavid du Colombier void 2423e12c5d1SDavid du Colombier menudel(int n) 2433e12c5d1SDavid du Colombier { 2443e12c5d1SDavid du Colombier int i; 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier if(nname==0 || n>=nname || text[n]) 2473e12c5d1SDavid du Colombier panic("menudel"); 2483e12c5d1SDavid du Colombier free(name[n]); 2493e12c5d1SDavid du Colombier --nname; 2503e12c5d1SDavid du Colombier for(i = n; i<nname; i++) 2513e12c5d1SDavid du Colombier name[i]=name[i+1], text[i]=text[i+1], tag[i]=tag[i+1]; 2523e12c5d1SDavid du Colombier } 2533e12c5d1SDavid du Colombier 2543e12c5d1SDavid du Colombier void 2553e12c5d1SDavid du Colombier setpat(char *s) 2563e12c5d1SDavid du Colombier { 2573e12c5d1SDavid du Colombier static char pat[17]; 2583e12c5d1SDavid du Colombier 2593e12c5d1SDavid du Colombier pat[0] = '/'; 2603e12c5d1SDavid du Colombier strncpy(pat+1, s, 15); 2613e12c5d1SDavid du Colombier menu2str[Search] = pat; 2623e12c5d1SDavid du Colombier } 2633e12c5d1SDavid du Colombier 2643e12c5d1SDavid du Colombier #define NBUF 64 2653e12c5d1SDavid du Colombier static uchar buf[NBUF*UTFmax]={' ', ' ', ' ', ' '}; 2663e12c5d1SDavid du Colombier 2673e12c5d1SDavid du Colombier char * 2683e12c5d1SDavid du Colombier paren(char *s) 2693e12c5d1SDavid du Colombier { 2703e12c5d1SDavid du Colombier uchar *t = buf; 2713e12c5d1SDavid du Colombier 2723e12c5d1SDavid du Colombier *t++ = '('; 2733e12c5d1SDavid du Colombier do; while(*t++ = *s++); 2743e12c5d1SDavid du Colombier t[-1] = ')'; 2753e12c5d1SDavid du Colombier *t = 0; 2763e12c5d1SDavid du Colombier return (char *)buf; 2773e12c5d1SDavid du Colombier } 2783e12c5d1SDavid du Colombier char* 2793e12c5d1SDavid du Colombier genmenu2(int n) 2803e12c5d1SDavid du Colombier { 2813e12c5d1SDavid du Colombier Text *t=(Text *)which->user1; 2823e12c5d1SDavid du Colombier char *p; 2833e12c5d1SDavid du Colombier if(n>=NMENU2+(menu2str[Search]!=0)) 2843e12c5d1SDavid du Colombier return 0; 2853e12c5d1SDavid du Colombier p = menu2str[n]; 2863e12c5d1SDavid du Colombier if(!lock && !t->lock || n==Search || n==Look) 2873e12c5d1SDavid du Colombier return p; 2883e12c5d1SDavid du Colombier return paren(p); 2893e12c5d1SDavid du Colombier } 2903e12c5d1SDavid du Colombier char* 2913e12c5d1SDavid du Colombier genmenu2c(int n) 2923e12c5d1SDavid du Colombier { 2933e12c5d1SDavid du Colombier Text *t=(Text *)which->user1; 2943e12c5d1SDavid du Colombier char *p; 2953e12c5d1SDavid du Colombier if(n >= NMENU2C) 2963e12c5d1SDavid du Colombier return 0; 2973e12c5d1SDavid du Colombier if(n == Send) 2983e12c5d1SDavid du Colombier p="send"; 2993e12c5d1SDavid du Colombier else 3003e12c5d1SDavid du Colombier p = menu2str[n]; 3013e12c5d1SDavid du Colombier if(!lock && !t->lock) 3023e12c5d1SDavid du Colombier return p; 3033e12c5d1SDavid du Colombier return paren(p); 3043e12c5d1SDavid du Colombier } 3053e12c5d1SDavid du Colombier char * 3063e12c5d1SDavid du Colombier genmenu3(int n) 3073e12c5d1SDavid du Colombier { 3083e12c5d1SDavid du Colombier Text *t; 3093e12c5d1SDavid du Colombier int c, i, k, l, w; 3103e12c5d1SDavid du Colombier Rune r; 3113e12c5d1SDavid du Colombier char *p; 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier if(n >= NMENU3+nname) 3143e12c5d1SDavid du Colombier return 0; 3153e12c5d1SDavid du Colombier if(n < NMENU3){ 3163e12c5d1SDavid du Colombier p = menu3str[n]; 3173e12c5d1SDavid du Colombier if(lock) 3183e12c5d1SDavid du Colombier p = paren(p); 3193e12c5d1SDavid du Colombier return p; 3203e12c5d1SDavid du Colombier } 3213e12c5d1SDavid du Colombier n -= NMENU3; 3223e12c5d1SDavid du Colombier if(n == 0) /* unless we've been fooled, this is cmd */ 3233e12c5d1SDavid du Colombier return (char *)&name[n][1]; 3243e12c5d1SDavid du Colombier if(mw == -1){ 3253e12c5d1SDavid du Colombier mw = 7; /* strlen("~~sam~~"); */ 3263e12c5d1SDavid du Colombier for(i=1; i<nname; i++){ 3273e12c5d1SDavid du Colombier w = utflen((char*)name[i]+1)+4; /* include "'+. " */ 3283e12c5d1SDavid du Colombier if(w > mw) 3293e12c5d1SDavid du Colombier mw = w; 3303e12c5d1SDavid du Colombier } 3313e12c5d1SDavid du Colombier } 3323e12c5d1SDavid du Colombier if(mw > NBUF) 3333e12c5d1SDavid du Colombier mw = NBUF; 3343e12c5d1SDavid du Colombier t = text[n]; 3353e12c5d1SDavid du Colombier buf[0] = name[n][0]; 3363e12c5d1SDavid du Colombier buf[1] = '-'; 3373e12c5d1SDavid du Colombier buf[2] = ' '; 3383e12c5d1SDavid du Colombier buf[3] = ' '; 3393e12c5d1SDavid du Colombier if(t){ 3403e12c5d1SDavid du Colombier if(t->nwin == 1) 3413e12c5d1SDavid du Colombier buf[1] = '+'; 3423e12c5d1SDavid du Colombier else if(t->nwin > 1) 3433e12c5d1SDavid du Colombier buf[1] = '*'; 3443e12c5d1SDavid du Colombier if(work && t==(Text *)work->user1) { 3453e12c5d1SDavid du Colombier buf[2]= '.'; 3463e12c5d1SDavid du Colombier if(modified) 3473e12c5d1SDavid du Colombier buf[0] = '\''; 3483e12c5d1SDavid du Colombier } 3493e12c5d1SDavid du Colombier } 3503e12c5d1SDavid du Colombier l = utflen((char*)name[n]+1); 3513e12c5d1SDavid du Colombier if(l > NBUF-4-2){ 3523e12c5d1SDavid du Colombier i = 4; 3533e12c5d1SDavid du Colombier k = 1; 3543e12c5d1SDavid du Colombier while(i < NBUF/2){ 3553e12c5d1SDavid du Colombier k += chartorune(&r, (char*)name[n]+k); 3563e12c5d1SDavid du Colombier i++; 3573e12c5d1SDavid du Colombier } 3583e12c5d1SDavid du Colombier c = name[n][k]; 3593e12c5d1SDavid du Colombier name[n][k] = 0; 3603e12c5d1SDavid du Colombier strcpy((char*)buf+4, (char*)name[n]+1); 3613e12c5d1SDavid du Colombier name[n][k] = c; 3623e12c5d1SDavid du Colombier strcat((char*)buf, "..."); 3633e12c5d1SDavid du Colombier while((l-i) >= NBUF/2-4){ 3643e12c5d1SDavid du Colombier k += chartorune(&r, (char*)name[n]+k); 3653e12c5d1SDavid du Colombier i++; 3663e12c5d1SDavid du Colombier } 3673e12c5d1SDavid du Colombier strcat((char*)buf, (char*)name[n]+k); 3683e12c5d1SDavid du Colombier }else 3693e12c5d1SDavid du Colombier strcpy((char*)buf+4, (char*)name[n]+1); 3703e12c5d1SDavid du Colombier i = utflen((char*)buf); 3713e12c5d1SDavid du Colombier k = strlen((char*)buf); 3723e12c5d1SDavid du Colombier while(i<mw && k<sizeof buf-1){ 3733e12c5d1SDavid du Colombier buf[k++] = ' '; 3743e12c5d1SDavid du Colombier i++; 3753e12c5d1SDavid du Colombier } 3763e12c5d1SDavid du Colombier buf[k] = 0; 3773e12c5d1SDavid du Colombier return (char *)buf; 3783e12c5d1SDavid du Colombier } 379