aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2014-06-04 08:58:31 +0400
committerDmitry Antipov2014-06-04 08:58:31 +0400
commitcfd794af4214ae0e5587ab8b1f4e5fcb355a0f12 (patch)
treec45be02b5b568e7534eb91e03ba46899dc42dff5 /src
parent39ec03147e88bb7a12d2e42edfa0206f6b7d546b (diff)
downloademacs-cfd794af4214ae0e5587ab8b1f4e5fcb355a0f12.tar.gz
emacs-cfd794af4214ae0e5587ab8b1f4e5fcb355a0f12.zip
Use terminal-specific hooks to display menus.
* termhooks.h (struct terminal): New field menu_show_hook. * menu.h (<anonymous enum>): Bit flags for menu hooks. (x_menu_show, w32_menu_show, ns_menu_show, tty_menu_show): Adjust prototypes. * menu.c (Fx_popup_menu): Use bit flags and menu_show_hook. * nsmenu.m (ns_menu_show): * w32menu.c (w32_menu_show): * xmenu.c (x_menu_show): * term.c (tty_menu_show): Adjust to use bit flags. (set_tty_hooks): Set menu_show_hook. * xterm.c (x_create_terminal): * nsterm.m (ns_create_terminal): * msdos.c (initialize_msdos_display): * w32term.c (w32_create_terminal): Likewise.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog18
-rw-r--r--src/menu.c53
-rw-r--r--src/menu.h27
-rw-r--r--src/msdos.c1
-rw-r--r--src/nsmenu.m3
-rw-r--r--src/nsterm.m3
-rw-r--r--src/term.c19
-rw-r--r--src/termhooks.h5
-rw-r--r--src/w32menu.c17
-rw-r--r--src/w32term.c2
-rw-r--r--src/xmenu.c40
-rw-r--r--src/xterm.c2
12 files changed, 104 insertions, 86 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 48f82e9ef42..bf46f8e7f1e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,21 @@
12014-06-04 Dmitry Antipov <dmantipov@yandex.ru>
2
3 Use terminal-specific hooks to display menus.
4 * termhooks.h (struct terminal): New field menu_show_hook.
5 * menu.h (<anonymous enum>): Bit flags for menu hooks.
6 (x_menu_show, w32_menu_show, ns_menu_show, tty_menu_show):
7 Adjust prototypes.
8 * menu.c (Fx_popup_menu): Use bit flags and menu_show_hook.
9 * nsmenu.m (ns_menu_show):
10 * w32menu.c (w32_menu_show):
11 * xmenu.c (x_menu_show):
12 * term.c (tty_menu_show): Adjust to use bit flags.
13 (set_tty_hooks): Set menu_show_hook.
14 * xterm.c (x_create_terminal):
15 * nsterm.m (ns_create_terminal):
16 * msdos.c (initialize_msdos_display):
17 * w32term.c (w32_create_terminal): Likewise.
18
12014-06-03 Juanma Barranquero <lekktu@gmail.com> 192014-06-03 Juanma Barranquero <lekktu@gmail.com>
2 20
3 * w32heap.c (DUMPED_HEAP_SIZE) [!_WIN64]: Reduce to 11 MB. 21 * w32heap.c (DUMPED_HEAP_SIZE) [!_WIN64]: Reduce to 11 MB.
diff --git a/src/menu.c b/src/menu.c
index 0cd886f55d1..b65401c6f4f 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1161,9 +1161,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
1161 Lisp_Object selection = Qnil; 1161 Lisp_Object selection = Qnil;
1162 struct frame *f = NULL; 1162 struct frame *f = NULL;
1163 Lisp_Object x, y, window; 1163 Lisp_Object x, y, window;
1164 bool keymaps = 0; 1164 int menuflags = 0;
1165 bool for_click = 0;
1166 bool kbd_menu_navigation = 0;
1167 ptrdiff_t specpdl_count = SPECPDL_INDEX (); 1165 ptrdiff_t specpdl_count = SPECPDL_INDEX ();
1168 struct gcpro gcpro1; 1166 struct gcpro gcpro1;
1169 1167
@@ -1193,12 +1191,12 @@ no quit occurs and `x-popup-menu' returns nil. */)
1193 } 1191 }
1194 else 1192 else
1195 { 1193 {
1196 for_click = 1; 1194 menuflags |= MENU_FOR_CLICK;
1197 tem = Fcar (Fcdr (position)); /* EVENT_START (position) */ 1195 tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
1198 window = Fcar (tem); /* POSN_WINDOW (tem) */ 1196 window = Fcar (tem); /* POSN_WINDOW (tem) */
1199 tem2 = Fcar (Fcdr (tem)); /* POSN_POSN (tem) */ 1197 tem2 = Fcar (Fcdr (tem)); /* POSN_POSN (tem) */
1200 /* The kbd_menu_navigation flag is set when the menu was 1198 /* The MENU_KBD_NAVIGATION field is set when the menu
1201 invoked by F10, which probably means they have no 1199 was invoked by F10, which probably means they have no
1202 mouse. In that case, we let them switch between 1200 mouse. In that case, we let them switch between
1203 top-level menu-bar menus by using C-f/C-b and 1201 top-level menu-bar menus by using C-f/C-b and
1204 horizontal arrow keys, since they cannot click the 1202 horizontal arrow keys, since they cannot click the
@@ -1211,7 +1209,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
1211 if (!EQ (POSN_POSN (last_nonmenu_event), 1209 if (!EQ (POSN_POSN (last_nonmenu_event),
1212 POSN_POSN (position)) 1210 POSN_POSN (position))
1213 && CONSP (tem2) && EQ (Fcar (tem2), Qmenu_bar)) 1211 && CONSP (tem2) && EQ (Fcar (tem2), Qmenu_bar))
1214 kbd_menu_navigation = 1; 1212 menuflags |= MENU_KBD_NAVIGATION;
1215 tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */ 1213 tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
1216 x = Fcar (tem); 1214 x = Fcar (tem);
1217 y = Fcdr (tem); 1215 y = Fcdr (tem);
@@ -1340,7 +1338,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
1340 if (!NILP (prompt) && menu_items_n_panes >= 0) 1338 if (!NILP (prompt) && menu_items_n_panes >= 0)
1341 ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt); 1339 ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt);
1342 1340
1343 keymaps = 1; 1341 menuflags |= MENU_KEYMAPS;
1344 } 1342 }
1345 else if (CONSP (menu) && KEYMAPP (XCAR (menu))) 1343 else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
1346 { 1344 {
@@ -1373,7 +1371,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
1373 if (!NILP (title) && menu_items_n_panes >= 0) 1371 if (!NILP (title) && menu_items_n_panes >= 0)
1374 ASET (menu_items, MENU_ITEMS_PANE_NAME, title); 1372 ASET (menu_items, MENU_ITEMS_PANE_NAME, title);
1375 1373
1376 keymaps = 1; 1374 menuflags |= MENU_KEYMAPS;
1377 1375
1378 SAFE_FREE (); 1376 SAFE_FREE ();
1379 } 1377 }
@@ -1385,7 +1383,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
1385 1383
1386 list_of_panes (Fcdr (menu)); 1384 list_of_panes (Fcdr (menu));
1387 1385
1388 keymaps = 0; 1386 menuflags &= ~MENU_KEYMAPS;
1389 } 1387 }
1390 1388
1391 unbind_to (specpdl_count, Qnil); 1389 unbind_to (specpdl_count, Qnil);
@@ -1416,39 +1414,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
1416#endif 1414#endif
1417 1415
1418 /* Display them in a menu. */ 1416 /* Display them in a menu. */
1419 1417 selection = FRAME_TERMINAL (f)->menu_show_hook (f, xpos, ypos, menuflags,
1420 /* FIXME: Use a terminal hook! */ 1418 title, &error_name);
1421#if defined HAVE_NTGUI
1422 if (FRAME_W32_P (f))
1423 selection = w32_menu_show (f, xpos, ypos, for_click,
1424 keymaps, title, &error_name);
1425 else
1426#endif
1427#if defined HAVE_NS
1428 if (FRAME_NS_P (f))
1429 selection = ns_menu_show (f, xpos, ypos, for_click,
1430 keymaps, title, &error_name);
1431 else
1432#endif
1433#if (defined (HAVE_X_WINDOWS) || defined (MSDOS))
1434 if (FRAME_X_P (f) || FRAME_MSDOS_P (f))
1435 selection = xmenu_show (f, xpos, ypos, for_click,
1436 keymaps, title, &error_name);
1437 else
1438#endif
1439#ifndef MSDOS
1440 if (FRAME_TERMCAP_P (f))
1441 {
1442 ptrdiff_t count1 = SPECPDL_INDEX ();
1443
1444 /* Avoid crashes if, e.g., another client will connect while we
1445 are in a menu. */
1446 temporarily_switch_to_single_kboard (f);
1447 selection = tty_menu_show (f, xpos, ypos, for_click, keymaps, title,
1448 kbd_menu_navigation, &error_name);
1449 unbind_to (count1, Qnil);
1450 }
1451#endif
1452 1419
1453#ifdef HAVE_NS 1420#ifdef HAVE_NS
1454 unbind_to (specpdl_count, Qnil); 1421 unbind_to (specpdl_count, Qnil);
diff --git a/src/menu.h b/src/menu.h
index 266a471bc38..e2d7601378e 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -26,6 +26,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26extern Lisp_Object Qunsupported__w32_dialog; 26extern Lisp_Object Qunsupported__w32_dialog;
27#endif 27#endif
28 28
29/* Bit fields used by terminal-specific menu_show_hook. */
30
31enum {
32 MENU_KEYMAPS = 0x1,
33 MENU_FOR_CLICK = 0x2,
34 MENU_KBD_NAVIGATION = 0x4
35};
36
29extern void x_set_menu_bar_lines (struct frame *f, 37extern void x_set_menu_bar_lines (struct frame *f,
30 Lisp_Object value, 38 Lisp_Object value,
31 Lisp_Object oldval); 39 Lisp_Object oldval);
@@ -49,14 +57,19 @@ extern widget_value *digest_single_submenu (int, int, bool);
49#ifdef HAVE_X_WINDOWS 57#ifdef HAVE_X_WINDOWS
50extern void mouse_position_for_popup (struct frame *f, int *x, int *y); 58extern void mouse_position_for_popup (struct frame *f, int *x, int *y);
51#endif 59#endif
52 60#if defined (HAVE_X_WINDOWS) || defined (MSDOS)
53extern Lisp_Object w32_menu_show (struct frame *, int, int, int, int, 61extern Lisp_Object x_menu_show (struct frame *, int, int, int,
62 Lisp_Object, const char **);
63#endif
64#ifdef HAVE_NTGUI
65extern Lisp_Object w32_menu_show (struct frame *, int, int, int,
54 Lisp_Object, const char **); 66 Lisp_Object, const char **);
55extern Lisp_Object ns_menu_show (struct frame *, int, int, bool, bool, 67#endif
68#ifdef HAVE_NS
69extern Lisp_Object ns_menu_show (struct frame *, int, int, int,
56 Lisp_Object, const char **); 70 Lisp_Object, const char **);
57extern Lisp_Object xmenu_show (struct frame *, int, int, bool, bool, 71#endif
58 Lisp_Object, const char **); 72extern Lisp_Object tty_menu_show (struct frame *, int, int, int,
59extern Lisp_Object tty_menu_show (struct frame *, int, int, bool, bool, 73 Lisp_Object, const char **);
60 Lisp_Object, bool, const char **);
61extern ptrdiff_t menu_item_width (const unsigned char *); 74extern ptrdiff_t menu_item_width (const unsigned char *);
62#endif /* MENU_H */ 75#endif /* MENU_H */
diff --git a/src/msdos.c b/src/msdos.c
index 21794341222..ccca371583f 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -1863,6 +1863,7 @@ initialize_msdos_display (struct terminal *term)
1863 term->update_end_hook = IT_update_end; 1863 term->update_end_hook = IT_update_end;
1864 term->frame_up_to_date_hook = IT_frame_up_to_date; 1864 term->frame_up_to_date_hook = IT_frame_up_to_date;
1865 term->mouse_position_hook = 0; /* set later by dos_ttraw */ 1865 term->mouse_position_hook = 0; /* set later by dos_ttraw */
1866 term->menu_show_hook = x_menu_show;
1866 term->frame_rehighlight_hook = 0; 1867 term->frame_rehighlight_hook = 0;
1867 term->frame_raise_lower_hook = 0; 1868 term->frame_raise_lower_hook = 0;
1868 term->set_vertical_scroll_bar_hook = 0; 1869 term->set_vertical_scroll_bar_hook = 0;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 46b7400b2e4..65494cb2582 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -812,7 +812,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
812 ========================================================================== */ 812 ========================================================================== */
813 813
814Lisp_Object 814Lisp_Object
815ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, 815ns_menu_show (struct frame *f, int x, int y, int menuflags,
816 Lisp_Object title, const char **error) 816 Lisp_Object title, const char **error)
817{ 817{
818 EmacsMenu *pmenu; 818 EmacsMenu *pmenu;
@@ -820,6 +820,7 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
820 Lisp_Object tem; 820 Lisp_Object tem;
821 ptrdiff_t specpdl_count = SPECPDL_INDEX (); 821 ptrdiff_t specpdl_count = SPECPDL_INDEX ();
822 widget_value *wv, *first_wv = 0; 822 widget_value *wv, *first_wv = 0;
823 bool keymaps = (menuflags & MENU_KEYMAPS);
823 824
824 block_input (); 825 block_input ();
825 826
diff --git a/src/nsterm.m b/src/nsterm.m
index f91b86daea6..295cfc5c86d 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -54,7 +54,7 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
54 54
55#include "termhooks.h" 55#include "termhooks.h"
56#include "termchar.h" 56#include "termchar.h"
57 57#include "menu.h"
58#include "window.h" 58#include "window.h"
59#include "keyboard.h" 59#include "keyboard.h"
60#include "buffer.h" 60#include "buffer.h"
@@ -4164,6 +4164,7 @@ ns_create_terminal (struct ns_display_info *dpyinfo)
4164 terminal->frame_rehighlight_hook = ns_frame_rehighlight; 4164 terminal->frame_rehighlight_hook = ns_frame_rehighlight;
4165 terminal->frame_raise_lower_hook = ns_frame_raise_lower; 4165 terminal->frame_raise_lower_hook = ns_frame_raise_lower;
4166 terminal->fullscreen_hook = ns_fullscreen_hook; 4166 terminal->fullscreen_hook = ns_fullscreen_hook;
4167 terminal->menu_show_hook = ns_menu_show;
4167 terminal->set_vertical_scroll_bar_hook = ns_set_vertical_scroll_bar; 4168 terminal->set_vertical_scroll_bar_hook = ns_set_vertical_scroll_bar;
4168 terminal->condemn_scroll_bars_hook = ns_condemn_scroll_bars; 4169 terminal->condemn_scroll_bars_hook = ns_condemn_scroll_bars;
4169 terminal->redeem_scroll_bar_hook = ns_redeem_scroll_bar; 4170 terminal->redeem_scroll_bar_hook = ns_redeem_scroll_bar;
diff --git a/src/term.c b/src/term.c
index 379c94e54a1..aa0be9871c8 100644
--- a/src/term.c
+++ b/src/term.c
@@ -3583,8 +3583,8 @@ tty_menu_new_item_coords (struct frame *f, int which, int *x, int *y)
3583} 3583}
3584 3584
3585Lisp_Object 3585Lisp_Object
3586tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, 3586tty_menu_show (struct frame *f, int x, int y, int menuflags,
3587 Lisp_Object title, bool kbd_navigation, const char **error_name) 3587 Lisp_Object title, const char **error_name)
3588{ 3588{
3589 tty_menu *menu; 3589 tty_menu *menu;
3590 int pane, selidx, lpane, status; 3590 int pane, selidx, lpane, status;
@@ -3621,6 +3621,10 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
3621 menu functions pointers to the contents of strings. */ 3621 menu functions pointers to the contents of strings. */
3622 specpdl_count = inhibit_garbage_collection (); 3622 specpdl_count = inhibit_garbage_collection ();
3623 3623
3624 /* Avoid crashes if, e.g., another client will connect while we
3625 are in a menu. */
3626 temporarily_switch_to_single_kboard (f);
3627
3624 /* Adjust coordinates to be root-window-relative. */ 3628 /* Adjust coordinates to be root-window-relative. */
3625 item_x = x += f->left_pos; 3629 item_x = x += f->left_pos;
3626 item_y = y += f->top_pos; 3630 item_y = y += f->top_pos;
@@ -3642,7 +3646,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
3642 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); 3646 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
3643 pane_string = (NILP (pane_name) 3647 pane_string = (NILP (pane_name)
3644 ? "" : SSDATA (pane_name)); 3648 ? "" : SSDATA (pane_name));
3645 if (keymaps && !NILP (prefix)) 3649 if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
3646 pane_string++; 3650 pane_string++;
3647 3651
3648 lpane = tty_menu_add_pane (menu, pane_string); 3652 lpane = tty_menu_add_pane (menu, pane_string);
@@ -3782,7 +3786,8 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
3782 specbind (Qoverriding_terminal_local_map, 3786 specbind (Qoverriding_terminal_local_map,
3783 Fsymbol_value (Qtty_menu_navigation_map)); 3787 Fsymbol_value (Qtty_menu_navigation_map));
3784 status = tty_menu_activate (menu, &pane, &selidx, x, y, &datap, 3788 status = tty_menu_activate (menu, &pane, &selidx, x, y, &datap,
3785 tty_menu_help_callback, kbd_navigation); 3789 tty_menu_help_callback,
3790 menuflags & MENU_KBD_NAVIGATION);
3786 entry = pane_prefix = Qnil; 3791 entry = pane_prefix = Qnil;
3787 3792
3788 switch (status) 3793 switch (status)
@@ -3808,7 +3813,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
3808 { 3813 {
3809 entry 3814 entry
3810 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); 3815 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
3811 if (keymaps != 0) 3816 if (menuflags & MENU_KEYMAPS)
3812 { 3817 {
3813 entry = Fcons (entry, Qnil); 3818 entry = Fcons (entry, Qnil);
3814 if (!NILP (pane_prefix)) 3819 if (!NILP (pane_prefix))
@@ -3841,7 +3846,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
3841 Ftop_level (); 3846 Ftop_level ();
3842 /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means 3847 /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
3843 the menu was invoked with a mouse event as POSITION). */ 3848 the menu was invoked with a mouse event as POSITION). */
3844 if (! for_click) 3849 if (!(menuflags & MENU_FOR_CLICK))
3845 Fsignal (Qquit, Qnil); 3850 Fsignal (Qquit, Qnil);
3846 break; 3851 break;
3847 } 3852 }
@@ -3922,6 +3927,7 @@ clear_tty_hooks (struct terminal *terminal)
3922 terminal->frame_rehighlight_hook = 0; 3927 terminal->frame_rehighlight_hook = 0;
3923 terminal->frame_raise_lower_hook = 0; 3928 terminal->frame_raise_lower_hook = 0;
3924 terminal->fullscreen_hook = 0; 3929 terminal->fullscreen_hook = 0;
3930 terminal->menu_show_hook = 0;
3925 terminal->set_vertical_scroll_bar_hook = 0; 3931 terminal->set_vertical_scroll_bar_hook = 0;
3926 terminal->condemn_scroll_bars_hook = 0; 3932 terminal->condemn_scroll_bars_hook = 0;
3927 terminal->redeem_scroll_bar_hook = 0; 3933 terminal->redeem_scroll_bar_hook = 0;
@@ -3953,6 +3959,7 @@ set_tty_hooks (struct terminal *terminal)
3953 terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes; 3959 terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes;
3954 terminal->set_terminal_modes_hook = &tty_set_terminal_modes; 3960 terminal->set_terminal_modes_hook = &tty_set_terminal_modes;
3955 terminal->update_end_hook = &tty_update_end; 3961 terminal->update_end_hook = &tty_update_end;
3962 terminal->menu_show_hook = &tty_menu_show;
3956 terminal->set_terminal_window_hook = &tty_set_terminal_window; 3963 terminal->set_terminal_window_hook = &tty_set_terminal_window;
3957 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */ 3964 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
3958 terminal->delete_frame_hook = &tty_free_frame_resources; 3965 terminal->delete_frame_hook = &tty_free_frame_resources;
diff --git a/src/termhooks.h b/src/termhooks.h
index 207b8ccbc3c..76adc539e48 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -478,7 +478,10 @@ struct terminal
478 may do something OS dependent, like extended window manager hints on X11. */ 478 may do something OS dependent, like extended window manager hints on X11. */
479 void (*fullscreen_hook) (struct frame *f); 479 void (*fullscreen_hook) (struct frame *f);
480 480
481 481 /* This hook is called to display menus. */
482 Lisp_Object (*menu_show_hook) (struct frame *f, int x, int y, int menuflags,
483 Lisp_Object title, const char **error_name);
484
482 /* Scroll bar hooks. */ 485 /* Scroll bar hooks. */
483 486
484 /* The representation of scroll bars is determined by the code which 487 /* The representation of scroll bars is determined by the code which
diff --git a/src/w32menu.c b/src/w32menu.c
index 467eb7a5710..6276c840fc6 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -549,8 +549,9 @@ free_frame_menubar (struct frame *f)
549/* F is the frame the menu is for. 549/* F is the frame the menu is for.
550 X and Y are the frame-relative specified position, 550 X and Y are the frame-relative specified position,
551 relative to the inside upper left corner of the frame F. 551 relative to the inside upper left corner of the frame F.
552 FOR_CLICK is nonzero if this menu was invoked for a mouse click. 552 Bitfield MENUFLAGS bits are:
553 KEYMAPS is 1 if this menu was specified with keymaps; 553 MENU_FOR_CLICK is set if this menu was invoked for a mouse click.
554 MENU_KEYMAPS is set if this menu was specified with keymaps;
554 in that case, we return a list containing the chosen item's value 555 in that case, we return a list containing the chosen item's value
555 and perhaps also the pane's prefix. 556 and perhaps also the pane's prefix.
556 TITLE is the specified menu title. 557 TITLE is the specified menu title.
@@ -558,7 +559,7 @@ free_frame_menubar (struct frame *f)
558 (We return nil on failure, but the value doesn't actually matter.) */ 559 (We return nil on failure, but the value doesn't actually matter.) */
559 560
560Lisp_Object 561Lisp_Object
561w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps, 562w32_menu_show (struct frame *f, int x, int y, int menuflags,
562 Lisp_Object title, const char **error) 563 Lisp_Object title, const char **error)
563{ 564{
564 int i; 565 int i;
@@ -647,14 +648,14 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
647 /* If the pane has a meaningful name, 648 /* If the pane has a meaningful name,
648 make the pane a top-level menu item 649 make the pane a top-level menu item
649 with its items as a submenu beneath it. */ 650 with its items as a submenu beneath it. */
650 if (!keymaps && strcmp (pane_string, "")) 651 if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, ""))
651 { 652 {
652 wv = make_widget_value (pane_string, NULL, true, Qnil); 653 wv = make_widget_value (pane_string, NULL, true, Qnil);
653 if (save_wv) 654 if (save_wv)
654 save_wv->next = wv; 655 save_wv->next = wv;
655 else 656 else
656 first_wv->contents = wv; 657 first_wv->contents = wv;
657 if (keymaps && !NILP (prefix)) 658 if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
658 wv->name++; 659 wv->name++;
659 wv->button_type = BUTTON_TYPE_NONE; 660 wv->button_type = BUTTON_TYPE_NONE;
660 save_wv = wv; 661 save_wv = wv;
@@ -811,10 +812,10 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
811 i += 1; 812 i += 1;
812 else 813 else
813 { 814 {
814 entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); 815 entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
815 if (menu_item_selection == i) 816 if (menu_item_selection == i)
816 { 817 {
817 if (keymaps != 0) 818 if (menuflags & MENU_KEYMAPS)
818 { 819 {
819 int j; 820 int j;
820 821
@@ -832,7 +833,7 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
832 } 833 }
833 } 834 }
834 } 835 }
835 else if (!for_click) 836 else if (!(menuflags & MENU_FOR_CLICK))
836 { 837 {
837 unblock_input (); 838 unblock_input ();
838 /* Make "Cancel" equivalent to C-g. */ 839 /* Make "Cancel" equivalent to C-g. */
diff --git a/src/w32term.c b/src/w32term.c
index 5145c840c71..213cff4f138 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -50,6 +50,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50#include "process.h" 50#include "process.h"
51#include "atimer.h" 51#include "atimer.h"
52#include "keymap.h" 52#include "keymap.h"
53#include "menu.h"
53 54
54#ifdef WINDOWSNT 55#ifdef WINDOWSNT
55#include "w32.h" /* for filename_from_utf16, filename_from_ansi */ 56#include "w32.h" /* for filename_from_utf16, filename_from_ansi */
@@ -6272,6 +6273,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
6272 terminal->frame_rehighlight_hook = w32_frame_rehighlight; 6273 terminal->frame_rehighlight_hook = w32_frame_rehighlight;
6273 terminal->frame_raise_lower_hook = w32_frame_raise_lower; 6274 terminal->frame_raise_lower_hook = w32_frame_raise_lower;
6274 terminal->fullscreen_hook = w32fullscreen_hook; 6275 terminal->fullscreen_hook = w32fullscreen_hook;
6276 terminal->menu_show_hook = w32_menu_show;
6275 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar; 6277 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
6276 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars; 6278 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
6277 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar; 6279 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
diff --git a/src/xmenu.c b/src/xmenu.c
index c167eaa8159..18793457dad 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -179,7 +179,7 @@ mouse_position_for_popup (struct frame *f, int *x, int *y)
179 179
180 unblock_input (); 180 unblock_input ();
181 181
182 /* xmenu_show expects window coordinates, not root window 182 /* x_menu_show expects window coordinates, not root window
183 coordinates. Translate. */ 183 coordinates. Translate. */
184 *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f); 184 *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
185 *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f); 185 *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
@@ -1158,16 +1158,17 @@ free_frame_menubar (struct frame *f)
1158 1158
1159#endif /* USE_X_TOOLKIT || USE_GTK */ 1159#endif /* USE_X_TOOLKIT || USE_GTK */
1160 1160
1161/* xmenu_show actually displays a menu using the panes and items in menu_items 1161/* x_menu_show actually displays a menu using the panes and items in menu_items
1162 and returns the value selected from it. 1162 and returns the value selected from it.
1163 There are two versions of xmenu_show, one for Xt and one for Xlib. 1163 There are two versions of x_menu_show, one for Xt and one for Xlib.
1164 Both assume input is blocked by the caller. */ 1164 Both assume input is blocked by the caller. */
1165 1165
1166/* F is the frame the menu is for. 1166/* F is the frame the menu is for.
1167 X and Y are the frame-relative specified position, 1167 X and Y are the frame-relative specified position,
1168 relative to the inside upper left corner of the frame F. 1168 relative to the inside upper left corner of the frame F.
1169 FOR_CLICK is true if this menu was invoked for a mouse click. 1169 Bitfield MENUFLAGS bits are:
1170 KEYMAPS is true if this menu was specified with keymaps; 1170 MENU_FOR_CLICK is set if this menu was invoked for a mouse click.
1171 MENU_KEYMAPS is set if this menu was specified with keymaps;
1171 in that case, we return a list containing the chosen item's value 1172 in that case, we return a list containing the chosen item's value
1172 and perhaps also the pane's prefix. 1173 and perhaps also the pane's prefix.
1173 TITLE is the specified menu title. 1174 TITLE is the specified menu title.
@@ -1433,8 +1434,8 @@ cleanup_widget_value_tree (void *arg)
1433} 1434}
1434 1435
1435Lisp_Object 1436Lisp_Object
1436xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, 1437x_menu_show (struct frame *f, int x, int y, int menuflags,
1437 Lisp_Object title, const char **error_name) 1438 Lisp_Object title, const char **error_name)
1438{ 1439{
1439 int i; 1440 int i;
1440 widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; 1441 widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
@@ -1519,14 +1520,14 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
1519 /* If the pane has a meaningful name, 1520 /* If the pane has a meaningful name,
1520 make the pane a top-level menu item 1521 make the pane a top-level menu item
1521 with its items as a submenu beneath it. */ 1522 with its items as a submenu beneath it. */
1522 if (!keymaps && strcmp (pane_string, "")) 1523 if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, ""))
1523 { 1524 {
1524 wv = make_widget_value (pane_string, NULL, true, Qnil); 1525 wv = make_widget_value (pane_string, NULL, true, Qnil);
1525 if (save_wv) 1526 if (save_wv)
1526 save_wv->next = wv; 1527 save_wv->next = wv;
1527 else 1528 else
1528 first_wv->contents = wv; 1529 first_wv->contents = wv;
1529 if (keymaps && !NILP (prefix)) 1530 if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
1530 wv->name++; 1531 wv->name++;
1531 wv->button_type = BUTTON_TYPE_NONE; 1532 wv->button_type = BUTTON_TYPE_NONE;
1532 save_wv = wv; 1533 save_wv = wv;
@@ -1625,7 +1626,8 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
1625 record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv); 1626 record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
1626 1627
1627 /* Actually create and show the menu until popped down. */ 1628 /* Actually create and show the menu until popped down. */
1628 create_and_show_popup_menu (f, first_wv, x, y, for_click); 1629 create_and_show_popup_menu (f, first_wv, x, y,
1630 menuflags & MENU_FOR_CLICK);
1629 1631
1630 unbind_to (specpdl_count, Qnil); 1632 unbind_to (specpdl_count, Qnil);
1631 1633
@@ -1666,7 +1668,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
1666 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); 1668 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
1667 if (menu_item_selection == aref_addr (menu_items, i)) 1669 if (menu_item_selection == aref_addr (menu_items, i))
1668 { 1670 {
1669 if (keymaps) 1671 if (menuflags & MENU_KEYMAPS)
1670 { 1672 {
1671 int j; 1673 int j;
1672 1674
@@ -1684,7 +1686,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
1684 } 1686 }
1685 } 1687 }
1686 } 1688 }
1687 else if (!for_click) 1689 else if (!(menuflags & MENU_FOR_CLICK))
1688 { 1690 {
1689 unblock_input (); 1691 unblock_input ();
1690 /* Make "Cancel" equivalent to C-g. */ 1692 /* Make "Cancel" equivalent to C-g. */
@@ -2022,7 +2024,7 @@ menu_help_callback (char const *help_string, int pane, int item)
2022 if (EQ (first_item[0], Qt)) 2024 if (EQ (first_item[0], Qt))
2023 pane_name = first_item[MENU_ITEMS_PANE_NAME]; 2025 pane_name = first_item[MENU_ITEMS_PANE_NAME];
2024 else if (EQ (first_item[0], Qquote)) 2026 else if (EQ (first_item[0], Qquote))
2025 /* This shouldn't happen, see xmenu_show. */ 2027 /* This shouldn't happen, see x_menu_show. */
2026 pane_name = empty_unibyte_string; 2028 pane_name = empty_unibyte_string;
2027 else 2029 else
2028 pane_name = first_item[MENU_ITEMS_ITEM_NAME]; 2030 pane_name = first_item[MENU_ITEMS_ITEM_NAME];
@@ -2064,8 +2066,8 @@ pop_down_menu (Lisp_Object arg)
2064 2066
2065 2067
2066Lisp_Object 2068Lisp_Object
2067xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, 2069x_menu_show (struct frame *f, int x, int y, int menuflags,
2068 Lisp_Object title, const char **error_name) 2070 Lisp_Object title, const char **error_name)
2069{ 2071{
2070 Window root; 2072 Window root;
2071 XMenu *menu; 2073 XMenu *menu;
@@ -2140,7 +2142,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
2140 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); 2142 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
2141 pane_string = (NILP (pane_name) 2143 pane_string = (NILP (pane_name)
2142 ? "" : SSDATA (pane_name)); 2144 ? "" : SSDATA (pane_name));
2143 if (keymaps && !NILP (prefix)) 2145 if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
2144 pane_string++; 2146 pane_string++;
2145 2147
2146 lpane = XMenuAddPane (FRAME_X_DISPLAY (f), menu, pane_string, TRUE); 2148 lpane = XMenuAddPane (FRAME_X_DISPLAY (f), menu, pane_string, TRUE);
@@ -2263,7 +2265,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
2263 if (ulx < 0) x -= ulx; 2265 if (ulx < 0) x -= ulx;
2264 if (uly < 0) y -= uly; 2266 if (uly < 0) y -= uly;
2265 2267
2266 if (! for_click) 2268 if (!(menuflags & MENU_FOR_CLICK))
2267 { 2269 {
2268 /* If position was not given by a mouse click, adjust so upper left 2270 /* If position was not given by a mouse click, adjust so upper left
2269 corner of the menu as a whole ends up at given coordinates. This 2271 corner of the menu as a whole ends up at given coordinates. This
@@ -2317,7 +2319,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
2317 { 2319 {
2318 entry 2320 entry
2319 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); 2321 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
2320 if (keymaps) 2322 if (menuflags & MENU_KEYMAPS)
2321 { 2323 {
2322 entry = list1 (entry); 2324 entry = list1 (entry);
2323 if (!NILP (pane_prefix)) 2325 if (!NILP (pane_prefix))
@@ -2339,7 +2341,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
2339 case XM_NO_SELECT: 2341 case XM_NO_SELECT:
2340 /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means 2342 /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
2341 the menu was invoked with a mouse event as POSITION). */ 2343 the menu was invoked with a mouse event as POSITION). */
2342 if (! for_click) 2344 if (!(menuflags & MENU_FOR_CLICK))
2343 { 2345 {
2344 unblock_input (); 2346 unblock_input ();
2345 Fsignal (Qquit, Qnil); 2347 Fsignal (Qquit, Qnil);
diff --git a/src/xterm.c b/src/xterm.c
index c4b8db35f31..df4ab349104 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -75,6 +75,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
75#include "xsettings.h" 75#include "xsettings.h"
76#include "xgselect.h" 76#include "xgselect.h"
77#include "sysselect.h" 77#include "sysselect.h"
78#include "menu.h"
78 79
79#ifdef USE_X_TOOLKIT 80#ifdef USE_X_TOOLKIT
80#include <X11/Shell.h> 81#include <X11/Shell.h>
@@ -10531,6 +10532,7 @@ x_create_terminal (struct x_display_info *dpyinfo)
10531 terminal->frame_rehighlight_hook = XTframe_rehighlight; 10532 terminal->frame_rehighlight_hook = XTframe_rehighlight;
10532 terminal->frame_raise_lower_hook = XTframe_raise_lower; 10533 terminal->frame_raise_lower_hook = XTframe_raise_lower;
10533 terminal->fullscreen_hook = XTfullscreen_hook; 10534 terminal->fullscreen_hook = XTfullscreen_hook;
10535 terminal->menu_show_hook = x_menu_show;
10534 terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; 10536 terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
10535 terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars; 10537 terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
10536 terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar; 10538 terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;