aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/samterm/menu.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-09-30 17:47:44 +0000
committerrsc <devnull@localhost>2003-09-30 17:47:44 +0000
commit84b1cb73b3f0837f5b959579818158fbb2b1b206 (patch)
tree7e27c119d2c2fe00a70a39985c3715b3d8ca363b /src/cmd/samterm/menu.c
parenta59ea66fa99f7b6f03eac71dc0713c33f912b6ab (diff)
downloadplan9port-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.c403
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;
+}