Commit cfd794af authored by Dmitry Antipov's avatar Dmitry Antipov

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.
parent 39ec0314
2014-06-04 Dmitry Antipov <dmantipov@yandex.ru>
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.
2014-06-03 Juanma Barranquero <lekktu@gmail.com>
* w32heap.c (DUMPED_HEAP_SIZE) [!_WIN64]: Reduce to 11 MB.
......
......@@ -1161,9 +1161,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
Lisp_Object selection = Qnil;
struct frame *f = NULL;
Lisp_Object x, y, window;
bool keymaps = 0;
bool for_click = 0;
bool kbd_menu_navigation = 0;
int menuflags = 0;
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
struct gcpro gcpro1;
......@@ -1193,12 +1191,12 @@ no quit occurs and `x-popup-menu' returns nil. */)
}
else
{
for_click = 1;
menuflags |= MENU_FOR_CLICK;
tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
window = Fcar (tem); /* POSN_WINDOW (tem) */
tem2 = Fcar (Fcdr (tem)); /* POSN_POSN (tem) */
/* The kbd_menu_navigation flag is set when the menu was
invoked by F10, which probably means they have no
/* The MENU_KBD_NAVIGATION field is set when the menu
was invoked by F10, which probably means they have no
mouse. In that case, we let them switch between
top-level menu-bar menus by using C-f/C-b and
horizontal arrow keys, since they cannot click the
......@@ -1211,7 +1209,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
if (!EQ (POSN_POSN (last_nonmenu_event),
POSN_POSN (position))
&& CONSP (tem2) && EQ (Fcar (tem2), Qmenu_bar))
kbd_menu_navigation = 1;
menuflags |= MENU_KBD_NAVIGATION;
tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
x = Fcar (tem);
y = Fcdr (tem);
......@@ -1340,7 +1338,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
if (!NILP (prompt) && menu_items_n_panes >= 0)
ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt);
keymaps = 1;
menuflags |= MENU_KEYMAPS;
}
else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
{
......@@ -1373,7 +1371,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
if (!NILP (title) && menu_items_n_panes >= 0)
ASET (menu_items, MENU_ITEMS_PANE_NAME, title);
keymaps = 1;
menuflags |= MENU_KEYMAPS;
SAFE_FREE ();
}
......@@ -1385,7 +1383,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
list_of_panes (Fcdr (menu));
keymaps = 0;
menuflags &= ~MENU_KEYMAPS;
}
unbind_to (specpdl_count, Qnil);
......@@ -1416,39 +1414,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
#endif
/* Display them in a menu. */
/* FIXME: Use a terminal hook! */
#if defined HAVE_NTGUI
if (FRAME_W32_P (f))
selection = w32_menu_show (f, xpos, ypos, for_click,
keymaps, title, &error_name);
else
#endif
#if defined HAVE_NS
if (FRAME_NS_P (f))
selection = ns_menu_show (f, xpos, ypos, for_click,
keymaps, title, &error_name);
else
#endif
#if (defined (HAVE_X_WINDOWS) || defined (MSDOS))
if (FRAME_X_P (f) || FRAME_MSDOS_P (f))
selection = xmenu_show (f, xpos, ypos, for_click,
keymaps, title, &error_name);
else
#endif
#ifndef MSDOS
if (FRAME_TERMCAP_P (f))
{
ptrdiff_t count1 = SPECPDL_INDEX ();
/* Avoid crashes if, e.g., another client will connect while we
are in a menu. */
temporarily_switch_to_single_kboard (f);
selection = tty_menu_show (f, xpos, ypos, for_click, keymaps, title,
kbd_menu_navigation, &error_name);
unbind_to (count1, Qnil);
}
#endif
selection = FRAME_TERMINAL (f)->menu_show_hook (f, xpos, ypos, menuflags,
title, &error_name);
#ifdef HAVE_NS
unbind_to (specpdl_count, Qnil);
......
......@@ -26,6 +26,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
extern Lisp_Object Qunsupported__w32_dialog;
#endif
/* Bit fields used by terminal-specific menu_show_hook. */
enum {
MENU_KEYMAPS = 0x1,
MENU_FOR_CLICK = 0x2,
MENU_KBD_NAVIGATION = 0x4
};
extern void x_set_menu_bar_lines (struct frame *f,
Lisp_Object value,
Lisp_Object oldval);
......@@ -49,14 +57,19 @@ extern widget_value *digest_single_submenu (int, int, bool);
#ifdef HAVE_X_WINDOWS
extern void mouse_position_for_popup (struct frame *f, int *x, int *y);
#endif
extern Lisp_Object w32_menu_show (struct frame *, int, int, int, int,
#if defined (HAVE_X_WINDOWS) || defined (MSDOS)
extern Lisp_Object x_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
#endif
#ifdef HAVE_NTGUI
extern Lisp_Object w32_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
extern Lisp_Object ns_menu_show (struct frame *, int, int, bool, bool,
#endif
#ifdef HAVE_NS
extern Lisp_Object ns_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
extern Lisp_Object xmenu_show (struct frame *, int, int, bool, bool,
Lisp_Object, const char **);
extern Lisp_Object tty_menu_show (struct frame *, int, int, bool, bool,
Lisp_Object, bool, const char **);
#endif
extern Lisp_Object tty_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
extern ptrdiff_t menu_item_width (const unsigned char *);
#endif /* MENU_H */
......@@ -1863,6 +1863,7 @@ initialize_msdos_display (struct terminal *term)
term->update_end_hook = IT_update_end;
term->frame_up_to_date_hook = IT_frame_up_to_date;
term->mouse_position_hook = 0; /* set later by dos_ttraw */
term->menu_show_hook = x_menu_show;
term->frame_rehighlight_hook = 0;
term->frame_raise_lower_hook = 0;
term->set_vertical_scroll_bar_hook = 0;
......
......@@ -812,7 +812,7 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
========================================================================== */
Lisp_Object
ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
ns_menu_show (struct frame *f, int x, int y, int menuflags,
Lisp_Object title, const char **error)
{
EmacsMenu *pmenu;
......@@ -820,6 +820,7 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
Lisp_Object tem;
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
widget_value *wv, *first_wv = 0;
bool keymaps = (menuflags & MENU_KEYMAPS);
block_input ();
......
......@@ -54,7 +54,7 @@ Updated by Christian Limpach (chris@nice.ch)
#include "termhooks.h"
#include "termchar.h"
#include "menu.h"
#include "window.h"
#include "keyboard.h"
#include "buffer.h"
......@@ -4164,6 +4164,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
terminal->frame_rehighlight_hook = ns_frame_rehighlight;
terminal->frame_raise_lower_hook = ns_frame_raise_lower;
terminal->fullscreen_hook = ns_fullscreen_hook;
terminal->menu_show_hook = ns_menu_show;
terminal->set_vertical_scroll_bar_hook = ns_set_vertical_scroll_bar;
terminal->condemn_scroll_bars_hook = ns_condemn_scroll_bars;
terminal->redeem_scroll_bar_hook = ns_redeem_scroll_bar;
......
......@@ -3583,8 +3583,8 @@ tty_menu_new_item_coords (struct frame *f, int which, int *x, int *y)
}
Lisp_Object
tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
Lisp_Object title, bool kbd_navigation, const char **error_name)
tty_menu_show (struct frame *f, int x, int y, int menuflags,
Lisp_Object title, const char **error_name)
{
tty_menu *menu;
int pane, selidx, lpane, status;
......@@ -3621,6 +3621,10 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
menu functions pointers to the contents of strings. */
specpdl_count = inhibit_garbage_collection ();
/* Avoid crashes if, e.g., another client will connect while we
are in a menu. */
temporarily_switch_to_single_kboard (f);
/* Adjust coordinates to be root-window-relative. */
item_x = x += f->left_pos;
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,
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
pane_string = (NILP (pane_name)
? "" : SSDATA (pane_name));
if (keymaps && !NILP (prefix))
if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
pane_string++;
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,
specbind (Qoverriding_terminal_local_map,
Fsymbol_value (Qtty_menu_navigation_map));
status = tty_menu_activate (menu, &pane, &selidx, x, y, &datap,
tty_menu_help_callback, kbd_navigation);
tty_menu_help_callback,
menuflags & MENU_KBD_NAVIGATION);
entry = pane_prefix = Qnil;
switch (status)
......@@ -3808,7 +3813,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
{
entry
= AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
if (keymaps != 0)
if (menuflags & MENU_KEYMAPS)
{
entry = Fcons (entry, Qnil);
if (!NILP (pane_prefix))
......@@ -3841,7 +3846,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
Ftop_level ();
/* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
the menu was invoked with a mouse event as POSITION). */
if (! for_click)
if (!(menuflags & MENU_FOR_CLICK))
Fsignal (Qquit, Qnil);
break;
}
......@@ -3922,6 +3927,7 @@ clear_tty_hooks (struct terminal *terminal)
terminal->frame_rehighlight_hook = 0;
terminal->frame_raise_lower_hook = 0;
terminal->fullscreen_hook = 0;
terminal->menu_show_hook = 0;
terminal->set_vertical_scroll_bar_hook = 0;
terminal->condemn_scroll_bars_hook = 0;
terminal->redeem_scroll_bar_hook = 0;
......@@ -3953,6 +3959,7 @@ set_tty_hooks (struct terminal *terminal)
terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes;
terminal->set_terminal_modes_hook = &tty_set_terminal_modes;
terminal->update_end_hook = &tty_update_end;
terminal->menu_show_hook = &tty_menu_show;
terminal->set_terminal_window_hook = &tty_set_terminal_window;
terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
terminal->delete_frame_hook = &tty_free_frame_resources;
......
......@@ -478,7 +478,10 @@ struct terminal
may do something OS dependent, like extended window manager hints on X11. */
void (*fullscreen_hook) (struct frame *f);
/* This hook is called to display menus. */
Lisp_Object (*menu_show_hook) (struct frame *f, int x, int y, int menuflags,
Lisp_Object title, const char **error_name);
/* Scroll bar hooks. */
/* The representation of scroll bars is determined by the code which
......
......@@ -549,8 +549,9 @@ free_frame_menubar (struct frame *f)
/* F is the frame the menu is for.
X and Y are the frame-relative specified position,
relative to the inside upper left corner of the frame F.
FOR_CLICK is nonzero if this menu was invoked for a mouse click.
KEYMAPS is 1 if this menu was specified with keymaps;
Bitfield MENUFLAGS bits are:
MENU_FOR_CLICK is set if this menu was invoked for a mouse click.
MENU_KEYMAPS is set if this menu was specified with keymaps;
in that case, we return a list containing the chosen item's value
and perhaps also the pane's prefix.
TITLE is the specified menu title.
......@@ -558,7 +559,7 @@ free_frame_menubar (struct frame *f)
(We return nil on failure, but the value doesn't actually matter.) */
Lisp_Object
w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
w32_menu_show (struct frame *f, int x, int y, int menuflags,
Lisp_Object title, const char **error)
{
int i;
......@@ -647,14 +648,14 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
/* If the pane has a meaningful name,
make the pane a top-level menu item
with its items as a submenu beneath it. */
if (!keymaps && strcmp (pane_string, ""))
if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, ""))
{
wv = make_widget_value (pane_string, NULL, true, Qnil);
if (save_wv)
save_wv->next = wv;
else
first_wv->contents = wv;
if (keymaps && !NILP (prefix))
if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
wv->name++;
wv->button_type = BUTTON_TYPE_NONE;
save_wv = wv;
......@@ -811,10 +812,10 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
i += 1;
else
{
entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
if (menu_item_selection == i)
{
if (keymaps != 0)
if (menuflags & MENU_KEYMAPS)
{
int j;
......@@ -832,7 +833,7 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
}
}
}
else if (!for_click)
else if (!(menuflags & MENU_FOR_CLICK))
{
unblock_input ();
/* Make "Cancel" equivalent to C-g. */
......
......@@ -50,6 +50,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "process.h"
#include "atimer.h"
#include "keymap.h"
#include "menu.h"
#ifdef WINDOWSNT
#include "w32.h" /* for filename_from_utf16, filename_from_ansi */
......@@ -6272,6 +6273,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
terminal->frame_rehighlight_hook = w32_frame_rehighlight;
terminal->frame_raise_lower_hook = w32_frame_raise_lower;
terminal->fullscreen_hook = w32fullscreen_hook;
terminal->menu_show_hook = w32_menu_show;
terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
......
......@@ -179,7 +179,7 @@ mouse_position_for_popup (struct frame *f, int *x, int *y)
unblock_input ();
/* xmenu_show expects window coordinates, not root window
/* x_menu_show expects window coordinates, not root window
coordinates. Translate. */
*x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
*y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
......@@ -1158,16 +1158,17 @@ free_frame_menubar (struct frame *f)
#endif /* USE_X_TOOLKIT || USE_GTK */
/* xmenu_show actually displays a menu using the panes and items in menu_items
/* x_menu_show actually displays a menu using the panes and items in menu_items
and returns the value selected from it.
There are two versions of xmenu_show, one for Xt and one for Xlib.
There are two versions of x_menu_show, one for Xt and one for Xlib.
Both assume input is blocked by the caller. */
/* F is the frame the menu is for.
X and Y are the frame-relative specified position,
relative to the inside upper left corner of the frame F.
FOR_CLICK is true if this menu was invoked for a mouse click.
KEYMAPS is true if this menu was specified with keymaps;
Bitfield MENUFLAGS bits are:
MENU_FOR_CLICK is set if this menu was invoked for a mouse click.
MENU_KEYMAPS is set if this menu was specified with keymaps;
in that case, we return a list containing the chosen item's value
and perhaps also the pane's prefix.
TITLE is the specified menu title.
......@@ -1433,8 +1434,8 @@ cleanup_widget_value_tree (void *arg)
}
Lisp_Object
xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
Lisp_Object title, const char **error_name)
x_menu_show (struct frame *f, int x, int y, int menuflags,
Lisp_Object title, const char **error_name)
{
int i;
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,
/* If the pane has a meaningful name,
make the pane a top-level menu item
with its items as a submenu beneath it. */
if (!keymaps && strcmp (pane_string, ""))
if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, ""))
{
wv = make_widget_value (pane_string, NULL, true, Qnil);
if (save_wv)
save_wv->next = wv;
else
first_wv->contents = wv;
if (keymaps && !NILP (prefix))
if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
wv->name++;
wv->button_type = BUTTON_TYPE_NONE;
save_wv = wv;
......@@ -1625,7 +1626,8 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
/* Actually create and show the menu until popped down. */
create_and_show_popup_menu (f, first_wv, x, y, for_click);
create_and_show_popup_menu (f, first_wv, x, y,
menuflags & MENU_FOR_CLICK);
unbind_to (specpdl_count, Qnil);
......@@ -1666,7 +1668,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
= AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
if (menu_item_selection == aref_addr (menu_items, i))
{
if (keymaps)
if (menuflags & MENU_KEYMAPS)
{
int j;
......@@ -1684,7 +1686,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
}
}
}
else if (!for_click)
else if (!(menuflags & MENU_FOR_CLICK))
{
unblock_input ();
/* Make "Cancel" equivalent to C-g. */
......@@ -2022,7 +2024,7 @@ menu_help_callback (char const *help_string, int pane, int item)
if (EQ (first_item[0], Qt))
pane_name = first_item[MENU_ITEMS_PANE_NAME];
else if (EQ (first_item[0], Qquote))
/* This shouldn't happen, see xmenu_show. */
/* This shouldn't happen, see x_menu_show. */
pane_name = empty_unibyte_string;
else
pane_name = first_item[MENU_ITEMS_ITEM_NAME];
......@@ -2064,8 +2066,8 @@ pop_down_menu (Lisp_Object arg)
Lisp_Object
xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
Lisp_Object title, const char **error_name)
x_menu_show (struct frame *f, int x, int y, int menuflags,
Lisp_Object title, const char **error_name)
{
Window root;
XMenu *menu;
......@@ -2140,7 +2142,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
pane_string = (NILP (pane_name)
? "" : SSDATA (pane_name));
if (keymaps && !NILP (prefix))
if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
pane_string++;
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,
if (ulx < 0) x -= ulx;
if (uly < 0) y -= uly;
if (! for_click)
if (!(menuflags & MENU_FOR_CLICK))
{
/* If position was not given by a mouse click, adjust so upper left
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,
{
entry
= AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
if (keymaps)
if (menuflags & MENU_KEYMAPS)
{
entry = list1 (entry);
if (!NILP (pane_prefix))
......@@ -2339,7 +2341,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
case XM_NO_SELECT:
/* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
the menu was invoked with a mouse event as POSITION). */
if (! for_click)
if (!(menuflags & MENU_FOR_CLICK))
{
unblock_input ();
Fsignal (Qquit, Qnil);
......
......@@ -75,6 +75,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "xsettings.h"
#include "xgselect.h"
#include "sysselect.h"
#include "menu.h"
#ifdef USE_X_TOOLKIT
#include <X11/Shell.h>
......@@ -10531,6 +10532,7 @@ x_create_terminal (struct x_display_info *dpyinfo)
terminal->frame_rehighlight_hook = XTframe_rehighlight;
terminal->frame_raise_lower_hook = XTframe_raise_lower;
terminal->fullscreen_hook = XTfullscreen_hook;
terminal->menu_show_hook = x_menu_show;
terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment