1 /* $Id: menu.c,v 1.46 2007/05/23 12:34:20 inu Exp $ */
16 static int gpm_process_menu_mouse(Gpm_Event * event, void *data);
17 extern int gpm_process_mouse(Gpm_Event *, void *);
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 */
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();}
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);
65 static int mPc(char c);
69 static int (*MenuKeymap[128]) (char c) = {
70 /* C-@ C-a C-b C-c C-d C-e C-f C-g */
72 mPc, mTop, mPrev, mClose, mNull, mLast, mNext, mNull,
74 mNull, mTop, mPrev, mClose, mNull, mLast, mNext, mNull,
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,
85 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mSrchF,
87 mNull, mNull, mNull, mNull, mNull, mNull , mNull, mNull,
89 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mSrchB,
91 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
93 mNull, mNull, mLineU, mLineD, mNull, mNull, mSrchP, mNull,
95 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
97 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
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,
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,
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,
118 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
120 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mEscB,
121 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
123 mNull, mNull, mNull, mEscB, mNull, mNull, mNull, mNull,
125 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
126 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
128 mNull, mNull, mNull, mNull, mNull, mNull, mPrev, mNull,
129 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
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,
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,
142 mNull, mUp, mDown, mOk, mCancel,mClose, mNull, mNull,
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,
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,
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,
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,
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,
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,
180 static int (*MenuPcKeymap[256])(char c)={
182 mNull, mNull, mNull, mNull, mNull, mNull, mNull, mNull,
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,
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,
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
236 /* --- SelectMenu --- */
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);
244 /* --- SelectMenu (END) --- */
246 /* --- SelTabMenu --- */
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);
254 /* --- SelTabMenu (END) --- */
256 /* --- MainMenu --- */
258 static Menu MainMenu;
260 /* FIXME: gettextize here */
261 static wc_ces MainMenuCharset = WC_CES_US_ASCII; /* FIXME: charset of source code */
262 static int MainMenuEncode = FALSE;
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",
270 {MENU_POPUP, N_(" Select Tab (t) "), NULL, 0, NULL, &SelTabMenu, "tT",
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},
292 /* --- MainMenu (END) --- */
294 static MenuList *w3mMenuList;
296 static Menu *CurrentMenu = NULL;
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))
303 new_menu(Menu *menu, MenuItem *item)
322 for (i = 0; item[i].type != MENU_END; i++) ;
324 menu->height = menu->nitem;
325 for (i = 0; i < 128; i++)
326 menu->keymap[i] = MenuKeymap[i];
328 for (i = 0; i < menu->nitem; i++) {
329 if ((p = item[i].keys) != NULL) {
332 menu->keymap[(int)*p] = mSelect;
333 menu->keyselect[(int)*p] = i;
338 l = get_strwidth(item[i].label);
345 geom_menu(Menu *menu, int x, int y, int mselect)
347 int win_x, win_y, win_w, win_h;
349 menu->select = mselect;
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;
360 menu->width = COLS - 2 * FRAME_WIDTH;
361 menu->width -= menu->width % FRAME_WIDTH;
362 win_w = menu->width + 2 * FRAME_WIDTH;
365 menu->x = win_x + FRAME_WIDTH;
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;
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;
384 draw_all_menu(Menu *menu)
386 if (menu->parent != NULL)
387 draw_all_menu(menu->parent);
392 draw_menu(Menu *menu)
397 x = menu->x - FRAME_WIDTH;
398 w = menu->width + 2 * FRAME_WIDTH;
401 if (menu->offset == 0) {
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]);
411 mvaddstr(y, x, FRAME[5]);
413 for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i++)
414 mvaddstr(y, x + i, " ");
416 mvaddstr(y, x + i, FRAME[5]);
418 i = (w / 2 - 1) / FRAME_WIDTH * FRAME_WIDTH;
419 mvaddstr(y, x + i, ":");
422 for (j = 0; j < menu->height; j++) {
425 mvaddstr(y, x, FRAME[5]);
427 draw_menu_item(menu, menu->offset + j);
429 mvaddstr(y, x + w - FRAME_WIDTH, FRAME[5]);
433 if (menu->offset + menu->height == menu->nitem) {
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]);
443 mvaddstr(y, x, FRAME[5]);
445 for (i = FRAME_WIDTH; i < w - FRAME_WIDTH; i++)
446 mvaddstr(y, x + i, " ");
448 mvaddstr(y, x + i, FRAME[5]);
450 i = (w / 2 - 1) / FRAME_WIDTH * FRAME_WIDTH;
451 mvaddstr(y, x + i, ":");
456 draw_menu_item(Menu *menu, int mselect)
458 mvaddnstr(menu->y + mselect - menu->offset, menu->x,
459 menu->item[mselect].label, menu->width);
463 select_menu(Menu *menu, int mselect)
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);
472 if (menu->select >= menu->offset &&
473 menu->select < menu->offset + menu->height)
474 draw_menu_item(menu, menu->select);
475 menu->select = mselect;
477 draw_menu_item(menu, menu->select);
480 * move(menu->cursorY, menu->cursorX); */
481 move(menu->y + mselect - menu->offset, menu->x);
485 return (menu->select);
489 goto_menu(Menu *menu, int mselect, int down)
492 if (mselect >= menu->nitem)
493 mselect = menu->nitem - 1;
494 else if (mselect < 0)
497 while (menu->item[mselect].type == MENU_NOP) {
499 if (++mselect >= menu->nitem) {
500 down_menu(menu, select_in - menu->select);
501 mselect = menu->select;
507 up_menu(menu, menu->select - select_in);
508 mselect = menu->select;
516 select_menu(menu, mselect);
520 up_menu(Menu *menu, int n)
522 if (n < 0 || menu->offset == 0)
525 if (menu->offset < 0)
532 down_menu(Menu *menu, int n)
534 if (n < 0 || menu->offset + menu->height == menu->nitem)
537 if (menu->offset + menu->height > menu->nitem)
538 menu->offset = menu->nitem - menu->height;
544 action_menu(Menu *menu)
550 if (menu->active == 0) {
551 if (menu->parent != NULL)
552 menu->parent->active = 0;
556 select_menu(menu, menu->select);
562 #endif /* USE_MOUSE */
567 #if defined(USE_GPM) || defined(USE_SYSMOUSE)
568 if (c == X_MOUSE_SELECTED) {
569 mselect = X_Mouse_Selection;
570 if (mselect != MENU_NOTHING)
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)
581 if (mselect >= 0 && mselect < menu->nitem) {
582 item = menu->item[mselect];
583 if (item.type & MENU_POPUP) {
584 popup_menu(menu, item.popup);
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) {
593 CurrentKeyData = NULL;
594 CurrentCmdData = item.data;
596 CurrentCmdData = NULL;
599 else if (mselect == MENU_CLOSE) {
600 if (menu->parent != NULL)
601 menu->parent->active = 0;
607 popup_menu(Menu *parent, Menu *menu)
611 if (menu->item == NULL || menu->nitem == 0)
618 gpm_handler = gpm_process_menu_mouse;
621 sysm_handler = sysm_process_menu_mouse;
622 #endif /* USE_SYSMOUSE */
623 #endif /* USE_MOUSE */
624 menu->parent = parent;
625 menu->select = menu->initial;
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);
633 geom_menu(menu, menu->x, menu->y, menu->select);
637 active = action_menu(CurrentMenu);
638 displayBuffer(Currentbuf, B_FORCE_REDRAW);
641 CurrentMenu = parent;
644 if (CurrentMenu == NULL)
645 gpm_handler = gpm_process_mouse;
648 if (CurrentMenu == NULL)
649 sysm_handler = sysm_process_mouse;
650 #endif /* USE_SYSMOUSE */
651 #endif /* USE_MOUSE */
655 guess_menu_xy(Menu *parent, int width, int *x, int *y)
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;
664 *y = parent->y + parent->select - parent->offset;
668 new_option_menu(Menu *menu, char **label, int *variable, void (*func) ())
674 if (label == NULL || *label == NULL)
677 for (i = 0, p = label; *p != NULL; i++, p++) ;
680 item = New_N(MenuItem, nitem + 1);
682 for (i = 0, p = label; i < nitem; i++, p++) {
684 item[i].type = MENU_VALUE | MENU_FUNC;
686 item[i].type = MENU_VALUE;
688 item[i].variable = variable;
691 item[i].popup = NULL;
694 item[nitem].type = MENU_END;
696 new_menu(menu, item);
705 FRAME = graph_symbol;
711 FRAME = get_symbol(DisplayCharset, &FRAME_WIDTH);
712 if (!WcOption.use_wide)
716 FRAME = get_symbol();
721 /* --- MenuFunctions --- */
728 return (MenuPcKeymap[(int)c] (c));
736 return (MenuEscKeymap[(int)c] (c));
746 return (MenuEscBKeymap[(int)c] (c));
754 d = (int)c - (int)'0';
757 d = d * 10 + (int)c - (int)'0';
761 return (MenuEscDKeymap[d] (c));
763 return (MENU_NOTHING);
769 return (MENU_NOTHING);
776 return (select_menu(CurrentMenu, CurrentMenu->keyselect[(int)c]));
778 return (MENU_NOTHING);
784 if (CurrentMenu->select >= CurrentMenu->nitem - 1)
785 return (MENU_NOTHING);
786 goto_menu(CurrentMenu, CurrentMenu->select + 1, 1);
787 return (MENU_NOTHING);
793 if (CurrentMenu->select <= 0)
794 return (MENU_NOTHING);
795 goto_menu(CurrentMenu, CurrentMenu->select - 1, -1);
796 return (MENU_NOTHING);
802 goto_menu(CurrentMenu, CurrentMenu->nitem - 1, -1);
803 return (MENU_NOTHING);
809 goto_menu(CurrentMenu, 0, 1);
810 return (MENU_NOTHING);
816 int mselect = CurrentMenu->select + CurrentMenu->height;
818 if (mselect >= CurrentMenu->nitem)
820 down_menu(CurrentMenu, CurrentMenu->height);
821 goto_menu(CurrentMenu, mselect, -1);
822 return (MENU_NOTHING);
828 int mselect = CurrentMenu->select - CurrentMenu->height;
832 up_menu(CurrentMenu, CurrentMenu->height);
833 goto_menu(CurrentMenu, mselect, 1);
834 return (MENU_NOTHING);
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);
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);
860 int mselect = CurrentMenu->select;
862 if (mselect >= CurrentMenu->nitem)
864 if (CurrentMenu->offset + CurrentMenu->height >= CurrentMenu->nitem)
867 down_menu(CurrentMenu, 1);
868 if (mselect < CurrentMenu->offset)
871 goto_menu(CurrentMenu, mselect, 1);
872 return (MENU_NOTHING);
878 int mselect = CurrentMenu->select;
882 if (CurrentMenu->offset <= 0)
885 up_menu(CurrentMenu, 1);
886 if (mselect >= CurrentMenu->offset + CurrentMenu->height)
889 goto_menu(CurrentMenu, mselect, -1);
890 return (MENU_NOTHING);
896 int mselect = CurrentMenu->select;
898 if (CurrentMenu->item[mselect].type == MENU_NOP)
899 return (MENU_NOTHING);
906 return (MENU_CANCEL);
919 draw_all_menu(CurrentMenu);
920 select_menu(CurrentMenu, CurrentMenu->select);
921 return (MENU_NOTHING);
924 static char *SearchString = NULL;
926 int (*menuSearchRoutine) (Menu *, char *, int);
929 menuForwardSearch(Menu *menu, char *str, int from)
933 if ((p = regexCompile(str, IgnoreCase)) != NULL) {
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)
947 menu_search_forward(Menu *menu, int from)
951 str = inputStrHist("Forward: ", NULL, TextHist);
952 if (str != NULL && *str == '\0')
954 if (str == NULL || *str == '\0')
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);
964 disp_message("Not found", TRUE);
972 mselect = menu_search_forward(CurrentMenu, CurrentMenu->select);
974 goto_menu(CurrentMenu, mselect, 1);
975 return (MENU_NOTHING);
979 menuBackwardSearch(Menu *menu, char *str, int from)
983 if ((p = regexCompile(str, IgnoreCase)) != NULL) {
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)
997 menu_search_backward(Menu *menu, int from)
1001 str = inputStrHist("Backward: ", NULL, TextHist);
1002 if (str != NULL && *str == '\0')
1004 if (str == NULL || *str == '\0')
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);
1014 disp_message("Not found", TRUE);
1022 mselect = menu_search_backward(CurrentMenu, CurrentMenu->select);
1024 goto_menu(CurrentMenu, mselect, -1);
1025 return (MENU_NOTHING);
1029 menu_search_next_previous(Menu *menu, int from, int reverse)
1032 static int (*routine[2]) (Menu *, char *, int) = {
1033 menuForwardSearch, menuBackwardSearch};
1036 if (menuSearchRoutine == NULL) {
1037 disp_message("No previous regular expression", TRUE);
1040 str = conv_search_string(SearchString, DisplayCharset);
1043 if (menuSearchRoutine == menuBackwardSearch)
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);
1051 disp_message("Not found", TRUE);
1059 mselect = menu_search_next_previous(CurrentMenu, CurrentMenu->select, 0);
1061 goto_menu(CurrentMenu, mselect, 1);
1062 return (MENU_NOTHING);
1069 mselect = menu_search_next_previous(CurrentMenu, CurrentMenu->select, 1);
1071 goto_menu(CurrentMenu, mselect, -1);
1072 return (MENU_NOTHING);
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
1087 mMouse_scroll_line(void)
1090 if (relative_wheel_scroll)
1091 i = (relative_wheel_scroll_ratio * CurrentMenu->height + 99) / 100;
1093 i = fixed_wheel_scroll_count;
1098 process_mMouse(int btn, int x, int y)
1102 static int press_btn = MOUSE_BTN_RESET, press_x, press_y;
1107 if (x < 0 || x >= COLS || y < 0 || y > LASTLINE)
1108 return (MENU_NOTHING);
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);
1119 else if ((x >= menu->x - FRAME_WIDTH &&
1121 (x >= menu->x + menu->width &&
1122 x < menu->x + menu->width + FRAME_WIDTH)) {
1123 return (MENU_NOTHING);
1125 else if (press_y > y) {
1126 for (i = 0; i < press_y - y; i++)
1128 return (MENU_NOTHING);
1130 else if (press_y < y) {
1131 for (i = 0; i < y - press_y; i++)
1133 return (MENU_NOTHING);
1135 else if (y == menu->y - 1) {
1137 return (MENU_NOTHING);
1139 else if (y == menu->y + menu->height) {
1141 return (MENU_NOTHING);
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));
1150 case MOUSE_BTN4_DOWN_RXVT:
1151 for (i = 0; i < mMouse_scroll_line(); i++)
1154 case MOUSE_BTN5_DOWN_RXVT:
1155 for (i = 0; i < mMouse_scroll_line(); i++)
1160 else if (btn == MOUSE_BTN4_DOWN_XTERM) {
1161 for (i = 0; i < mMouse_scroll_line(); i++)
1164 else if (btn == MOUSE_BTN5_DOWN_XTERM) {
1165 for (i = 0; i < mMouse_scroll_line(); i++)
1169 if (btn != MOUSE_BTN4_DOWN_RXVT || press_btn == MOUSE_BTN_RESET) {
1175 press_btn = MOUSE_BTN_RESET;
1177 return (MENU_NOTHING);
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;
1194 x = (unsigned char)getch() - 33;
1197 y = (unsigned char)getch() - 33;
1202 * if (x < 0 || x >= COLS || y < 0 || y > LASTLINE) return; */
1203 return process_mMouse(btn, x, y);
1208 gpm_process_menu_mouse(Gpm_Event * event, void *data)
1210 int btn = MOUSE_BTN_RESET, x, y;
1211 if (event->type & GPM_UP)
1213 else if (event->type & GPM_DOWN) {
1214 switch (event->buttons) {
1216 btn = MOUSE_BTN1_DOWN;
1219 btn = MOUSE_BTN2_DOWN;
1222 btn = MOUSE_BTN3_DOWN;
1227 GPM_DRAWPOINTER(event);
1232 X_Mouse_Selection = process_mMouse(btn, x - 1, y - 1);
1233 return X_MOUSE_SELECTED;
1235 #endif /* USE_GPM */
1239 sysm_process_menu_mouse(int x, int y, int nbs, int obs)
1246 else if (nbs & ~obs) {
1248 btn = bits & 0x1 ? MOUSE_BTN1_DOWN :
1249 (bits & 0x2 ? MOUSE_BTN2_DOWN :
1250 (bits & 0x4 ? MOUSE_BTN3_DOWN : 0));
1252 else /* nbs == obs */
1254 X_Mouse_Selection = process_mMouse(btn, x, y);
1255 return X_MOUSE_SELECTED;
1257 #endif /* USE_SYSMOUSE */
1258 #else /* not USE_MOUSE */
1262 return (MENU_NOTHING);
1264 #endif /* not USE_MOUSE */
1266 /* --- MenuFunctions (END) --- */
1268 /* --- MainMenu --- */
1271 popupMenu(int x, int y, Menu *menu)
1278 menu->cursorX = Currentbuf->cursorX + Currentbuf->rootX;
1279 menu->cursorY = Currentbuf->cursorY + Currentbuf->rootY;
1280 menu->x = x + FRAME_WIDTH + 1;
1283 popup_menu(NULL, menu);
1287 mainMenu(int x, int y)
1289 popupMenu(x, y, &MainMenu);
1292 DEFUN(mainMn, MAIN_MENU MENU, "Popup menu")
1294 Menu *menu = &MainMenu;
1297 int x = Currentbuf->cursorX + Currentbuf->rootX,
1298 y = Currentbuf->cursorY + Currentbuf->rootY;
1300 data = searchKeyData();
1302 n = getMenuN(w3mMenuList, data);
1305 menu = w3mMenuList[n].menu;
1308 if (mouse_action.in_action) {
1309 x = mouse_action.cursorX;
1310 y = mouse_action.cursorY;
1313 popupMenu(x, y, menu);
1316 /* --- MainMenu (END) --- */
1318 /* --- SelectMenu --- */
1320 DEFUN(selMn, SELECT_MENU, "Popup buffer selection menu")
1322 int x = Currentbuf->cursorX + Currentbuf->rootX,
1323 y = Currentbuf->cursorY + Currentbuf->rootY;
1326 if (mouse_action.in_action) {
1327 x = mouse_action.cursorX;
1328 y = mouse_action.cursorY;
1331 popupMenu(x, y, &SelectMenu);
1335 initSelectMenu(void)
1337 int i, nitem, len = 0, l;
1342 static char *comment = " SPC for select / D for delete buffer ";
1345 for (i = 0, buf = Firstbuf; buf != NULL; i++, buf = buf->nextBuffer) {
1346 if (buf == Currentbuf)
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) {
1357 if (strcmp(buf->currentURL.file, "-")) {
1358 Strcat_char(str, ' ');
1360 conv_from_system(buf->currentURL.real_file));
1363 /* case SCM_UNKNOWN: */
1367 Strcat_char(str, ' ');
1368 p = parsedURL2Str(&buf->currentURL)->ptr;
1370 p = url_unquote_conv(p, 0);
1371 Strcat_charp(str, p);
1375 label[i] = str->ptr;
1376 if (len < str->length)
1379 l = get_strwidth(comment);
1382 if (len > COLS - 2 * FRAME_WIDTH)
1383 len = COLS - 2 * FRAME_WIDTH;
1384 len = (len > 1) ? ((len - l + 1) / 2) : 0;
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;
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;
1408 if (SelectV < 0 || SelectV >= SelectMenu.nitem)
1410 for (i = 0, buf = Firstbuf; i < SelectV; i++, buf = buf->nextBuffer) ;
1412 for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) {
1413 if (buf == Currentbuf)
1419 tmpClearBuffer(buf);
1426 int i, x, y, mselect;
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);
1437 Currentbuf = nthBuffer(Firstbuf, i - 1);;
1438 if (Firstbuf == NULL) {
1439 Firstbuf = nullBuffer();
1440 Currentbuf = Firstbuf;
1445 mselect = CurrentMenu->select;
1452 geom_menu(CurrentMenu, x, y, 0);
1454 CurrentMenu->select = (mselect <= CurrentMenu->nitem - 2) ? mselect
1455 : (CurrentMenu->nitem - 2);
1457 displayBuffer(Currentbuf, B_FORCE_REDRAW);
1458 draw_all_menu(CurrentMenu);
1459 select_menu(CurrentMenu, CurrentMenu->select);
1460 return (MENU_NOTHING);
1463 /* --- SelectMenu (END) --- */
1465 /* --- SelTabMenu --- */
1467 DEFUN(tabMn, TAB_MENU, "Popup tab selection menu")
1469 int x = Currentbuf->cursorX + Currentbuf->rootX,
1470 y = Currentbuf->cursorY + Currentbuf->rootY;
1473 if (mouse_action.in_action) {
1474 x = mouse_action.cursorX;
1475 y = mouse_action.cursorY;
1478 popupMenu(x, y, &SelTabMenu);
1482 initSelTabMenu(void)
1484 int i, nitem, len = 0, l;
1490 static char *comment = " SPC for select / D for delete tab ";
1493 for (i = 0, tab = LastTab; tab != NULL; i++, tab = tab->prevTab) {
1494 if (tab == CurrentTab)
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) {
1506 if (strcmp(buf->currentURL.file, "-")) {
1507 Strcat_char(str, ' ');
1509 conv_from_system(buf->currentURL.real_file));
1512 /* case SCM_UNKNOWN: */
1516 p = parsedURL2Str(&buf->currentURL)->ptr;
1518 p = url_unquote_conv(p, 0);
1519 Strcat_charp(str, p);
1523 label[i] = str->ptr;
1524 if (len < str->length)
1527 l = strlen(comment);
1530 if (len > COLS - 2 * FRAME_WIDTH)
1531 len = COLS - 2 * FRAME_WIDTH;
1532 len = (len > 1) ? ((len - l + 1) / 2) : 0;
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;
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;
1557 if (SelTabV < 0 || SelTabV >= SelTabMenu.nitem)
1559 for (i = 0, tab = LastTab; i < SelTabV && tab != NULL;
1560 i++, tab = tab->prevTab) ;
1562 for (tab = LastTab; tab != NULL; tab = tab->prevTab) {
1563 if (tab == CurrentTab)
1565 buf = tab->currentBuffer;
1570 tmpClearBuffer(buf);
1577 int i, x, y, mselect;
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) ;
1588 mselect = CurrentMenu->select;
1595 geom_menu(CurrentMenu, x, y, 0);
1597 CurrentMenu->select = (mselect <= CurrentMenu->nitem - 2) ? mselect
1598 : (CurrentMenu->nitem - 2);
1600 displayBuffer(Currentbuf, B_FORCE_REDRAW);
1601 draw_all_menu(CurrentMenu);
1602 select_menu(CurrentMenu, CurrentMenu->select);
1603 return (MENU_NOTHING);
1606 /* --- SelectMenu (END) --- */
1608 /* --- OptionMenu --- */
1611 optionMenu(int x, int y, char **label, int *variable, int initial,
1618 new_option_menu(&menu, label, variable, func);
1619 menu.cursorX = COLS - 1;
1620 menu.cursorY = LASTLINE;
1623 menu.initial = initial;
1625 popup_menu(NULL, &menu);
1628 /* --- OptionMenu (END) --- */
1630 /* --- InitMenu --- */
1633 interpret_menu(FILE * mf)
1637 int in_menu = 0, nmenu = 0, nitem = 0, type;
1638 MenuItem *item = NULL;
1640 wc_ces charset = SystemCharset;
1644 line = Strfgets(mf);
1646 Strremovefirstspaces(line);
1647 if (line->length == 0)
1650 line = wc_Str_conv(line, charset, InnerCharset);
1654 if (*s == '#') /* comment */
1657 type = setMenuItem(&item[nitem], s, p);
1659 continue; /* error */
1660 if (type == MENU_END)
1664 item = New_Reuse(MenuItem, item, (nitem + 1));
1665 w3mMenuList[nmenu].item = item;
1666 item[nitem].type = MENU_END;
1669 else if (!strcmp(s, "menu")) {
1671 if (*s == '\0') /* error */
1674 if ((nmenu = getMenuN(w3mMenuList, s)) != -1)
1675 w3mMenuList[nmenu].item = New(MenuItem);
1677 nmenu = addMenuList(&w3mMenuList, s);
1678 item = w3mMenuList[nmenu].item;
1680 item[nitem].type = MENU_END;
1683 else if (!strcmp(s, "charset") || !strcmp(s, "encoding")) {
1685 if (*s == '\0') /* error */
1687 charset = wc_guess_charset(s, charset);
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;
1712 if (!MainMenuEncode) {
1715 /* FIXME: charset that gettext(3) returns */
1716 MainMenuCharset = SystemCharset;
1718 for (item = MainMenuItem; item->type != MENU_END; item++)
1720 wc_conv(_(item->label), MainMenuCharset,
1722 MainMenuEncode = TRUE;
1725 if ((mf = fopen(confFile(MENU_FILE), "rt")) != NULL) {
1729 if ((mf = fopen(rcFile(MENU_FILE), "rt")) != NULL) {
1734 for (list = w3mMenuList; list->id != NULL; list++) {
1735 if (list->item == NULL)
1737 new_menu(list->menu, list->item);
1742 setMenuItem(MenuItem *item, char *type, char *line)
1744 char *label, *func, *popup, *keys, *data;
1748 if (type == NULL || *type == '\0') /* error */
1750 if (strcmp(type, "end") == 0) {
1751 item->type = MENU_END;
1754 else if (strcmp(type, "nop") == 0) {
1755 item->type = MENU_NOP;
1756 item->label = getQWord(&line);
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 */
1766 item->type = MENU_FUNC;
1767 item->label = label;
1768 f = getFuncList(func);
1769 item->func = w3mFuncList[(f >= 0) ? f : FUNCNAME_nulcmd].func;
1774 else if (strcmp(type, "popup") == 0) {
1775 label = getQWord(&line);
1776 popup = getQWord(&line);
1777 keys = getQWord(&line);
1778 if (*popup == '\0') /* error */
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;
1788 return -1; /* error */
1792 addMenuList(MenuList **mlist, char *id)
1795 MenuList *list = *mlist;
1797 for (n = 0; list->id != NULL; list++, n++) ;
1798 *mlist = New_Reuse(MenuList, *mlist, (n + 2));
1801 list->menu = New(Menu);
1802 list->item = New(MenuItem);
1803 (list + 1)->id = NULL;
1808 getMenuN(MenuList *list, char *id)
1812 for (n = 0; list->id != NULL; list++, n++) {
1813 if (strcmp(id, list->id) == 0)
1819 /* --- InitMenu (END) --- */
1822 link_menu(Buffer *buf)
1826 int i, nitem, len = 0, linkV = -1;
1834 for (i = 0, l = buf->linklist; l; i++, l = l->next) ;
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] ");
1845 Strcat_charp(str, " ");
1849 p = url_unquote_conv(l->url, buf->document_charset);
1852 Strcat_charp(str, p);
1853 label[i] = str->ptr;
1854 if (len < str->length)
1857 label[nitem] = NULL;
1860 new_option_menu(&menu, label, &linkV, NULL);
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;
1868 popup_menu(NULL, &menu);
1872 for (i = 0, l = buf->linklist; l; i++, l = l->next) {
1879 /* --- LinkMenu (END) --- */
1882 accesskey_menu(Buffer *buf)
1885 AnchorList *al = buf->href;
1888 int i, n, nitem = 0, key = -1;
1895 for (i = 0; i < al->nanchor; i++) {
1896 a = &al->anchors[i];
1897 if (!a->slave && a->accesskey && IS_ASCII(a->accesskey))
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;
1914 label[nitem] = NULL;
1916 new_option_menu(&menu, label, &key, NULL);
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;
1930 for (i = 0; i < nitem; i++) {
1931 c = ap[i]->accesskey;
1932 if (!IS_ALPHA(c) || menu.keyselect[n] >= 0)
1935 menu.keymap[(int)c] = mSelect;
1936 menu.keyselect[(int)c] = i;
1938 menu.keymap[(int)c] = mSelect;
1939 menu.keyselect[(int)c] = i;
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) {
1952 popup_menu(NULL, &menu);
1954 return (key >= 0) ? ap[key] : NULL;
1957 static char lmKeys[] = "abcdefgimopqrstuvwxyz";
1958 static char lmKeys2[] = "1234567890ABCDEFGHILMOPQRSTUVWXYZ";
1959 #define nlmKeys (sizeof(lmKeys) - 1)
1960 #define nlmKeys2 (sizeof(lmKeys2) - 1)
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);
1969 return (MENU_NOTHING);
1976 return select_menu(CurrentMenu, (CurrentMenu->select / nlmKeys) *
1977 nlmKeys + CurrentMenu->keyselect[(int)c]);
1979 return (MENU_NOTHING);
1983 list_menu(Buffer *buf)
1986 AnchorList *al = buf->href;
1989 int i, n, nitem = 0, key = -1, two = FALSE;
1996 for (i = 0; i < al->nanchor; i++) {
1997 a = &al->anchors[i];
2004 if (nitem >= nlmKeys)
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];
2011 t = getAnchorText(buf, al, a);
2014 if (two && n >= nlmKeys2 * nlmKeys)
2015 label[n] = Sprintf(" : %s", t)->ptr;
2017 label[n] = Sprintf("%c%c: %s", lmKeys2[n / nlmKeys],
2018 lmKeys[n % nlmKeys], t)->ptr;
2020 label[n] = Sprintf("%c: %s", lmKeys[n], t)->ptr;
2025 label[nitem] = NULL;
2029 new_option_menu(&menu, label, &key, NULL);
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;
2039 for (i = 0; i < nlmKeys2; i++) {
2041 menu.keymap[(int)c] = lmGoto;
2042 menu.keyselect[(int)c] = i;
2044 for (i = 0; i < nlmKeys; i++) {
2046 menu.keymap[(int)c] = lmSelect;
2047 menu.keyselect[(int)c] = i;
2051 for (i = 0; i < nitem; i++) {
2053 menu.keymap[(int)c] = mSelect;
2054 menu.keyselect[(int)c] = i;
2058 a = retrieveCurrentAnchor(buf);
2060 for (i = 0; i < nitem; i++) {
2061 if (a->hseq == ap[i]->hseq) {
2068 popup_menu(NULL, &menu);
2070 return (key >= 0) ? ap[key] : NULL;
2073 #endif /* USE_MENU */