1 #include <u.h> 2 #include <libc.h> 3 #include <libg.h> 4 #include <frame.h> 5 #include "flayer.h" 6 #include "samterm.h" 7 8 uchar *name[MAXFILES]; /* first byte is ' ' or '\'': modified state */ 9 Text *text[MAXFILES]; /* pointer to Text associated with file */ 10 ushort tag[MAXFILES]; /* text[i].tag, even if text[i] not defined */ 11 int nname; 12 int mw; 13 14 char *genmenu3(int); 15 char *genmenu2(int); 16 char *genmenu2c(int); 17 18 enum Menu2 19 { 20 Cut, 21 Paste, 22 Snarf, 23 Look, 24 Exch, 25 Search, 26 NMENU2 = Search, 27 Send = Search, 28 NMENU2C 29 }; 30 31 enum Menu3 32 { 33 New, 34 Zerox, 35 Reshape, 36 Close, 37 Write, 38 NMENU3 39 }; 40 41 char *menu2str[] = { 42 "cut", 43 "paste", 44 "snarf", 45 "look", 46 "<8½>", 47 0, /* storage for last pattern */ 48 }; 49 50 char *menu3str[] = { 51 "new", 52 "zerox", 53 "reshape", 54 "close", 55 "write", 56 }; 57 58 Menu menu2 = {0, genmenu2}; 59 Menu menu2c ={0, genmenu2c}; 60 Menu menu3 = {0, genmenu3}; 61 62 void 63 menu2hit(void) 64 { 65 Text *t=(Text *)which->user1; 66 int w = which-t->l; 67 int m; 68 69 m = menuhit(2, &mouse, t==&cmd? &menu2c : &menu2); 70 if(lock || t->lock) 71 return; 72 73 switch(m){ 74 case Cut: 75 cut(t, w, 1, 1); 76 break; 77 78 case Paste: 79 paste(t, w); 80 break; 81 82 case Snarf: 83 snarf(t, w); 84 break; 85 86 case Exch: 87 outT0(Tstartsnarf); 88 setlock(); 89 break; 90 91 case Look: 92 outTsll(Tlook, t->tag, which->p0, which->p1); 93 setlock(); 94 break; 95 96 case Search: 97 outcmd(); 98 if(t==&cmd) 99 outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1); 100 else 101 outT0(Tsearch); 102 setlock(); 103 break; 104 } 105 } 106 107 void 108 menu3hit(void) 109 { 110 Rectangle r; 111 Flayer *l; 112 int m, i; 113 Text *t; 114 115 mw = -1; 116 switch(m = menuhit(3, &mouse, &menu3)){ 117 case -1: 118 break; 119 120 case New: 121 if(!lock) 122 sweeptext(1, 0); 123 break; 124 125 case Zerox: 126 case Reshape: 127 if(!lock){ 128 cursorswitch(&bullseye); 129 buttons(Down); 130 if((mouse.buttons&4) && (l = flwhich(mouse.xy)) && getr(&r)) 131 duplicate(l, r, l->f.font, m==Reshape); 132 else 133 cursorswitch(cursor); 134 buttons(Up); 135 } 136 break; 137 138 case Close: 139 if(!lock){ 140 cursorswitch(&bullseye); 141 buttons(Down); 142 if((mouse.buttons&4) && (l = flwhich(mouse.xy)) && !lock){ 143 t=(Text *)l->user1; 144 if (t->nwin>1) 145 closeup(l); 146 else if(t!=&cmd) { 147 outTs(Tclose, t->tag); 148 setlock(); 149 } 150 } 151 cursorswitch(cursor); 152 buttons(Up); 153 } 154 break; 155 156 case Write: 157 if(!lock){ 158 cursorswitch(&bullseye); 159 buttons(Down); 160 if((mouse.buttons&4) && (l = flwhich(mouse.xy))){ 161 outTs(Twrite, ((Text *)l->user1)->tag); 162 setlock(); 163 }else 164 cursorswitch(cursor); 165 buttons(Up); 166 } 167 break; 168 169 default: 170 if(t = text[m-NMENU3]){ 171 i = t->front; 172 if(t->nwin==0 || t->l[i].textfn==0) 173 return; /* not ready yet; try again later */ 174 if(t->nwin>1 && which==&t->l[i]) 175 do 176 if(++i==NL) 177 i = 0; 178 while(i!=t->front && t->l[i].textfn==0); 179 current(&t->l[i]); 180 }else if(!lock) 181 sweeptext(0, tag[m-NMENU3]); 182 break; 183 } 184 } 185 186 187 Text * 188 sweeptext(int new, int tag) 189 { 190 Rectangle r; 191 Text *t; 192 193 if(getr(&r) && (t = malloc(sizeof(Text)))){ 194 memset((void*)t, 0, sizeof(Text)); 195 current((Flayer *)0); 196 flnew(&t->l[0], gettext, 0, (char *)t); 197 flinit(&t->l[0], r, font); /*bnl*/ 198 t->nwin = 1; 199 rinit(&t->rasp); 200 if(new) 201 startnewfile(Tstartnewfile, t); 202 else{ 203 rinit(&t->rasp); 204 t->tag = tag; 205 startfile(t); 206 } 207 return t; 208 } 209 return 0; 210 } 211 212 int 213 whichmenu(int tg) 214 { 215 int i; 216 217 for(i=0; i<nname; i++) 218 if(tag[i] == tg) 219 return i; 220 return -1; 221 } 222 223 void 224 menuins(int n, uchar *s, Text *t, int m, int tg) 225 { 226 int i; 227 228 if(nname == MAXFILES) 229 panic("menuins"); 230 for(i=nname; i>n; --i) 231 name[i]=name[i-1], text[i]=text[i-1], tag[i]=tag[i-1]; 232 text[n] = t; 233 tag[n] = tg; 234 name[n] = alloc(strlen((char*)s)+2); 235 name[n][0] = m; 236 strcpy((char*)name[n]+1, (char*)s); 237 nname++; 238 menu3.lasthit = n+NMENU3; 239 } 240 241 void 242 menudel(int n) 243 { 244 int i; 245 246 if(nname==0 || n>=nname || text[n]) 247 panic("menudel"); 248 free(name[n]); 249 --nname; 250 for(i = n; i<nname; i++) 251 name[i]=name[i+1], text[i]=text[i+1], tag[i]=tag[i+1]; 252 } 253 254 void 255 setpat(char *s) 256 { 257 static char pat[17]; 258 259 pat[0] = '/'; 260 strncpy(pat+1, s, 15); 261 menu2str[Search] = pat; 262 } 263 264 #define NBUF 64 265 static uchar buf[NBUF*UTFmax]={' ', ' ', ' ', ' '}; 266 267 char * 268 paren(char *s) 269 { 270 uchar *t = buf; 271 272 *t++ = '('; 273 do; while(*t++ = *s++); 274 t[-1] = ')'; 275 *t = 0; 276 return (char *)buf; 277 } 278 char* 279 genmenu2(int n) 280 { 281 Text *t=(Text *)which->user1; 282 char *p; 283 if(n>=NMENU2+(menu2str[Search]!=0)) 284 return 0; 285 p = menu2str[n]; 286 if(!lock && !t->lock || n==Search || n==Look) 287 return p; 288 return paren(p); 289 } 290 char* 291 genmenu2c(int n) 292 { 293 Text *t=(Text *)which->user1; 294 char *p; 295 if(n >= NMENU2C) 296 return 0; 297 if(n == Send) 298 p="send"; 299 else 300 p = menu2str[n]; 301 if(!lock && !t->lock) 302 return p; 303 return paren(p); 304 } 305 char * 306 genmenu3(int n) 307 { 308 Text *t; 309 int c, i, k, l, w; 310 Rune r; 311 char *p; 312 313 if(n >= NMENU3+nname) 314 return 0; 315 if(n < NMENU3){ 316 p = menu3str[n]; 317 if(lock) 318 p = paren(p); 319 return p; 320 } 321 n -= NMENU3; 322 if(n == 0) /* unless we've been fooled, this is cmd */ 323 return (char *)&name[n][1]; 324 if(mw == -1){ 325 mw = 7; /* strlen("~~sam~~"); */ 326 for(i=1; i<nname; i++){ 327 w = utflen((char*)name[i]+1)+4; /* include "'+. " */ 328 if(w > mw) 329 mw = w; 330 } 331 } 332 if(mw > NBUF) 333 mw = NBUF; 334 t = text[n]; 335 buf[0] = name[n][0]; 336 buf[1] = '-'; 337 buf[2] = ' '; 338 buf[3] = ' '; 339 if(t){ 340 if(t->nwin == 1) 341 buf[1] = '+'; 342 else if(t->nwin > 1) 343 buf[1] = '*'; 344 if(work && t==(Text *)work->user1) { 345 buf[2]= '.'; 346 if(modified) 347 buf[0] = '\''; 348 } 349 } 350 l = utflen((char*)name[n]+1); 351 if(l > NBUF-4-2){ 352 i = 4; 353 k = 1; 354 while(i < NBUF/2){ 355 k += chartorune(&r, (char*)name[n]+k); 356 i++; 357 } 358 c = name[n][k]; 359 name[n][k] = 0; 360 strcpy((char*)buf+4, (char*)name[n]+1); 361 name[n][k] = c; 362 strcat((char*)buf, "..."); 363 while((l-i) >= NBUF/2-4){ 364 k += chartorune(&r, (char*)name[n]+k); 365 i++; 366 } 367 strcat((char*)buf, (char*)name[n]+k); 368 }else 369 strcpy((char*)buf+4, (char*)name[n]+1); 370 i = utflen((char*)buf); 371 k = strlen((char*)buf); 372 while(i<mw && k<sizeof buf-1){ 373 buf[k++] = ' '; 374 i++; 375 } 376 buf[k] = 0; 377 return (char *)buf; 378 } 379