menu.c (52124B)
1 /* $Id$ */ 2 /* 3 * w3m menu.c 4 */ 5 #include <stdio.h> 6 7 #include "fm.h" 8 #include "menu.h" 9 #include "func.h" 10 #include "myctype.h" 11 #include "regex.h" 12 13 #ifdef USE_MOUSE 14 #ifdef USE_GPM 15 #include <gpm.h> 16 static int gpm_process_menu_mouse(Gpm_Event * event, void *data); 17 extern int gpm_process_mouse(Gpm_Event *, void *); 18 #endif /* USE_GPM */ 19 #ifdef USE_SYSMOUSE 20 extern int (*sysm_handler) (int x, int y, int nbs, int obs); 21 static int sysm_process_menu_mouse(int, int, int, int); 22 extern int sysm_process_mouse(int, int, int, int); 23 #endif /* USE_SYSMOUSE */ 24 #if defined(USE_GPM) || defined(USE_SYSMOUSE) 25 #define X_MOUSE_SELECTED (char)0xff 26 static int X_Mouse_Selection; 27 extern int do_getch(); 28 #define getch() do_getch() 29 #endif /* defined(USE_GPM) || defined(USE_SYSMOUSE) */ 30 #endif /* USE_MOUSE */ 31 32 #ifdef USE_MENU 33 34 static char **FRAME; 35 static int FRAME_WIDTH; 36 static int graph_mode = FALSE; 37 #define G_start {if (graph_mode) graphstart();} 38 #define G_end {if (graph_mode) graphend();} 39 40 static int mEsc(char c); 41 static int mEscB(char c); 42 static int mEscD(char c); 43 static int mNull(char c); 44 static int mSelect(char c); 45 static int mDown(char c); 46 static int mUp(char c); 47 static int mLast(char c); 48 static int mTop(char c); 49 static int mNext(char c); 50 static int mPrev(char c); 51 static int mFore(char c); 52 static int mBack(char c); 53 static int mLineU(char c); 54 static int mLineD(char c); 55 static int mOk(char c); 56 static int mCancel(char c); 57 static int mClose(char c); 58 static int mSusp(char c); 59 static int mMouse(char c); 60 static int mSrchF(char c); 61 static int mSrchB(char c); 62 static int mSrchN(char c); 63 static int mSrchP(char c); 64 #ifdef __EMX__ 65 static int mPc(char c); 66 #endif 67 68 /* *INDENT-OFF* */ 69 static int (*MenuKeymap[128]) (char c) = { 70 /* C-@ C-a C-b C-c C-d C-e C-f C-g */ 71 #ifdef __EMX__ 72 mPc, mTop, mPrev, mClose, mNull, mLast, mNext, mNull, 73 #else 74 mNull, mTop, mPrev, mClose, mNull, mLast, mNext, mNull, 75 #endif 76 /* C-h C-i C-j C-k C-l C-m C-n C-o */ 77 mCancel,mNull, mOk, mNull, mNull, mOk, mDown, mNull, 78 /* C-p C-q C-r C-s C-t C-u C-v C-w */ 79 mUp, mNull, mSrchB, mSrchF, mNull, mNull, mNext, mNull, 80 /* C-x C-y C-z C-[ C-\ C-] C-^ C-_ */ 81 mNull, mNull, mSusp, mEsc, mNull, mNull, mNull, mNull, 82 /* SPC ! " # $ % & ' */ 83 mOk, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 84 /* ( ) * + , - . / */ 85 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mSrchF, 86 /* 0 1 2 3 4 5 6 7 */ 87 mNull, mNull, mNull, mNull, mNull, mNull , mNull, mNull, 88 /* 8 9 : ; < = > ? */ 89 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mSrchB, 90 /* @ A B C D E F G */ 91 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 92 /* H I J K L M N O */ 93 mNull, mNull, mLineU, mLineD, mNull, mNull, mSrchP, mNull, 94 /* P Q R S T U V W */ 95 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 96 /* X Y Z [ \ ] ^ _ */ 97 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 98 /* ` a b c d e f g */ 99 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 100 /* h i j k l m n o */ 101 mCancel,mNull, mDown, mUp, mOk, mNull, mSrchN, mNull, 102 /* p q r s t u v w */ 103 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 104 /* x y z { | } ~ DEL */ 105 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mCancel, 106 }; 107 static int (*MenuEscKeymap[128]) (char c) = { 108 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 109 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 110 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 111 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 112 113 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 114 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 115 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 116 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 117 118 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 119 /* O */ 120 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mEscB, 121 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 122 /* [ */ 123 mNull, mNull, mNull, mEscB, mNull, mNull, mNull, mNull, 124 125 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 126 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 127 /* v */ 128 mNull, mNull, mNull, mNull, mNull, mNull, mPrev, mNull, 129 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 130 }; 131 static int (*MenuEscBKeymap[128]) (char c) = { 132 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 133 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 134 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 135 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 136 137 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 138 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 139 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 140 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 141 /* A B C D E */ 142 mNull, mUp, mDown, mOk, mCancel,mClose, mNull, mNull, 143 /* L M */ 144 mNull, mNull, mNull, mNull, mClose, mMouse, mNull, mNull, 145 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 146 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 147 148 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 149 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 150 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 151 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 152 }; 153 static int (*MenuEscDKeymap[128]) (char c) = { 154 /* 0 1 INS 3 4 PgUp, PgDn 7 */ 155 mNull, mNull, mClose, mNull, mNull, mBack, mFore, mNull, 156 /* 8 9 10 F1 F2 F3 F4 F5 */ 157 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 158 /* 16 F6 F7 F8 F9 F10 22 23 */ 159 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 160 /* 24 25 26 27 HELP 29 30 31 */ 161 mNull, mNull, mNull, mNull, mClose, mNull, mNull, mNull, 162 163 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 164 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 165 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 166 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 167 168 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 169 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 170 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 171 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 172 173 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 174 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 175 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 176 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 177 }; 178 179 #ifdef __EMX__ 180 static int (*MenuPcKeymap[256])(char c)={ 181 // Null 182 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 183 // S-Tab 184 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 185 // A-q A-w A-E A-r A-t A-y A-u A-i 186 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 187 // A-o A-p A-[ A-] A-a A-s 188 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 189 // A-d A-f A-g A-h A-j A-k A-l A-; 190 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 191 // A-' A-' A-\ A-x A-c A-v 192 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mPrev, 193 // A-b A-n A-m A-, A-. A-/ A-+ 194 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 195 // F1 F2 F3 F4 F5 196 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 197 // F6 F7 F8 F9 F10 Home 198 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mTop, 199 // Up PgUp A-/ Left 5 Right C-* End 200 mUp, mUp, mNull, mCancel,mNull, mOk, mNull, mLast, 201 // Down PgDn Ins Del S-F1 S-F2 S-F3 S-F4 202 mDown, mDown, mClose, mCancel,mNull, mNull, mNull, mNull, 203 // S-F5 S-F6 S-F7 S-F8 S-F9 S-F10 C-F1 C-F2 204 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 205 // C-F3 C-F4 C-F5 C-F6 C-F7 C-F8 C-F9 C-F10 206 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 207 // A-F1 A-F2 A-F3 A-F4 A-F5 A-F6 A-F7 A-F8 208 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 209 // A-F9 A-F10 PrtSc C-Left C-Right C-End C-PgDn C-Home 210 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 211 // A-1 A-2 A-3 A-4 A-5 A-6 A-7/8 A-9 212 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 213 // A-0 A - A-= C-PgUp F11 F12 S-F11 214 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 215 // S-F12 C-F11 C-F12 A-F11 A-F12 C-Up C-/ C-5 216 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 217 // S-* C-Down C-Ins C-Del C-Tab C - C-+ 218 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 219 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, 220 // A - A-Tab A-Enter 221 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 160 222 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 168 223 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 176 224 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 184 225 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 192 226 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 200 227 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 208 228 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 216 229 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 224 230 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 232 231 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull, // 240 232 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull // 248 233 }; 234 #endif 235 /* *INDENT-ON* */ 236 /* --- SelectMenu --- */ 237 238 static Menu SelectMenu; 239 static int SelectV = 0; 240 static void initSelectMenu(void); 241 static void smChBuf(void); 242 static int smDelBuf(char c); 243 244 /* --- SelectMenu (END) --- */ 245 246 /* --- SelTabMenu --- */ 247 248 static Menu SelTabMenu; 249 static int SelTabV = 0; 250 static void initSelTabMenu(void); 251 static void smChTab(void); 252 static int smDelTab(char c); 253 254 /* --- SelTabMenu (END) --- */ 255 256 /* --- MainMenu --- */ 257 258 static Menu MainMenu; 259 #ifdef USE_M17N 260 /* FIXME: gettextize here */ 261 static wc_ces MainMenuCharset = WC_CES_US_ASCII; /* FIXME: charset of source code */ 262 static int MainMenuEncode = FALSE; 263 #endif 264 265 static MenuItem MainMenuItem[] = { 266 /* type label variable value func popup keys data */ 267 {MENU_FUNC, N_(" Back (b) "), NULL, 0, backBf, NULL, "b", NULL}, 268 {MENU_POPUP, N_(" Select Buffer(s) "), NULL, 0, NULL, &SelectMenu, "s", 269 NULL}, 270 {MENU_POPUP, N_(" Select Tab (t) "), NULL, 0, NULL, &SelTabMenu, "tT", 271 NULL}, 272 {MENU_FUNC, N_(" View Source (v) "), NULL, 0, vwSrc, NULL, "vV", NULL}, 273 {MENU_FUNC, N_(" Edit Source (e) "), NULL, 0, editBf, NULL, "eE", NULL}, 274 {MENU_FUNC, N_(" Save Source (S) "), NULL, 0, svSrc, NULL, "S", NULL}, 275 {MENU_FUNC, N_(" Reload (r) "), NULL, 0, reload, NULL, "rR", NULL}, 276 {MENU_NOP, N_(" ---------------- "), NULL, 0, nulcmd, NULL, "", NULL}, 277 {MENU_FUNC, N_(" Go Link (a) "), NULL, 0, followA, NULL, "a", NULL}, 278 {MENU_FUNC, N_(" on New Tab (n) "), NULL, 0, tabA, NULL, "nN", NULL}, 279 {MENU_FUNC, N_(" Save Link (A) "), NULL, 0, svA, NULL, "A", NULL}, 280 {MENU_FUNC, N_(" View Image (i) "), NULL, 0, followI, NULL, "i", NULL}, 281 {MENU_FUNC, N_(" Save Image (I) "), NULL, 0, svI, NULL, "I", NULL}, 282 {MENU_FUNC, N_(" View Frame (f) "), NULL, 0, rFrame, NULL, "fF", NULL}, 283 {MENU_NOP, N_(" ---------------- "), NULL, 0, nulcmd, NULL, "", NULL}, 284 {MENU_FUNC, N_(" Bookmark (B) "), NULL, 0, ldBmark, NULL, "B", NULL}, 285 {MENU_FUNC, N_(" Help (h) "), NULL, 0, ldhelp, NULL, "hH", NULL}, 286 {MENU_FUNC, N_(" Option (o) "), NULL, 0, ldOpt, NULL, "oO", NULL}, 287 {MENU_NOP, N_(" ---------------- "), NULL, 0, nulcmd, NULL, "", NULL}, 288 {MENU_FUNC, N_(" Quit (q) "), NULL, 0, qquitfm, NULL, "qQ", NULL}, 289 {MENU_END, "", NULL, 0, nulcmd, NULL, "", NULL}, 290 }; 291 292 /* --- MainMenu (END) --- */ 293 294 static MenuList *w3mMenuList; 295 296 static Menu *CurrentMenu = NULL; 297 298 #define mvaddch(y, x, c) (move(y, x), addch(c)) 299 #define mvaddstr(y, x, str) (move(y, x), addstr(str)) 300 #define mvaddnstr(y, x, str, n) (move(y, x), addnstr_sup(str, n)) 301 302 void 303 new_menu(Menu *menu, MenuItem *item) 304 { 305 int i, l; 306 char *p; 307 308 menu->cursorX = 0; 309 menu->cursorY = 0; 310 menu->x = 0; 311 menu->y = 0; 312 menu->nitem = 0; 313 menu->item = item; 314 menu->initial = 0; 315 menu->select = 0; 316 menu->offset = 0; 317 menu->active = 0; 318 319 if (item == NULL) 320 return; 321 322 for (i = 0; item[i].type != MENU_END; i++) ; 323 menu->nitem = i; 324 menu->height = menu->nitem; 325 for (i = 0; i < 128; i++) 326 menu->keymap[i] = MenuKeymap[i]; 327 menu->width = 0; 328 for (i = 0; i < menu->nitem; i++) { 329 if ((p = item[i].keys) != NULL) { 330 while (*p) { 331 if (IS_ASCII(*p)) { 332 menu->keymap[(int)*p] = mSelect; 333 menu->keyselect[(int)*p] = i; 334 } 335 p++; 336 } 337 } 338 l = get_strwidth(item[i].label); 339 if (l > menu->width) 340 menu->width = l; 341 } 342 } 343 344 void 345 geom_menu(Menu *menu, int x, int y, int mselect) 346 { 347 int win_x, win_y, win_w, win_h; 348 349 menu->select = mselect; 350 351 if (menu->width % FRAME_WIDTH) 352 menu->width = (menu->width / FRAME_WIDTH + 1) * FRAME_WIDTH; 353 win_x = menu->x - FRAME_WIDTH; 354 win_w = menu->width + 2 * FRAME_WIDTH; 355 if (win_x + win_w > COLS) 356 win_x = COLS - win_w; 357 if (win_x < 0) { 358 win_x = 0; 359 if (win_w > COLS) { 360 menu->width = COLS - 2 * FRAME_WIDTH; 361 menu->width -= menu->width % FRAME_WIDTH; 362 win_w = menu->width + 2 * FRAME_WIDTH; 363 } 364 } 365 menu->x = win_x + FRAME_WIDTH; 366 367 win_y = menu->y - mselect - 1; 368 win_h = menu->height + 2; 369 if (win_y + win_h > LASTLINE) 370 win_y = LASTLINE - win_h; 371 if (win_y < 0) { 372 win_y = 0; 373 if (win_y + win_h > LASTLINE) { 374 win_h = LASTLINE - win_y; 375 menu->height = win_h - 2; 376 if (menu->height <= mselect) 377 menu->offset = mselect - menu->height + 1; 378 } 379 } 380 menu->y = win_y + 1; 381 } 382 383 void 384 draw_all_menu(Menu *menu) 385 { 386 if (menu->parent != NULL) 387 draw_all_menu(menu->parent); 388 draw_menu(menu); 389 } 390 391 void 392 draw_menu(Menu *menu) 393 { 394 int x, y, w; 395 int i, j; 396 397 x = menu->x - FRAME_WIDTH; 398 w = menu->width + 2 * FRAME_WIDTH; 399 y = menu->y - 1; 400 401 if (menu->offset == 0) { 402 G_start; 403 mvaddstr(y, x, FRAME[3]); 404 for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i += FRAME_WIDTH) 405 mvaddstr(y, x + i, FRAME[10]); 406 mvaddstr(y, x + i, FRAME[6]); 407 G_end; 408 } 409 else { 410 G_start; 411 mvaddstr(y, x, FRAME[5]); 412 G_end; 413 for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i++) 414 mvaddstr(y, x + i, " "); 415 G_start; 416 mvaddstr(y, x + i, FRAME[5]); 417 G_end; 418 i = (w / 2 - 1) / FRAME_WIDTH * FRAME_WIDTH; 419 mvaddstr(y, x + i, ":"); 420 } 421 422 for (j = 0; j < menu->height; j++) { 423 y++; 424 G_start; 425 mvaddstr(y, x, FRAME[5]); 426 G_end; 427 draw_menu_item(menu, menu->offset + j); 428 G_start; 429 mvaddstr(y, x + w - FRAME_WIDTH, FRAME[5]); 430 G_end; 431 } 432 y++; 433 if (menu->offset + menu->height == menu->nitem) { 434 G_start; 435 mvaddstr(y, x, FRAME[9]); 436 for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i += FRAME_WIDTH) 437 mvaddstr(y, x + i, FRAME[10]); 438 mvaddstr(y, x + i, FRAME[12]); 439 G_end; 440 } 441 else { 442 G_start; 443 mvaddstr(y, x, FRAME[5]); 444 G_end; 445 for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i++) 446 mvaddstr(y, x + i, " "); 447 G_start; 448 mvaddstr(y, x + i, FRAME[5]); 449 G_end; 450 i = (w / 2 - 1) / FRAME_WIDTH * FRAME_WIDTH; 451 mvaddstr(y, x + i, ":"); 452 } 453 } 454 455 void 456 draw_menu_item(Menu *menu, int mselect) 457 { 458 mvaddnstr(menu->y + mselect - menu->offset, menu->x, 459 menu->item[mselect].label, menu->width); 460 } 461 462 int 463 select_menu(Menu *menu, int mselect) 464 { 465 if (mselect < 0 || mselect >= menu->nitem) 466 return (MENU_NOTHING); 467 if (mselect < menu->offset) 468 up_menu(menu, menu->offset - mselect); 469 else if (mselect >= menu->offset + menu->height) 470 down_menu(menu, mselect - menu->offset - menu->height + 1); 471 472 if (menu->select >= menu->offset && 473 menu->select < menu->offset + menu->height) 474 draw_menu_item(menu, menu->select); 475 menu->select = mselect; 476 standout(); 477 draw_menu_item(menu, menu->select); 478 standend(); 479 /* 480 * move(menu->cursorY, menu->cursorX); */ 481 move(menu->y + mselect - menu->offset, menu->x); 482 toggle_stand(); 483 refresh(); 484 485 return (menu->select); 486 } 487 488 void 489 goto_menu(Menu *menu, int mselect, int down) 490 { 491 int select_in; 492 if (mselect >= menu->nitem) 493 mselect = menu->nitem - 1; 494 else if (mselect < 0) 495 mselect = 0; 496 select_in = mselect; 497 while (menu->item[mselect].type == MENU_NOP) { 498 if (down > 0) { 499 if (++mselect >= menu->nitem) { 500 down_menu(menu, select_in - menu->select); 501 mselect = menu->select; 502 break; 503 } 504 } 505 else if (down < 0) { 506 if (--mselect < 0) { 507 up_menu(menu, menu->select - select_in); 508 mselect = menu->select; 509 break; 510 } 511 } 512 else { 513 return; 514 } 515 } 516 select_menu(menu, mselect); 517 } 518 519 void 520 up_menu(Menu *menu, int n) 521 { 522 if (n < 0 || menu->offset == 0) 523 return; 524 menu->offset -= n; 525 if (menu->offset < 0) 526 menu->offset = 0; 527 528 draw_menu(menu); 529 } 530 531 void 532 down_menu(Menu *menu, int n) 533 { 534 if (n < 0 || menu->offset + menu->height == menu->nitem) 535 return; 536 menu->offset += n; 537 if (menu->offset + menu->height > menu->nitem) 538 menu->offset = menu->nitem - menu->height; 539 540 draw_menu(menu); 541 } 542 543 int 544 action_menu(Menu *menu) 545 { 546 char c; 547 int mselect; 548 MenuItem item; 549 550 if (menu->active == 0) { 551 if (menu->parent != NULL) 552 menu->parent->active = 0; 553 return (0); 554 } 555 draw_all_menu(menu); 556 select_menu(menu, menu->select); 557 558 while (1) { 559 #ifdef USE_MOUSE 560 if (use_mouse) 561 mouse_active(); 562 #endif /* USE_MOUSE */ 563 c = getch(); 564 #ifdef USE_MOUSE 565 if (use_mouse) 566 mouse_inactive(); 567 #if defined(USE_GPM) || defined(USE_SYSMOUSE) 568 if (c == X_MOUSE_SELECTED) { 569 mselect = X_Mouse_Selection; 570 if (mselect != MENU_NOTHING) 571 break; 572 } 573 #endif /* defined(USE_GPM) || defined(USE_SYSMOUSE) */ 574 #endif /* USE_MOUSE */ 575 if (IS_ASCII(c)) { /* Ascii */ 576 mselect = (*menu->keymap[(int)c]) (c); 577 if (mselect != MENU_NOTHING) 578 break; 579 } 580 } 581 if (mselect >= 0 && mselect < menu->nitem) { 582 item = menu->item[mselect]; 583 if (item.type & MENU_POPUP) { 584 popup_menu(menu, item.popup); 585 return (1); 586 } 587 if (menu->parent != NULL) 588 menu->parent->active = 0; 589 if (item.type & MENU_VALUE) 590 *item.variable = item.value; 591 if (item.type & MENU_FUNC) { 592 CurrentKey = -1; 593 CurrentKeyData = NULL; 594 CurrentCmdData = item.data; 595 (*item.func) (); 596 CurrentCmdData = NULL; 597 } 598 } 599 else if (mselect == MENU_CLOSE) { 600 if (menu->parent != NULL) 601 menu->parent->active = 0; 602 } 603 return (0); 604 } 605 606 void 607 popup_menu(Menu *parent, Menu *menu) 608 { 609 int active = 1; 610 611 if (menu->item == NULL || menu->nitem == 0) 612 return; 613 if (menu->active) 614 return; 615 616 #ifdef USE_MOUSE 617 #ifdef USE_GPM 618 gpm_handler = gpm_process_menu_mouse; 619 #endif /* USE_GPM */ 620 #ifdef USE_SYSMOUSE 621 sysm_handler = sysm_process_menu_mouse; 622 #endif /* USE_SYSMOUSE */ 623 #endif /* USE_MOUSE */ 624 menu->parent = parent; 625 menu->select = menu->initial; 626 menu->offset = 0; 627 menu->active = 1; 628 if (parent != NULL) { 629 menu->cursorX = parent->cursorX; 630 menu->cursorY = parent->cursorY; 631 guess_menu_xy(parent, menu->width, &menu->x, &menu->y); 632 } 633 geom_menu(menu, menu->x, menu->y, menu->select); 634 635 CurrentMenu = menu; 636 while (active) { 637 active = action_menu(CurrentMenu); 638 displayBuffer(Currentbuf, B_FORCE_REDRAW); 639 } 640 menu->active = 0; 641 CurrentMenu = parent; 642 #ifdef USE_MOUSE 643 #ifdef USE_GPM 644 if (CurrentMenu == NULL) 645 gpm_handler = gpm_process_mouse; 646 #endif /* USE_GPM */ 647 #ifdef USE_SYSMOUSE 648 if (CurrentMenu == NULL) 649 sysm_handler = sysm_process_mouse; 650 #endif /* USE_SYSMOUSE */ 651 #endif /* USE_MOUSE */ 652 } 653 654 void 655 guess_menu_xy(Menu *parent, int width, int *x, int *y) 656 { 657 *x = parent->x + parent->width + FRAME_WIDTH - 1; 658 if (*x + width + FRAME_WIDTH > COLS) { 659 *x = COLS - width - FRAME_WIDTH; 660 if ((parent->x + parent->width / 2 > *x) && 661 (parent->x + parent->width / 2 > COLS / 2)) 662 *x = parent->x - width - FRAME_WIDTH + 1; 663 } 664 *y = parent->y + parent->select - parent->offset; 665 } 666 667 void 668 new_option_menu(Menu *menu, char **label, int *variable, void (*func) ()) 669 { 670 int i, nitem; 671 char **p; 672 MenuItem *item; 673 674 if (label == NULL || *label == NULL) 675 return; 676 677 for (i = 0, p = label; *p != NULL; i++, p++) ; 678 nitem = i; 679 680 item = New_N(MenuItem, nitem + 1); 681 682 for (i = 0, p = label; i < nitem; i++, p++) { 683 if (func != NULL) 684 item[i].type = MENU_VALUE | MENU_FUNC; 685 else 686 item[i].type = MENU_VALUE; 687 item[i].label = *p; 688 item[i].variable = variable; 689 item[i].value = i; 690 item[i].func = func; 691 item[i].popup = NULL; 692 item[i].keys = ""; 693 } 694 item[nitem].type = MENU_END; 695 696 new_menu(menu, item); 697 } 698 699 static void 700 set_menu_frame(void) 701 { 702 if (graph_ok()) { 703 graph_mode = TRUE; 704 FRAME_WIDTH = 1; 705 FRAME = graph_symbol; 706 } 707 else { 708 graph_mode = FALSE; 709 #ifdef USE_M17N 710 FRAME_WIDTH = 0; 711 FRAME = get_symbol(DisplayCharset, &FRAME_WIDTH); 712 if (!WcOption.use_wide) 713 FRAME_WIDTH = 1; 714 #else 715 FRAME_WIDTH = 1; 716 FRAME = get_symbol(); 717 #endif 718 } 719 } 720 721 /* --- MenuFunctions --- */ 722 723 #ifdef __EMX__ 724 static int 725 mPc(char c) 726 { 727 c = getch(); 728 return (MenuPcKeymap[(int)c] (c)); 729 } 730 #endif 731 732 static int 733 mEsc(char c) 734 { 735 c = getch(); 736 return (MenuEscKeymap[(int)c] (c)); 737 } 738 739 static int 740 mEscB(char c) 741 { 742 c = getch(); 743 if (IS_DIGIT(c)) 744 return (mEscD(c)); 745 else 746 return (MenuEscBKeymap[(int)c] (c)); 747 } 748 749 static int 750 mEscD(char c) 751 { 752 int d; 753 754 d = (int)c - (int)'0'; 755 c = getch(); 756 if (IS_DIGIT(c)) { 757 d = d * 10 + (int)c - (int)'0'; 758 c = getch(); 759 } 760 if (c == '~') 761 return (MenuEscDKeymap[d] (c)); 762 else 763 return (MENU_NOTHING); 764 } 765 766 static int 767 mNull(char c) 768 { 769 return (MENU_NOTHING); 770 } 771 772 static int 773 mSelect(char c) 774 { 775 if (IS_ASCII(c)) 776 return (select_menu(CurrentMenu, CurrentMenu->keyselect[(int)c])); 777 else 778 return (MENU_NOTHING); 779 } 780 781 static int 782 mDown(char c) 783 { 784 if (CurrentMenu->select >= CurrentMenu->nitem - 1) 785 return (MENU_NOTHING); 786 goto_menu(CurrentMenu, CurrentMenu->select + 1, 1); 787 return (MENU_NOTHING); 788 } 789 790 static int 791 mUp(char c) 792 { 793 if (CurrentMenu->select <= 0) 794 return (MENU_NOTHING); 795 goto_menu(CurrentMenu, CurrentMenu->select - 1, -1); 796 return (MENU_NOTHING); 797 } 798 799 static int 800 mLast(char c) 801 { 802 goto_menu(CurrentMenu, CurrentMenu->nitem - 1, -1); 803 return (MENU_NOTHING); 804 } 805 806 static int 807 mTop(char c) 808 { 809 goto_menu(CurrentMenu, 0, 1); 810 return (MENU_NOTHING); 811 } 812 813 static int 814 mNext(char c) 815 { 816 int mselect = CurrentMenu->select + CurrentMenu->height; 817 818 if (mselect >= CurrentMenu->nitem) 819 return mLast(c); 820 down_menu(CurrentMenu, CurrentMenu->height); 821 goto_menu(CurrentMenu, mselect, -1); 822 return (MENU_NOTHING); 823 } 824 825 static int 826 mPrev(char c) 827 { 828 int mselect = CurrentMenu->select - CurrentMenu->height; 829 830 if (mselect < 0) 831 return mTop(c); 832 up_menu(CurrentMenu, CurrentMenu->height); 833 goto_menu(CurrentMenu, mselect, 1); 834 return (MENU_NOTHING); 835 } 836 837 static int 838 mFore(char c) 839 { 840 if (CurrentMenu->select >= CurrentMenu->nitem - 1) 841 return (MENU_NOTHING); 842 goto_menu(CurrentMenu, (CurrentMenu->select + CurrentMenu->height - 1), 843 (CurrentMenu->height + 1)); 844 return (MENU_NOTHING); 845 } 846 847 static int 848 mBack(char c) 849 { 850 if (CurrentMenu->select <= 0) 851 return (MENU_NOTHING); 852 goto_menu(CurrentMenu, (CurrentMenu->select - CurrentMenu->height + 1), 853 (-1 - CurrentMenu->height)); 854 return (MENU_NOTHING); 855 } 856 857 static int 858 mLineU(char c) 859 { 860 int mselect = CurrentMenu->select; 861 862 if (mselect >= CurrentMenu->nitem) 863 return mLast(c); 864 if (CurrentMenu->offset + CurrentMenu->height >= CurrentMenu->nitem) 865 mselect++; 866 else { 867 down_menu(CurrentMenu, 1); 868 if (mselect < CurrentMenu->offset) 869 mselect++; 870 } 871 goto_menu(CurrentMenu, mselect, 1); 872 return (MENU_NOTHING); 873 } 874 875 static int 876 mLineD(char c) 877 { 878 int mselect = CurrentMenu->select; 879 880 if (mselect <= 0) 881 return mTop(c); 882 if (CurrentMenu->offset <= 0) 883 mselect--; 884 else { 885 up_menu(CurrentMenu, 1); 886 if (mselect >= CurrentMenu->offset + CurrentMenu->height) 887 mselect--; 888 } 889 goto_menu(CurrentMenu, mselect, -1); 890 return (MENU_NOTHING); 891 } 892 893 static int 894 mOk(char c) 895 { 896 int mselect = CurrentMenu->select; 897 898 if (CurrentMenu->item[mselect].type == MENU_NOP) 899 return (MENU_NOTHING); 900 return (mselect); 901 } 902 903 static int 904 mCancel(char c) 905 { 906 return (MENU_CANCEL); 907 } 908 909 static int 910 mClose(char c) 911 { 912 return (MENU_CLOSE); 913 } 914 915 static int 916 mSusp(char c) 917 { 918 susp(); 919 draw_all_menu(CurrentMenu); 920 select_menu(CurrentMenu, CurrentMenu->select); 921 return (MENU_NOTHING); 922 } 923 924 static char *SearchString = NULL; 925 926 int (*menuSearchRoutine) (Menu *, char *, int); 927 928 static int 929 menuForwardSearch(Menu *menu, char *str, int from) 930 { 931 int i; 932 char *p; 933 if ((p = regexCompile(str, IgnoreCase)) != NULL) { 934 message(p, 0, 0); 935 return -1; 936 } 937 if (from < 0) 938 from = 0; 939 for (i = from; i < menu->nitem; i++) 940 if (menu->item[i].type != MENU_NOP && 941 regexMatch(menu->item[i].label, -1, 1) == 1) 942 return i; 943 return -1; 944 } 945 946 static int 947 menu_search_forward(Menu *menu, int from) 948 { 949 char *str; 950 int found; 951 str = inputStrHist("Forward: ", NULL, TextHist); 952 if (str != NULL && *str == '\0') 953 str = SearchString; 954 if (str == NULL || *str == '\0') 955 return -1; 956 SearchString = str; 957 str = conv_search_string(str, DisplayCharset); 958 menuSearchRoutine = menuForwardSearch; 959 found = menuForwardSearch(menu, str, from + 1); 960 if (WrapSearch && found == -1) 961 found = menuForwardSearch(menu, str, 0); 962 if (found >= 0) 963 return found; 964 disp_message("Not found", TRUE); 965 return -1; 966 } 967 968 static int 969 mSrchF(char c) 970 { 971 int mselect; 972 mselect = menu_search_forward(CurrentMenu, CurrentMenu->select); 973 if (mselect >= 0) 974 goto_menu(CurrentMenu, mselect, 1); 975 return (MENU_NOTHING); 976 } 977 978 static int 979 menuBackwardSearch(Menu *menu, char *str, int from) 980 { 981 int i; 982 char *p; 983 if ((p = regexCompile(str, IgnoreCase)) != NULL) { 984 message(p, 0, 0); 985 return -1; 986 } 987 if (from >= menu->nitem) 988 from = menu->nitem - 1; 989 for (i = from; i >= 0; i--) 990 if (menu->item[i].type != MENU_NOP && 991 regexMatch(menu->item[i].label, -1, 1) == 1) 992 return i; 993 return -1; 994 } 995 996 static int 997 menu_search_backward(Menu *menu, int from) 998 { 999 char *str; 1000 int found; 1001 str = inputStrHist("Backward: ", NULL, TextHist); 1002 if (str != NULL && *str == '\0') 1003 str = SearchString; 1004 if (str == NULL || *str == '\0') 1005 return -1; 1006 SearchString = str; 1007 str = conv_search_string(str, DisplayCharset); 1008 menuSearchRoutine = menuBackwardSearch; 1009 found = menuBackwardSearch(menu, str, from - 1); 1010 if (WrapSearch && found == -1) 1011 found = menuBackwardSearch(menu, str, menu->nitem); 1012 if (found >= 0) 1013 return found; 1014 disp_message("Not found", TRUE); 1015 return -1; 1016 } 1017 1018 static int 1019 mSrchB(char c) 1020 { 1021 int mselect; 1022 mselect = menu_search_backward(CurrentMenu, CurrentMenu->select); 1023 if (mselect >= 0) 1024 goto_menu(CurrentMenu, mselect, -1); 1025 return (MENU_NOTHING); 1026 } 1027 1028 static int 1029 menu_search_next_previous(Menu *menu, int from, int reverse) 1030 { 1031 int found; 1032 static int (*routine[2]) (Menu *, char *, int) = { 1033 menuForwardSearch, menuBackwardSearch}; 1034 char *str; 1035 1036 if (menuSearchRoutine == NULL) { 1037 disp_message("No previous regular expression", TRUE); 1038 return -1; 1039 } 1040 str = conv_search_string(SearchString, DisplayCharset); 1041 if (reverse != 0) 1042 reverse = 1; 1043 if (menuSearchRoutine == menuBackwardSearch) 1044 reverse ^= 1; 1045 from += reverse ? -1 : 1; 1046 found = (*routine[reverse]) (menu, str, from); 1047 if (WrapSearch && found == -1) 1048 found = (*routine[reverse]) (menu, str, reverse * menu->nitem); 1049 if (found >= 0) 1050 return found; 1051 disp_message("Not found", TRUE); 1052 return -1; 1053 } 1054 1055 static int 1056 mSrchN(char c) 1057 { 1058 int mselect; 1059 mselect = menu_search_next_previous(CurrentMenu, CurrentMenu->select, 0); 1060 if (mselect >= 0) 1061 goto_menu(CurrentMenu, mselect, 1); 1062 return (MENU_NOTHING); 1063 } 1064 1065 static int 1066 mSrchP(char c) 1067 { 1068 int mselect; 1069 mselect = menu_search_next_previous(CurrentMenu, CurrentMenu->select, 1); 1070 if (mselect >= 0) 1071 goto_menu(CurrentMenu, mselect, -1); 1072 return (MENU_NOTHING); 1073 } 1074 1075 #ifdef USE_MOUSE 1076 #define MOUSE_BTN1_DOWN 0 1077 #define MOUSE_BTN2_DOWN 1 1078 #define MOUSE_BTN3_DOWN 2 1079 #define MOUSE_BTN4_DOWN_RXVT 3 1080 #define MOUSE_BTN5_DOWN_RXVT 4 1081 #define MOUSE_BTN4_DOWN_XTERM 64 1082 #define MOUSE_BTN5_DOWN_XTERM 65 1083 #define MOUSE_BTN_UP 3 1084 #define MOUSE_BTN_RESET -1 1085 1086 static int 1087 mMouse_scroll_line(void) 1088 { 1089 int i = 0; 1090 if (relative_wheel_scroll) 1091 i = (relative_wheel_scroll_ratio * CurrentMenu->height + 99) / 100; 1092 else 1093 i = fixed_wheel_scroll_count; 1094 return i ? i : 1; 1095 } 1096 1097 static int 1098 process_mMouse(int btn, int x, int y) 1099 { 1100 Menu *menu; 1101 int mselect, i; 1102 static int press_btn = MOUSE_BTN_RESET, press_x, press_y; 1103 char c = ' '; 1104 1105 menu = CurrentMenu; 1106 1107 if (x < 0 || x >= COLS || y < 0 || y > LASTLINE) 1108 return (MENU_NOTHING); 1109 1110 if (btn == MOUSE_BTN_UP) { 1111 switch (press_btn) { 1112 case MOUSE_BTN1_DOWN: 1113 case MOUSE_BTN3_DOWN: 1114 if (x < menu->x - FRAME_WIDTH || 1115 x >= menu->x + menu->width + FRAME_WIDTH || 1116 y < menu->y - 1 || y >= menu->y + menu->height + 1) { 1117 return (MENU_CANCEL); 1118 } 1119 else if ((x >= menu->x - FRAME_WIDTH && 1120 x < menu->x) || 1121 (x >= menu->x + menu->width && 1122 x < menu->x + menu->width + FRAME_WIDTH)) { 1123 return (MENU_NOTHING); 1124 } 1125 else if (press_y > y) { 1126 for (i = 0; i < press_y - y; i++) 1127 mLineU(c); 1128 return (MENU_NOTHING); 1129 } 1130 else if (press_y < y) { 1131 for (i = 0; i < y - press_y; i++) 1132 mLineD(c); 1133 return (MENU_NOTHING); 1134 } 1135 else if (y == menu->y - 1) { 1136 mPrev(c); 1137 return (MENU_NOTHING); 1138 } 1139 else if (y == menu->y + menu->height) { 1140 mNext(c); 1141 return (MENU_NOTHING); 1142 } 1143 else { 1144 mselect = y - menu->y + menu->offset; 1145 if (menu->item[mselect].type == MENU_NOP) 1146 return (MENU_NOTHING); 1147 return (select_menu(menu, mselect)); 1148 } 1149 break; 1150 case MOUSE_BTN4_DOWN_RXVT: 1151 for (i = 0; i < mMouse_scroll_line(); i++) 1152 mLineD(c); 1153 break; 1154 case MOUSE_BTN5_DOWN_RXVT: 1155 for (i = 0; i < mMouse_scroll_line(); i++) 1156 mLineU(c); 1157 break; 1158 } 1159 } 1160 else if (btn == MOUSE_BTN4_DOWN_XTERM) { 1161 for (i = 0; i < mMouse_scroll_line(); i++) 1162 mLineD(c); 1163 } 1164 else if (btn == MOUSE_BTN5_DOWN_XTERM) { 1165 for (i = 0; i < mMouse_scroll_line(); i++) 1166 mLineU(c); 1167 } 1168 1169 if (btn != MOUSE_BTN4_DOWN_RXVT || press_btn == MOUSE_BTN_RESET) { 1170 press_btn = btn; 1171 press_x = x; 1172 press_y = y; 1173 } 1174 else { 1175 press_btn = MOUSE_BTN_RESET; 1176 } 1177 return (MENU_NOTHING); 1178 } 1179 1180 static int 1181 mMouse(char c) 1182 { 1183 int btn, x, y; 1184 1185 btn = (unsigned char)getch() - 32; 1186 #if defined(__CYGWIN__) && CYGWIN_VERSION_DLL_MAJOR < 1005 1187 if (cygwin_mouse_btn_swapped) { 1188 if (btn == MOUSE_BTN2_DOWN) 1189 btn = MOUSE_BTN3_DOWN; 1190 else if (btn == MOUSE_BTN3_DOWN) 1191 btn = MOUSE_BTN2_DOWN; 1192 } 1193 #endif 1194 x = (unsigned char)getch() - 33; 1195 if (x < 0) 1196 x += 0x100; 1197 y = (unsigned char)getch() - 33; 1198 if (y < 0) 1199 y += 0x100; 1200 1201 /* 1202 * if (x < 0 || x >= COLS || y < 0 || y > LASTLINE) return; */ 1203 return process_mMouse(btn, x, y); 1204 } 1205 1206 #ifdef USE_GPM 1207 static int 1208 gpm_process_menu_mouse(Gpm_Event * event, void *data) 1209 { 1210 int btn = MOUSE_BTN_RESET, x, y; 1211 if (event->type & GPM_UP) 1212 btn = MOUSE_BTN_UP; 1213 else if (event->type & GPM_DOWN) { 1214 switch (event->buttons) { 1215 case GPM_B_LEFT: 1216 btn = MOUSE_BTN1_DOWN; 1217 break; 1218 case GPM_B_MIDDLE: 1219 btn = MOUSE_BTN2_DOWN; 1220 break; 1221 case GPM_B_RIGHT: 1222 btn = MOUSE_BTN3_DOWN; 1223 break; 1224 } 1225 } 1226 else { 1227 GPM_DRAWPOINTER(event); 1228 return 0; 1229 } 1230 x = event->x; 1231 y = event->y; 1232 X_Mouse_Selection = process_mMouse(btn, x - 1, y - 1); 1233 return X_MOUSE_SELECTED; 1234 } 1235 #endif /* USE_GPM */ 1236 1237 #ifdef USE_SYSMOUSE 1238 static int 1239 sysm_process_menu_mouse(int x, int y, int nbs, int obs) 1240 { 1241 int btn; 1242 int bits; 1243 1244 if (obs & ~nbs) 1245 btn = MOUSE_BTN_UP; 1246 else if (nbs & ~obs) { 1247 bits = nbs & ~obs; 1248 btn = bits & 0x1 ? MOUSE_BTN1_DOWN : 1249 (bits & 0x2 ? MOUSE_BTN2_DOWN : 1250 (bits & 0x4 ? MOUSE_BTN3_DOWN : 0)); 1251 } 1252 else /* nbs == obs */ 1253 return 0; 1254 X_Mouse_Selection = process_mMouse(btn, x, y); 1255 return X_MOUSE_SELECTED; 1256 } 1257 #endif /* USE_SYSMOUSE */ 1258 #else /* not USE_MOUSE */ 1259 static int 1260 mMouse(char c) 1261 { 1262 return (MENU_NOTHING); 1263 } 1264 #endif /* not USE_MOUSE */ 1265 1266 /* --- MenuFunctions (END) --- */ 1267 1268 /* --- MainMenu --- */ 1269 1270 void 1271 popupMenu(int x, int y, Menu *menu) 1272 { 1273 set_menu_frame(); 1274 1275 initSelectMenu(); 1276 initSelTabMenu(); 1277 1278 menu->cursorX = Currentbuf->cursorX + Currentbuf->rootX; 1279 menu->cursorY = Currentbuf->cursorY + Currentbuf->rootY; 1280 menu->x = x + FRAME_WIDTH + 1; 1281 menu->y = y + 2; 1282 1283 popup_menu(NULL, menu); 1284 } 1285 1286 void 1287 mainMenu(int x, int y) 1288 { 1289 popupMenu(x, y, &MainMenu); 1290 } 1291 1292 DEFUN(mainMn, MAIN_MENU MENU, "Popup menu") 1293 { 1294 Menu *menu = &MainMenu; 1295 char *data; 1296 int n; 1297 int x = Currentbuf->cursorX + Currentbuf->rootX, 1298 y = Currentbuf->cursorY + Currentbuf->rootY; 1299 1300 data = searchKeyData(); 1301 if (data != NULL) { 1302 n = getMenuN(w3mMenuList, data); 1303 if (n < 0) 1304 return; 1305 menu = w3mMenuList[n].menu; 1306 } 1307 #ifdef USE_MOUSE 1308 if (mouse_action.in_action) { 1309 x = mouse_action.cursorX; 1310 y = mouse_action.cursorY; 1311 } 1312 #endif 1313 popupMenu(x, y, menu); 1314 } 1315 1316 /* --- MainMenu (END) --- */ 1317 1318 /* --- SelectMenu --- */ 1319 1320 DEFUN(selMn, SELECT_MENU, "Popup buffer selection menu") 1321 { 1322 int x = Currentbuf->cursorX + Currentbuf->rootX, 1323 y = Currentbuf->cursorY + Currentbuf->rootY; 1324 1325 #ifdef USE_MOUSE 1326 if (mouse_action.in_action) { 1327 x = mouse_action.cursorX; 1328 y = mouse_action.cursorY; 1329 } 1330 #endif 1331 popupMenu(x, y, &SelectMenu); 1332 } 1333 1334 static void 1335 initSelectMenu(void) 1336 { 1337 int i, nitem, len = 0, l; 1338 Buffer *buf; 1339 Str str; 1340 char **label; 1341 char *p; 1342 static char *comment = " SPC for select / D for delete buffer "; 1343 1344 SelectV = -1; 1345 for (i = 0, buf = Firstbuf; buf != NULL; i++, buf = buf->nextBuffer) { 1346 if (buf == Currentbuf) 1347 SelectV = i; 1348 } 1349 nitem = i; 1350 1351 label = New_N(char *, nitem + 2); 1352 for (i = 0, buf = Firstbuf; i < nitem; i++, buf = buf->nextBuffer) { 1353 str = Sprintf("<%s>", buf->buffername); 1354 if (buf->filename != NULL) { 1355 switch (buf->currentURL.scheme) { 1356 case SCM_LOCAL: 1357 if (strcmp(buf->currentURL.file, "-")) { 1358 Strcat_char(str, ' '); 1359 Strcat_charp(str, 1360 conv_from_system(buf->currentURL.real_file)); 1361 } 1362 break; 1363 /* case SCM_UNKNOWN: */ 1364 case SCM_MISSING: 1365 break; 1366 default: 1367 Strcat_char(str, ' '); 1368 p = parsedURL2Str(&buf->currentURL)->ptr; 1369 if (DecodeURL) 1370 p = url_unquote_conv(p, 0); 1371 Strcat_charp(str, p); 1372 break; 1373 } 1374 } 1375 label[i] = str->ptr; 1376 if (len < str->length) 1377 len = str->length; 1378 } 1379 l = get_strwidth(comment); 1380 if (len < l + 4) 1381 len = l + 4; 1382 if (len > COLS - 2 * FRAME_WIDTH) 1383 len = COLS - 2 * FRAME_WIDTH; 1384 len = (len > 1) ? ((len - l + 1) / 2) : 0; 1385 str = Strnew(); 1386 for (i = 0; i < len; i++) 1387 Strcat_char(str, '-'); 1388 Strcat_charp(str, comment); 1389 for (i = 0; i < len; i++) 1390 Strcat_char(str, '-'); 1391 label[nitem] = str->ptr; 1392 label[nitem + 1] = NULL; 1393 1394 new_option_menu(&SelectMenu, label, &SelectV, smChBuf); 1395 SelectMenu.initial = SelectV; 1396 SelectMenu.cursorX = Currentbuf->cursorX + Currentbuf->rootX; 1397 SelectMenu.cursorY = Currentbuf->cursorY + Currentbuf->rootY; 1398 SelectMenu.keymap['D'] = smDelBuf; 1399 SelectMenu.item[nitem].type = MENU_NOP; 1400 } 1401 1402 static void 1403 smChBuf(void) 1404 { 1405 int i; 1406 Buffer *buf; 1407 1408 if (SelectV < 0 || SelectV >= SelectMenu.nitem) 1409 return; 1410 for (i = 0, buf = Firstbuf; i < SelectV; i++, buf = buf->nextBuffer) ; 1411 Currentbuf = buf; 1412 for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) { 1413 if (buf == Currentbuf) 1414 continue; 1415 #ifdef USE_IMAGE 1416 deleteImage(buf); 1417 #endif 1418 if (clear_buffer) 1419 tmpClearBuffer(buf); 1420 } 1421 } 1422 1423 static int 1424 smDelBuf(char c) 1425 { 1426 int i, x, y, mselect; 1427 Buffer *buf; 1428 1429 if (CurrentMenu->select < 0 || CurrentMenu->select >= SelectMenu.nitem) 1430 return (MENU_NOTHING); 1431 for (i = 0, buf = Firstbuf; i < CurrentMenu->select; 1432 i++, buf = buf->nextBuffer) ; 1433 if (Currentbuf == buf) 1434 Currentbuf = buf->nextBuffer; 1435 Firstbuf = deleteBuffer(Firstbuf, buf); 1436 if (!Currentbuf) 1437 Currentbuf = nthBuffer(Firstbuf, i - 1);; 1438 if (Firstbuf == NULL) { 1439 Firstbuf = nullBuffer(); 1440 Currentbuf = Firstbuf; 1441 } 1442 1443 x = CurrentMenu->x; 1444 y = CurrentMenu->y; 1445 mselect = CurrentMenu->select; 1446 1447 initSelectMenu(); 1448 1449 CurrentMenu->x = x; 1450 CurrentMenu->y = y; 1451 1452 geom_menu(CurrentMenu, x, y, 0); 1453 1454 CurrentMenu->select = (mselect <= CurrentMenu->nitem - 2) ? mselect 1455 : (CurrentMenu->nitem - 2); 1456 1457 displayBuffer(Currentbuf, B_FORCE_REDRAW); 1458 draw_all_menu(CurrentMenu); 1459 select_menu(CurrentMenu, CurrentMenu->select); 1460 return (MENU_NOTHING); 1461 } 1462 1463 /* --- SelectMenu (END) --- */ 1464 1465 /* --- SelTabMenu --- */ 1466 1467 DEFUN(tabMn, TAB_MENU, "Popup tab selection menu") 1468 { 1469 int x = Currentbuf->cursorX + Currentbuf->rootX, 1470 y = Currentbuf->cursorY + Currentbuf->rootY; 1471 1472 #ifdef USE_MOUSE 1473 if (mouse_action.in_action) { 1474 x = mouse_action.cursorX; 1475 y = mouse_action.cursorY; 1476 } 1477 #endif 1478 popupMenu(x, y, &SelTabMenu); 1479 } 1480 1481 static void 1482 initSelTabMenu(void) 1483 { 1484 int i, nitem, len = 0, l; 1485 TabBuffer *tab; 1486 Buffer *buf; 1487 Str str; 1488 char **label; 1489 char *p; 1490 static char *comment = " SPC for select / D for delete tab "; 1491 1492 SelTabV = -1; 1493 for (i = 0, tab = LastTab; tab != NULL; i++, tab = tab->prevTab) { 1494 if (tab == CurrentTab) 1495 SelTabV = i; 1496 } 1497 nitem = i; 1498 1499 label = New_N(char *, nitem + 2); 1500 for (i = 0, tab = LastTab; i < nitem; i++, tab = tab->prevTab) { 1501 buf = tab->currentBuffer; 1502 str = Sprintf("<%s>", buf->buffername); 1503 if (buf->filename != NULL) { 1504 switch (buf->currentURL.scheme) { 1505 case SCM_LOCAL: 1506 if (strcmp(buf->currentURL.file, "-")) { 1507 Strcat_char(str, ' '); 1508 Strcat_charp(str, 1509 conv_from_system(buf->currentURL.real_file)); 1510 } 1511 break; 1512 /* case SCM_UNKNOWN: */ 1513 case SCM_MISSING: 1514 break; 1515 default: 1516 p = parsedURL2Str(&buf->currentURL)->ptr; 1517 if (DecodeURL) 1518 p = url_unquote_conv(p, 0); 1519 Strcat_charp(str, p); 1520 break; 1521 } 1522 } 1523 label[i] = str->ptr; 1524 if (len < str->length) 1525 len = str->length; 1526 } 1527 l = strlen(comment); 1528 if (len < l + 4) 1529 len = l + 4; 1530 if (len > COLS - 2 * FRAME_WIDTH) 1531 len = COLS - 2 * FRAME_WIDTH; 1532 len = (len > 1) ? ((len - l + 1) / 2) : 0; 1533 str = Strnew(); 1534 for (i = 0; i < len; i++) 1535 Strcat_char(str, '-'); 1536 Strcat_charp(str, comment); 1537 for (i = 0; i < len; i++) 1538 Strcat_char(str, '-'); 1539 label[nitem] = str->ptr; 1540 label[nitem + 1] = NULL; 1541 1542 new_option_menu(&SelTabMenu, label, &SelTabV, smChTab); 1543 SelTabMenu.initial = SelTabV; 1544 SelTabMenu.cursorX = Currentbuf->cursorX + Currentbuf->rootX; 1545 SelTabMenu.cursorY = Currentbuf->cursorY + Currentbuf->rootY; 1546 SelTabMenu.keymap['D'] = smDelTab; 1547 SelTabMenu.item[nitem].type = MENU_NOP; 1548 } 1549 1550 static void 1551 smChTab(void) 1552 { 1553 int i; 1554 TabBuffer *tab; 1555 Buffer *buf; 1556 1557 if (SelTabV < 0 || SelTabV >= SelTabMenu.nitem) 1558 return; 1559 for (i = 0, tab = LastTab; i < SelTabV && tab != NULL; 1560 i++, tab = tab->prevTab) ; 1561 CurrentTab = tab; 1562 for (tab = LastTab; tab != NULL; tab = tab->prevTab) { 1563 if (tab == CurrentTab) 1564 continue; 1565 buf = tab->currentBuffer; 1566 #ifdef USE_IMAGE 1567 deleteImage(buf); 1568 #endif 1569 if (clear_buffer) 1570 tmpClearBuffer(buf); 1571 } 1572 } 1573 1574 static int 1575 smDelTab(char c) 1576 { 1577 int i, x, y, mselect; 1578 TabBuffer *tab; 1579 1580 if (CurrentMenu->select < 0 || CurrentMenu->select >= SelTabMenu.nitem) 1581 return (MENU_NOTHING); 1582 for (i = 0, tab = LastTab; i < CurrentMenu->select && tab != NULL; 1583 i++, tab = tab->prevTab) ; 1584 deleteTab(tab); 1585 1586 x = CurrentMenu->x; 1587 y = CurrentMenu->y; 1588 mselect = CurrentMenu->select; 1589 1590 initSelTabMenu(); 1591 1592 CurrentMenu->x = x; 1593 CurrentMenu->y = y; 1594 1595 geom_menu(CurrentMenu, x, y, 0); 1596 1597 CurrentMenu->select = (mselect <= CurrentMenu->nitem - 2) ? mselect 1598 : (CurrentMenu->nitem - 2); 1599 1600 displayBuffer(Currentbuf, B_FORCE_REDRAW); 1601 draw_all_menu(CurrentMenu); 1602 select_menu(CurrentMenu, CurrentMenu->select); 1603 return (MENU_NOTHING); 1604 } 1605 1606 /* --- SelectMenu (END) --- */ 1607 1608 /* --- OptionMenu --- */ 1609 1610 void 1611 optionMenu(int x, int y, char **label, int *variable, int initial, 1612 void (*func) ()) 1613 { 1614 Menu menu; 1615 1616 set_menu_frame(); 1617 1618 new_option_menu(&menu, label, variable, func); 1619 menu.cursorX = COLS - 1; 1620 menu.cursorY = LASTLINE; 1621 menu.x = x; 1622 menu.y = y; 1623 menu.initial = initial; 1624 1625 popup_menu(NULL, &menu); 1626 } 1627 1628 /* --- OptionMenu (END) --- */ 1629 1630 /* --- InitMenu --- */ 1631 1632 static void 1633 interpret_menu(FILE * mf) 1634 { 1635 Str line; 1636 char *p, *s; 1637 int in_menu = 0, nmenu = 0, nitem = 0, type; 1638 MenuItem *item = NULL; 1639 #ifdef USE_M17N 1640 wc_ces charset = SystemCharset; 1641 #endif 1642 1643 while (!feof(mf)) { 1644 line = Strfgets(mf); 1645 Strchop(line); 1646 Strremovefirstspaces(line); 1647 if (line->length == 0) 1648 continue; 1649 #ifdef USE_M17N 1650 line = wc_Str_conv(line, charset, InnerCharset); 1651 #endif 1652 p = line->ptr; 1653 s = getWord(&p); 1654 if (*s == '#') /* comment */ 1655 continue; 1656 if (in_menu) { 1657 type = setMenuItem(&item[nitem], s, p); 1658 if (type == -1) 1659 continue; /* error */ 1660 if (type == MENU_END) 1661 in_menu = 0; 1662 else { 1663 nitem++; 1664 item = New_Reuse(MenuItem, item, (nitem + 1)); 1665 w3mMenuList[nmenu].item = item; 1666 item[nitem].type = MENU_END; 1667 } 1668 } 1669 else if (!strcmp(s, "menu")) { 1670 s = getQWord(&p); 1671 if (*s == '\0') /* error */ 1672 continue; 1673 in_menu = 1; 1674 if ((nmenu = getMenuN(w3mMenuList, s)) != -1) 1675 w3mMenuList[nmenu].item = New(MenuItem); 1676 else 1677 nmenu = addMenuList(&w3mMenuList, s); 1678 item = w3mMenuList[nmenu].item; 1679 nitem = 0; 1680 item[nitem].type = MENU_END; 1681 } 1682 #ifdef USE_M17N 1683 else if (!strcmp(s, "charset") || !strcmp(s, "encoding")) { 1684 s = getQWord(&p); 1685 if (*s == '\0') /* error */ 1686 continue; 1687 charset = wc_guess_charset(s, charset); 1688 } 1689 #endif 1690 } 1691 } 1692 1693 void 1694 initMenu(void) 1695 { 1696 FILE *mf; 1697 MenuList *list; 1698 1699 w3mMenuList = New_N(MenuList, 3); 1700 w3mMenuList[0].id = "Main"; 1701 w3mMenuList[0].menu = &MainMenu; 1702 w3mMenuList[0].item = MainMenuItem; 1703 w3mMenuList[1].id = "Select"; 1704 w3mMenuList[1].menu = &SelectMenu; 1705 w3mMenuList[1].item = NULL; 1706 w3mMenuList[2].id = "SelectTab"; 1707 w3mMenuList[2].menu = &SelTabMenu; 1708 w3mMenuList[2].item = NULL; 1709 w3mMenuList[3].id = NULL; 1710 1711 #ifdef USE_M17N 1712 if (!MainMenuEncode) { 1713 MenuItem *item; 1714 #ifdef ENABLE_NLS 1715 /* FIXME: charset that gettext(3) returns */ 1716 MainMenuCharset = SystemCharset; 1717 #endif 1718 for (item = MainMenuItem; item->type != MENU_END; item++) 1719 item->label = 1720 wc_conv(_(item->label), MainMenuCharset, 1721 InnerCharset)->ptr; 1722 MainMenuEncode = TRUE; 1723 } 1724 #endif 1725 if ((mf = fopen(confFile(MENU_FILE), "rt")) != NULL) { 1726 interpret_menu(mf); 1727 fclose(mf); 1728 } 1729 if ((mf = fopen(rcFile(MENU_FILE), "rt")) != NULL) { 1730 interpret_menu(mf); 1731 fclose(mf); 1732 } 1733 1734 for (list = w3mMenuList; list->id != NULL; list++) { 1735 if (list->item == NULL) 1736 continue; 1737 new_menu(list->menu, list->item); 1738 } 1739 } 1740 1741 int 1742 setMenuItem(MenuItem *item, char *type, char *line) 1743 { 1744 char *label, *func, *popup, *keys, *data; 1745 int f; 1746 int n; 1747 1748 if (type == NULL || *type == '\0') /* error */ 1749 return -1; 1750 if (strcmp(type, "end") == 0) { 1751 item->type = MENU_END; 1752 return MENU_END; 1753 } 1754 else if (strcmp(type, "nop") == 0) { 1755 item->type = MENU_NOP; 1756 item->label = getQWord(&line); 1757 return MENU_NOP; 1758 } 1759 else if (strcmp(type, "func") == 0) { 1760 label = getQWord(&line); 1761 func = getWord(&line); 1762 keys = getQWord(&line); 1763 data = getQWord(&line); 1764 if (*func == '\0') /* error */ 1765 return -1; 1766 item->type = MENU_FUNC; 1767 item->label = label; 1768 f = getFuncList(func); 1769 item->func = w3mFuncList[(f >= 0) ? f : FUNCNAME_nulcmd].func; 1770 item->keys = keys; 1771 item->data = data; 1772 return MENU_FUNC; 1773 } 1774 else if (strcmp(type, "popup") == 0) { 1775 label = getQWord(&line); 1776 popup = getQWord(&line); 1777 keys = getQWord(&line); 1778 if (*popup == '\0') /* error */ 1779 return -1; 1780 item->type = MENU_POPUP; 1781 item->label = label; 1782 if ((n = getMenuN(w3mMenuList, popup)) == -1) 1783 n = addMenuList(&w3mMenuList, popup); 1784 item->popup = w3mMenuList[n].menu; 1785 item->keys = keys; 1786 return MENU_POPUP; 1787 } 1788 return -1; /* error */ 1789 } 1790 1791 int 1792 addMenuList(MenuList **mlist, char *id) 1793 { 1794 int n; 1795 MenuList *list = *mlist; 1796 1797 for (n = 0; list->id != NULL; list++, n++) ; 1798 *mlist = New_Reuse(MenuList, *mlist, (n + 2)); 1799 list = *mlist + n; 1800 list->id = id; 1801 list->menu = New(Menu); 1802 list->item = New(MenuItem); 1803 (list + 1)->id = NULL; 1804 return n; 1805 } 1806 1807 int 1808 getMenuN(MenuList *list, char *id) 1809 { 1810 int n; 1811 1812 for (n = 0; list->id != NULL; list++, n++) { 1813 if (strcmp(id, list->id) == 0) 1814 return n; 1815 } 1816 return -1; 1817 } 1818 1819 /* --- InitMenu (END) --- */ 1820 1821 LinkList * 1822 link_menu(Buffer *buf) 1823 { 1824 Menu menu; 1825 LinkList *l; 1826 int i, nitem, len = 0, linkV = -1; 1827 char **label; 1828 Str str; 1829 char *p; 1830 1831 if (!buf->linklist) 1832 return NULL; 1833 1834 for (i = 0, l = buf->linklist; l; i++, l = l->next) ; 1835 nitem = i; 1836 1837 label = New_N(char *, nitem + 1); 1838 for (i = 0, l = buf->linklist; l; i++, l = l->next) { 1839 str = Strnew_charp(l->title ? l->title : "(empty)"); 1840 if (l->type == LINK_TYPE_REL) 1841 Strcat_charp(str, " [Rel] "); 1842 else if (l->type == LINK_TYPE_REV) 1843 Strcat_charp(str, " [Rev] "); 1844 else 1845 Strcat_charp(str, " "); 1846 if (!l->url) 1847 p = ""; 1848 else if (DecodeURL) 1849 p = url_unquote_conv(l->url, buf->document_charset); 1850 else 1851 p = l->url; 1852 Strcat_charp(str, p); 1853 label[i] = str->ptr; 1854 if (len < str->length) 1855 len = str->length; 1856 } 1857 label[nitem] = NULL; 1858 1859 set_menu_frame(); 1860 new_option_menu(&menu, label, &linkV, NULL); 1861 1862 menu.initial = 0; 1863 menu.cursorX = buf->cursorX + buf->rootX; 1864 menu.cursorY = buf->cursorY + buf->rootY; 1865 menu.x = menu.cursorX + FRAME_WIDTH + 1; 1866 menu.y = menu.cursorY + 2; 1867 1868 popup_menu(NULL, &menu); 1869 1870 if (linkV < 0) 1871 return NULL; 1872 for (i = 0, l = buf->linklist; l; i++, l = l->next) { 1873 if (i == linkV) 1874 return l; 1875 } 1876 return NULL; 1877 } 1878 1879 /* --- LinkMenu (END) --- */ 1880 1881 Anchor * 1882 accesskey_menu(Buffer *buf) 1883 { 1884 Menu menu; 1885 AnchorList *al = buf->href; 1886 Anchor *a; 1887 Anchor **ap; 1888 int i, n, nitem = 0, key = -1; 1889 char **label; 1890 char *t; 1891 unsigned char c; 1892 1893 if (!al) 1894 return NULL; 1895 for (i = 0; i < al->nanchor; i++) { 1896 a = &al->anchors[i]; 1897 if (!a->slave && a->accesskey && IS_ASCII(a->accesskey)) 1898 nitem++; 1899 } 1900 if (!nitem) 1901 return NULL; 1902 1903 label = New_N(char *, nitem + 1); 1904 ap = New_N(Anchor *, nitem); 1905 for (i = 0, n = 0; i < al->nanchor; i++) { 1906 a = &al->anchors[i]; 1907 if (!a->slave && a->accesskey && IS_ASCII(a->accesskey)) { 1908 t = getAnchorText(buf, al, a); 1909 label[n] = Sprintf("%c: %s", a->accesskey, t ? t : "")->ptr; 1910 ap[n] = a; 1911 n++; 1912 } 1913 } 1914 label[nitem] = NULL; 1915 1916 new_option_menu(&menu, label, &key, NULL); 1917 1918 menu.initial = 0; 1919 menu.cursorX = buf->cursorX + buf->rootX; 1920 menu.cursorY = buf->cursorY + buf->rootY; 1921 menu.x = menu.cursorX + FRAME_WIDTH + 1; 1922 menu.y = menu.cursorY + 2; 1923 for (i = 0; i < 128; i++) 1924 menu.keyselect[i] = -1; 1925 for (i = 0; i < nitem; i++) { 1926 c = ap[i]->accesskey; 1927 menu.keymap[(int)c] = mSelect; 1928 menu.keyselect[(int)c] = i; 1929 } 1930 for (i = 0; i < nitem; i++) { 1931 c = ap[i]->accesskey; 1932 if (!IS_ALPHA(c) || menu.keyselect[n] >= 0) 1933 continue; 1934 c = TOLOWER(c); 1935 menu.keymap[(int)c] = mSelect; 1936 menu.keyselect[(int)c] = i; 1937 c = TOUPPER(c); 1938 menu.keymap[(int)c] = mSelect; 1939 menu.keyselect[(int)c] = i; 1940 } 1941 1942 a = retrieveCurrentAnchor(buf); 1943 if (a && a->accesskey && IS_ASCII(a->accesskey)) { 1944 for (i = 0; i < nitem; i++) { 1945 if (a->hseq == ap[i]->hseq) { 1946 menu.initial = i; 1947 break; 1948 } 1949 } 1950 } 1951 1952 popup_menu(NULL, &menu); 1953 1954 return (key >= 0) ? ap[key] : NULL; 1955 } 1956 1957 static char lmKeys[] = "abcdefgimopqrstuvwxyz"; 1958 static char lmKeys2[] = "1234567890ABCDEFGHILMOPQRSTUVWXYZ"; 1959 #define nlmKeys (sizeof(lmKeys) - 1) 1960 #define nlmKeys2 (sizeof(lmKeys2) - 1) 1961 1962 static int 1963 lmGoto(char c) 1964 { 1965 if (IS_ASCII(c) && CurrentMenu->keyselect[(int)c] >= 0) { 1966 goto_menu(CurrentMenu, CurrentMenu->nitem - 1, -1); 1967 goto_menu(CurrentMenu, CurrentMenu->keyselect[(int)c] * nlmKeys, 1); 1968 } 1969 return (MENU_NOTHING); 1970 } 1971 1972 static int 1973 lmSelect(char c) 1974 { 1975 if (IS_ASCII(c)) 1976 return select_menu(CurrentMenu, (CurrentMenu->select / nlmKeys) * 1977 nlmKeys + CurrentMenu->keyselect[(int)c]); 1978 else 1979 return (MENU_NOTHING); 1980 } 1981 1982 Anchor * 1983 list_menu(Buffer *buf) 1984 { 1985 Menu menu; 1986 AnchorList *al = buf->href; 1987 Anchor *a; 1988 Anchor **ap; 1989 int i, n, nitem = 0, key = -1, two = FALSE; 1990 char **label; 1991 char *t; 1992 unsigned char c; 1993 1994 if (!al) 1995 return NULL; 1996 for (i = 0; i < al->nanchor; i++) { 1997 a = &al->anchors[i]; 1998 if (!a->slave) 1999 nitem++; 2000 } 2001 if (!nitem) 2002 return NULL; 2003 2004 if (nitem >= nlmKeys) 2005 two = TRUE; 2006 label = New_N(char *, nitem + 1); 2007 ap = New_N(Anchor *, nitem); 2008 for (i = 0, n = 0; i < al->nanchor; i++) { 2009 a = &al->anchors[i]; 2010 if (!a->slave) { 2011 t = getAnchorText(buf, al, a); 2012 if (!t) 2013 t = ""; 2014 if (two && n >= nlmKeys2 * nlmKeys) 2015 label[n] = Sprintf(" : %s", t)->ptr; 2016 else if (two) 2017 label[n] = Sprintf("%c%c: %s", lmKeys2[n / nlmKeys], 2018 lmKeys[n % nlmKeys], t)->ptr; 2019 else 2020 label[n] = Sprintf("%c: %s", lmKeys[n], t)->ptr; 2021 ap[n] = a; 2022 n++; 2023 } 2024 } 2025 label[nitem] = NULL; 2026 2027 set_menu_frame(); 2028 set_menu_frame(); 2029 new_option_menu(&menu, label, &key, NULL); 2030 2031 menu.initial = 0; 2032 menu.cursorX = buf->cursorX + buf->rootX; 2033 menu.cursorY = buf->cursorY + buf->rootY; 2034 menu.x = menu.cursorX + FRAME_WIDTH + 1; 2035 menu.y = menu.cursorY + 2; 2036 for (i = 0; i < 128; i++) 2037 menu.keyselect[i] = -1; 2038 if (two) { 2039 for (i = 0; i < nlmKeys2; i++) { 2040 c = lmKeys2[i]; 2041 menu.keymap[(int)c] = lmGoto; 2042 menu.keyselect[(int)c] = i; 2043 } 2044 for (i = 0; i < nlmKeys; i++) { 2045 c = lmKeys[i]; 2046 menu.keymap[(int)c] = lmSelect; 2047 menu.keyselect[(int)c] = i; 2048 } 2049 } 2050 else { 2051 for (i = 0; i < nitem; i++) { 2052 c = lmKeys[i]; 2053 menu.keymap[(int)c] = mSelect; 2054 menu.keyselect[(int)c] = i; 2055 } 2056 } 2057 2058 a = retrieveCurrentAnchor(buf); 2059 if (a) { 2060 for (i = 0; i < nitem; i++) { 2061 if (a->hseq == ap[i]->hseq) { 2062 menu.initial = i; 2063 break; 2064 } 2065 } 2066 } 2067 2068 popup_menu(NULL, &menu); 2069 2070 return (key >= 0) ? ap[key] : NULL; 2071 } 2072 2073 #endif /* USE_MENU */