diff options
author | rsc <devnull@localhost> | 2003-09-30 17:47:44 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-09-30 17:47:44 +0000 |
commit | 84b1cb73b3f0837f5b959579818158fbb2b1b206 (patch) | |
tree | 7e27c119d2c2fe00a70a39985c3715b3d8ca363b /src/cmd/samterm/menu.c | |
parent | a59ea66fa99f7b6f03eac71dc0713c33f912b6ab (diff) | |
download | plan9port-84b1cb73b3f0837f5b959579818158fbb2b1b206.tar.gz plan9port-84b1cb73b3f0837f5b959579818158fbb2b1b206.tar.bz2 plan9port-84b1cb73b3f0837f5b959579818158fbb2b1b206.zip |
Initial revision
Diffstat (limited to 'src/cmd/samterm/menu.c')
-rw-r--r-- | src/cmd/samterm/menu.c | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/src/cmd/samterm/menu.c b/src/cmd/samterm/menu.c new file mode 100644 index 00000000..18070a8f --- /dev/null +++ b/src/cmd/samterm/menu.c @@ -0,0 +1,403 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <thread.h> +#include <mouse.h> +#include <cursor.h> +#include <keyboard.h> +#include <frame.h> +#include "flayer.h" +#include "samterm.h" + +uchar **name; /* first byte is ' ' or '\'': modified state */ +Text **text; /* pointer to Text associated with file */ +ushort *tag; /* text[i].tag, even if text[i] not defined */ +int nname; +int mname; +int mw; + +char *genmenu3(int); +char *genmenu2(int); +char *genmenu2c(int); + +enum Menu2 +{ + Cut, + Paste, + Snarf, + Plumb, + Look, + Exch, + Search, + NMENU2 = Search, + Send = Search, + NMENU2C +}; + +enum Menu3 +{ + New, + Zerox, + Resize, + Close, + Write, + NMENU3 +}; + +char *menu2str[] = { + "cut", + "paste", + "snarf", + "plumb", + "look", + "<rio>", + 0, /* storage for last pattern */ +}; + +char *menu3str[] = { + "new", + "zerox", + "resize", + "close", + "write", +}; + +Menu menu2 = {0, genmenu2}; +Menu menu2c ={0, genmenu2c}; +Menu menu3 = {0, genmenu3}; + +void +menu2hit(void) +{ + Text *t=(Text *)which->user1; + int w = which-t->l; + int m; + + if(hversion==0 || plumbfd<0) + menu2str[Plumb] = "(plumb)"; + m = menuhit(2, mousectl, t==&cmd? &menu2c : &menu2, nil); + if(hostlock || t->lock) + return; + + switch(m){ + case Cut: + cut(t, w, 1, 1); + break; + + case Paste: + paste(t, w); + break; + + case Snarf: + snarf(t, w); + break; + + case Plumb: + if(hversion > 0) + outTsll(Tplumb, t->tag, which->p0, which->p1); + break; + + case Exch: + snarf(t, w); + outT0(Tstartsnarf); + setlock(); + break; + + case Look: + outTsll(Tlook, t->tag, which->p0, which->p1); + setlock(); + break; + + case Search: + outcmd(); + if(t==&cmd) + outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1); + else + outT0(Tsearch); + setlock(); + break; + } +} + +void +menu3hit(void) +{ + Rectangle r; + Flayer *l; + int m, i; + Text *t; + + mw = -1; + m = menuhit(3, mousectl, &menu3, nil); + switch(m){ + case -1: + break; + + case New: + if(!hostlock) + sweeptext(1, 0); + break; + + case Zerox: + case Resize: + if(!hostlock){ + setcursor(mousectl, &bullseye); + buttons(Down); + if((mousep->buttons&4) && (l = flwhich(mousep->xy)) && getr(&r)) + duplicate(l, r, l->f.font, m==Resize); + else + setcursor(mousectl, cursor); + buttons(Up); + } + break; + + case Close: + if(!hostlock){ + setcursor(mousectl, &bullseye); + buttons(Down); + if((mousep->buttons&4) && (l = flwhich(mousep->xy)) && !hostlock){ + t=(Text *)l->user1; + if (t->nwin>1) + closeup(l); + else if(t!=&cmd) { + outTs(Tclose, t->tag); + setlock(); + } + } + setcursor(mousectl, cursor); + buttons(Up); + } + break; + + case Write: + if(!hostlock){ + setcursor(mousectl, &bullseye); + buttons(Down); + if((mousep->buttons&4) && (l = flwhich(mousep->xy))){ + outTs(Twrite, ((Text *)l->user1)->tag); + setlock(); + }else + setcursor(mousectl, cursor); + buttons(Up); + } + break; + + default: + if(t = text[m-NMENU3]){ + i = t->front; + if(t->nwin==0 || t->l[i].textfn==0) + return; /* not ready yet; try again later */ + if(t->nwin>1 && which==&t->l[i]) + do + if(++i==NL) + i = 0; + while(i!=t->front && t->l[i].textfn==0); + current(&t->l[i]); + }else if(!hostlock) + sweeptext(0, tag[m-NMENU3]); + break; + } +} + + +Text * +sweeptext(int new, int tag) +{ + Rectangle r; + Text *t; + + if(getr(&r) && (t = malloc(sizeof(Text)))){ + memset((void*)t, 0, sizeof(Text)); + current((Flayer *)0); + flnew(&t->l[0], gettext, 0, (char *)t); + flinit(&t->l[0], r, font, maincols); /*bnl*/ + t->nwin = 1; + rinit(&t->rasp); + if(new) + startnewfile(Tstartnewfile, t); + else{ + rinit(&t->rasp); + t->tag = tag; + startfile(t); + } + return t; + } + return 0; +} + +int +whichmenu(int tg) +{ + int i; + + for(i=0; i<nname; i++) + if(tag[i] == tg) + return i; + return -1; +} + +void +menuins(int n, uchar *s, Text *t, int m, int tg) +{ + int i; + + if(nname == mname){ + if(mname == 0) + mname = 32; + else + mname *= 2; + name = realloc(name, sizeof(name[0])*mname); + text = realloc(text, sizeof(text[0])*mname); + tag = realloc(tag, sizeof(tag[0])*mname); + if(name==nil || text==nil || tag==nil) + panic("realloc"); + } + for(i=nname; i>n; --i) + name[i]=name[i-1], text[i]=text[i-1], tag[i]=tag[i-1]; + text[n] = t; + tag[n] = tg; + name[n] = alloc(strlen((char*)s)+2); + name[n][0] = m; + strcpy((char*)name[n]+1, (char*)s); + nname++; + menu3.lasthit = n+NMENU3; +} + +void +menudel(int n) +{ + int i; + + if(nname==0 || n>=nname || text[n]) + panic("menudel"); + free(name[n]); + --nname; + for(i = n; i<nname; i++) + name[i]=name[i+1], text[i]=text[i+1], tag[i]=tag[i+1]; +} + +void +setpat(char *s) +{ + static char pat[17]; + + pat[0] = '/'; + strncpy(pat+1, s, 15); + menu2str[Search] = pat; +} + +#define NBUF 64 +static uchar buf[NBUF*UTFmax]={' ', ' ', ' ', ' '}; + +char * +paren(char *s) +{ + uchar *t = buf; + + *t++ = '('; + do; while(*t++ = *s++); + t[-1] = ')'; + *t = 0; + return (char *)buf; +} +char* +genmenu2(int n) +{ + Text *t=(Text *)which->user1; + char *p; + if(n>=NMENU2+(menu2str[Search]!=0)) + return 0; + p = menu2str[n]; + if(!hostlock && !t->lock || n==Search || n==Look) + return p; + return paren(p); +} +char* +genmenu2c(int n) +{ + Text *t=(Text *)which->user1; + char *p; + if(n >= NMENU2C) + return 0; + if(n == Send) + p="send"; + else + p = menu2str[n]; + if(!hostlock && !t->lock) + return p; + return paren(p); +} +char * +genmenu3(int n) +{ + Text *t; + int c, i, k, l, w; + Rune r; + char *p; + + if(n >= NMENU3+nname) + return 0; + if(n < NMENU3){ + p = menu3str[n]; + if(hostlock) + p = paren(p); + return p; + } + n -= NMENU3; + if(n == 0) /* unless we've been fooled, this is cmd */ + return (char *)&name[n][1]; + if(mw == -1){ + mw = 7; /* strlen("~~sam~~"); */ + for(i=1; i<nname; i++){ + w = utflen((char*)name[i]+1)+4; /* include "'+. " */ + if(w > mw) + mw = w; + } + } + if(mw > NBUF) + mw = NBUF; + t = text[n]; + buf[0] = name[n][0]; + buf[1] = '-'; + buf[2] = ' '; + buf[3] = ' '; + if(t){ + if(t->nwin == 1) + buf[1] = '+'; + else if(t->nwin > 1) + buf[1] = '*'; + if(work && t==(Text *)work->user1) { + buf[2]= '.'; + if(modified) + buf[0] = '\''; + } + } + l = utflen((char*)name[n]+1); + if(l > NBUF-4-2){ + i = 4; + k = 1; + while(i < NBUF/2){ + k += chartorune(&r, (char*)name[n]+k); + i++; + } + c = name[n][k]; + name[n][k] = 0; + strcpy((char*)buf+4, (char*)name[n]+1); + name[n][k] = c; + strcat((char*)buf, "..."); + while((l-i) >= NBUF/2-4){ + k += chartorune(&r, (char*)name[n]+k); + i++; + } + strcat((char*)buf, (char*)name[n]+k); + }else + strcpy((char*)buf+4, (char*)name[n]+1); + i = utflen((char*)buf); + k = strlen((char*)buf); + while(i<mw && k<sizeof buf-1){ + buf[k++] = ' '; + i++; + } + buf[k] = 0; + return (char *)buf; +} |