|
|
1.1 root 1: #include "samterm.h"
2:
3: uchar *name[MAXFILES]; /* first byte is ' ' or '\'': modified state */
4: Text *text[MAXFILES]; /* pointer to Text associated with file */
5: ushort tag[MAXFILES]; /* text[i].tag, even if text[i] not defined */
6: int nname;
7: char *genmenu3();
8: char *genmenu2();
9: char *genmenu2c();
10: Text *sweeptext();
11: enum Menu2{
12: Cut,
13: Paste,
14: Snarf,
15: Look,
16: Exch,
17: Search,
18: NMENU2=Search,
19: Send=Search,
20: Scroll,
21: NMENU2C
22: };
23: enum Menu3{
24: New,
25: Xerox,
26: Reshape,
27: Close,
28: Write,
29: NMENU3
30: };
31: char *menu2str[]={
32: "cut",
33: "paste",
34: "snarf",
35: "look",
36: "<mux>",
37: 0, /* storage for last pattern */
38: };
39: char *menu3str[]={
40: "new",
41: "xerox",
42: "reshape",
43: "close",
44: "write",
45: };
46: Menu menu2={0, genmenu2};
47: Menu menu2c={0, genmenu2c};
48: Menu menu3={0, genmenu3};
49: menu2hit()
50: {
51: register Text *t=(Text *)which->user1;
52: register w=which-t->l;
53: switch(menuhit(t==&cmd? &menu2c : &menu2, 2)){
54: case Cut:
55: if(!lock && !t->lock)
56: cut(t, w, 1);
57: break;
58: case Paste:
59: if(!lock && !t->lock)
60: paste(t, w);
61: break;
62: case Snarf:
63: if(!lock && !t->lock)
64: snarf(t, w);
65: break;
66: case Exch:
67: outT0(Tstartsnarf);
68: setlock();
69: break;
70: case Look:
71: outTsll(Tlook, t->tag, which->p0, which->p1);
72: break;
73: case Search:
74: outcmd();
75: if(t==&cmd)
76: outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1);
77: else
78: outT0(Tsearch);
79: break;
80: case Scroll:
81: if(cmd.l[w].user0^=1)
82: center(&cmd.l[w], t->rasp.nbytes);
83: break;
84: }
85: }
86: menu3hit()
87: {
88: Rectangle r;
89: register Flayer *l;
90: register m, i;
91: register Text *t;
92: switch(m=menuhit(&menu3, 3)){
93: case -1:
94: break;
95: case New:
96: sweeptext(1, 0);
97: break;
98: case Xerox:
99: case Reshape:
100: cursswitch(&bullseye);
101: buttons(Down);
102: if(button3() && (l=flwhich(mouse.xy)) && getr(&r))
103: duplicate(l, r, l->f.font, m==Reshape);
104: else
105: cursswitch(cursor);
106: buttons(Up);
107: break;
108: case Close:
109: cursswitch(&bullseye);
110: buttons(Down);
111: if(button3() && (l=flwhich(mouse.xy)) && !lock){
112: t=(Text *)l->user1;
113: if(t!=&cmd || t->nwin>1){
114: if(t->nwin>1)
115: close(l);
116: else
117: outTs(Tclose, t->tag);
118: }
119: }
120: cursswitch(cursor);
121: buttons(Up);
122: break;
123: case Write:
124: cursswitch(&bullseye);
125: buttons(Down);
126: if(button3() && (l=flwhich(mouse.xy)))
127: outTs(Twrite, ((Text *)l->user1)->tag);
128: cursswitch(cursor);
129: buttons(Up);
130: break;
131: default:
132: if(t=text[m-NMENU3]){
133: i=t->front;
134: if(t->nwin==0 || t->l[i].textfn==0)
135: return; /* not ready yet; try again later */
136: if(t->nwin>1 && which==&t->l[i])
137: do
138: if(++i==NL)
139: i=0;
140: while(i!=t->front && t->l[i].textfn==0);
141: current(&t->l[i]);
142: }else
143: sweeptext(0, tag[m-NMENU3]);
144: break;
145: }
146: }
147: Text *
148: sweeptext(new, tag)
149: {
150: Rectangle r;
151: register Text *t;
152: if(!own(MOUSE))
153: wait(MOUSE);
154: if(getr(&r) && (t=(Text *)alloc(sizeof(Text)))){
155: current((Flayer *)0);
156: flnew(&t->l[0], gettext, 0, (char *)t);
157: flinit(&t->l[0], r, &defont);
158: t->nwin=1;
159: rinit(&t->rasp);
160: if(new)
161: startnewfile(Tstartnewfile, t);
162: else{
163: rinit(&t->rasp);
164: t->tag=tag;
165: startfile(t);
166: }
167: return t;
168: }
169: return 0;
170: }
171: whichmenu(tg)
172: register tg;
173: {
174: register i;
175: for(i=0; i<nname; i++)
176: if(tag[i]==tg)
177: return i;
178: return -1;
179: }
180: menuins(n, s, t, m, tg)
181: uchar *s;
182: Text *t;
183: {
184: register i;
185: if(nname==MAXFILES)
186: panic("menuins");
187: for(i=nname; i>n; --i)
188: name[i]=name[i-1], text[i]=text[i-1], tag[i]=tag[i-1];
189: text[n]=t;
190: tag[n]=tg;
191: name[n]=ALLOC(strlen(s)+2);
192: name[n][0]=m;
193: copystr(s, name[n]+1);
194: nname++;
195: /* ehg's hack, implemented by rob: make this guy pop up under menu */
196: /* non-jerq implementers: delete the rest of this procedure */
197: #define MENULINES 16
198: if((n+=NMENU3)<16)
199: menu3.prevtop=0;
200: else if(n>nname+NMENU3-MENULINES){
201: menu3.prevtop=nname+NMENU3-MENULINES;
202: }else
203: menu3.prevtop=n-MENULINES/2;
204: menu3.prevhit=n-menu3.prevtop;
205: }
206: menudel(n){
207: register i;
208: if(nname==0 || n>=nname || text[n])
209: panic("menudel");
210: free(name[n]);
211: --nname;
212: for(i=n; i<nname; i++)
213: name[i]=name[i+1], text[i]=text[i+1], tag[i]=tag[i+1];
214: }
215: setpat(s)
216: register char *s;
217: {
218: static char pat[17];
219: pat[0]='/';
220: strcpy(pat+1, s); /* host guarantees it fits */
221: menu2str[Search]=pat;
222: }
223: static uchar buf[64]={' ', ' ', ' ', ' '};
224: char *
225: paren(s)
226: register char *s;
227: {
228: register uchar *t=buf;
229: *t++='(';
230: do; while(*t++=*s++);
231: t[-1]=')';
232: *t=0;
233: return (char *)buf;
234: }
235: char *
236: genmenu2(n)
237: register n;
238: {
239: register Text *t=(Text *)which->user1;
240: register char *p;
241: if(n>=NMENU2+(menu2str[Search]!=0))
242: return 0;
243: p=menu2str[n];
244: if(!lock && !t->lock || n==Search || n==Look)
245: return p;
246: return paren(p);
247: }
248: char *
249: genmenu2c(n)
250: register n;
251: {
252: register Text *t=(Text *)which->user1;
253: register char *p;
254: if(n>=NMENU2C)
255: return 0;
256: if(n==Scroll)
257: p=which->user0? "noscroll" : "scroll";
258: else if(n==Send)
259: p="send";
260: else
261: p=menu2str[n];
262: if(!lock && !t->lock)
263: return p;
264: return paren(p);
265: }
266: char *
267: genmenu3(n)
268: register n;
269: {
270: register Text *t;
271: register i;
272: if(n>=(int)NMENU3+nname)
273: return 0;
274: if(n<(int)NMENU3)
275: return menu3str[n];
276: n-=(int)NMENU3;
277: if(n==0) /* unless we've been fooled, this is cmd */
278: return (char *)&name[n][1];
279: t=text[n];
280: buf[0]=name[n][0];
281: buf[1]='-';
282: buf[2]=' ';
283: buf[3]=' ';
284: if(t){
285: if(t->nwin==1)
286: buf[1]='+';
287: else if(t->nwin>1)
288: buf[1]='*';
289: if(work && t==(Text *)work->user1)
290: buf[2]='.';
291: }
292: if((i=strlen(name[n]+1))>sizeof buf-4-2){
293: int c, k;
294: k=sizeof buf/2;
295: c=name[n][k];
296: name[n][k]=0;
297: copystr(name[n]+1, buf+4);
298: name[n][k]=c;
299: copystr((uchar *)"...", buf+4+k-1);
300: copystr(name[n]+1+i-(sizeof buf-4-k-4), buf+4+k+2);
301: }else
302: copystr(name[n]+1, buf+4);
303: i=strlen(buf);
304: buf[i++]='\240';
305: buf[i]=0;
306: return (char *)buf;
307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.