Commit ef7417fd authored by Stefan Monnier's avatar Stefan Monnier

* menu.c (Fx_popup_menu): Consolidate versions from xmenu.c,

w32menu.c, and nsmenu.m.
Simplify the obsolete case where position is nil.
(cleanup_popup_menu): New function, moved from nsmenu.m.
(struct skp): Remove slot `notreal'.
(single_keymap_panes, keymap_panes): Remove arg `notreal' and adjust callers.
(single_menu_item): Adjust call to parse_menu_item.
(syms_of_menu): Defsubr x-popup-menu.
* menu.h (Vmenu_updating_frame): Consolidate declarations from *menu.c.
(keymap_panes): Don't export any more.
(mouse_position_for_popup, w32_menu_show, ns_menu_show, xmenu_show): Declare.
* keyboard.c (parse_menu_item): Remove arg `notreal'.
(menu_bar_item, read_char_minibuf_menu_prompt): Adjust callers.
* keyboard.h (parse_menu_item): Update declaration.
* xmenu.c (Fx_popup_menu): Remove.
(syms_of_xmenu): Don't defsubr x-popup-menu.
* w32menu.c (Fx_popup_menu): Remove.
(syms_of_w32menu): Don't defsubr x-popup-menu.
* nsmenu.m (cleanup_popup_menu): Remove.
(ns_menu_show): Rename from ns_popup_menu and remove all the code
moved to menu.c's Fx_popup_menu.
(Fx_popup_menu): Remove.
(syms_of_nsmenu): Don't defsubr x-popup-menu, and don't initialize
menu_items (it's done in menu.c already).
parent 4359a806
2009-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
* menu.c (Fx_popup_menu): Consolidate versions from xmenu.c,
w32menu.c, and nsmenu.m.
Simplify the obsolete case where position is nil.
(cleanup_popup_menu): New function, moved from nsmenu.m.
(struct skp): Remove slot `notreal'.
(single_keymap_panes, keymap_panes): Remove arg `notreal' and
adjust callers.
(single_menu_item): Adjust call to parse_menu_item.
(syms_of_menu): Defsubr x-popup-menu.
* menu.h (Vmenu_updating_frame): Consolidate declarations from *menu.c.
(keymap_panes): Don't export any more.
(mouse_position_for_popup, w32_menu_show, ns_menu_show)
(xmenu_show): Declare.
* keyboard.c (parse_menu_item): Remove arg `notreal'.
(menu_bar_item, read_char_minibuf_menu_prompt): Adjust callers.
* keyboard.h (parse_menu_item): Update declaration.
* xmenu.c (Fx_popup_menu): Remove.
(syms_of_xmenu): Don't defsubr x-popup-menu.
* w32menu.c (Fx_popup_menu): Remove.
(syms_of_w32menu): Don't defsubr x-popup-menu.
* nsmenu.m (cleanup_popup_menu): Remove.
(ns_menu_show): Rename from ns_popup_menu and remove all the code
moved to menu.c's Fx_popup_menu.
(Fx_popup_menu): Remove.
(syms_of_nsmenu): Don't defsubr x-popup-menu, and don't initialize
menu_items (it's done in menu.c already).
2009-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
* keyboard.c (parse_menu_item): Handle `notreal' a bit earlier.
......
......@@ -7797,7 +7797,7 @@ menu_bar_item (key, item, dummy1, dummy2)
parse_menu_item, so that if it turns out it wasn't a menu item,
it still correctly hides any further menu item. */
GCPRO1 (key);
i = parse_menu_item (item, 0, 1);
i = parse_menu_item (item, 1);
UNGCPRO;
if (!i)
return;
......@@ -7865,8 +7865,6 @@ menu_item_eval_property (sexpr)
/* This function parses a menu item and leaves the result in the
vector item_properties.
ITEM is a key binding, a possible menu item.
If NOTREAL is nonzero, only check for equivalent key bindings, don't
evaluate dynamic expressions in the menu item.
INMENUBAR is > 0 when this is considered for an entry in a menu bar
top level.
INMENUBAR is < 0 when this is considered for an entry in a keyboard menu.
......@@ -7874,9 +7872,9 @@ menu_item_eval_property (sexpr)
otherwise. */
int
parse_menu_item (item, notreal, inmenubar)
parse_menu_item (item, inmenubar)
Lisp_Object item;
int notreal, inmenubar;
int inmenubar;
{
Lisp_Object def, tem, item_string, start;
Lisp_Object filter;
......@@ -7966,7 +7964,7 @@ parse_menu_item (item, notreal, inmenubar)
else
ASET (item_properties, ITEM_PROPERTY_ENABLE, XCAR (item));
}
else if (EQ (tem, QCvisible) && !notreal)
else if (EQ (tem, QCvisible))
{
/* If got a visible property and that evaluates to nil
then ignore this item. */
......@@ -8015,7 +8013,7 @@ parse_menu_item (item, notreal, inmenubar)
/* If item string is not a string, evaluate it to get string.
If we don't get a string, skip this item. */
item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
if (!(STRINGP (item_string) || notreal))
if (!(STRINGP (item_string)))
{
item_string = menu_item_eval_property (item_string);
if (!STRINGP (item_string))
......@@ -8037,10 +8035,7 @@ parse_menu_item (item, notreal, inmenubar)
tem = AREF (item_properties, ITEM_PROPERTY_ENABLE);
if (!EQ (tem, Qt))
{
if (notreal)
tem = Qt;
else
tem = menu_item_eval_property (tem);
tem = menu_item_eval_property (tem);
if (inmenubar && NILP (tem))
return 0; /* Ignore disabled items in menu bar. */
ASET (item_properties, ITEM_PROPERTY_ENABLE, tem);
......@@ -8068,11 +8063,6 @@ parse_menu_item (item, notreal, inmenubar)
if (inmenubar > 0)
return 1;
/* If we only want to precompute equivalent key bindings (which we
don't even do any more anyway), stop here. */
if (notreal)
return 1;
{ /* This is a command. See if there is an equivalent key binding. */
Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
......@@ -8763,7 +8753,7 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
}
/* Ignore the element if it has no prompt string. */
if (INTEGERP (event) && parse_menu_item (elt, 0, -1))
if (INTEGERP (event) && parse_menu_item (elt, -1))
{
/* 1 if the char to type matches the string. */
int char_matches;
......
......@@ -443,7 +443,7 @@ extern Lisp_Object Vfunction_key_map;
/* Keymap of key translations that can override keymaps. */
extern Lisp_Object Vkey_translation_map;
extern int parse_menu_item P_ ((Lisp_Object, int, int));
extern int parse_menu_item (Lisp_Object, int);
extern void echo_now P_ ((void));
extern void init_kboard P_ ((KBOARD *));
......
This diff is collapsed.
......@@ -19,12 +19,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef MENU_H
#define MENU_H
extern Lisp_Object Vmenu_updating_frame;
extern void init_menu_items P_ ((void));
extern void finish_menu_items P_ ((void));
extern void discard_menu_items P_ ((void));
extern void save_menu_items P_ ((void));
extern int parse_single_submenu P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
extern void keymap_panes P_ ((Lisp_Object *, int, int));
extern void list_of_panes P_ ((Lisp_Object));
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
extern void free_menubar_widget_value_tree P_ ((widget_value *));
......@@ -33,6 +34,16 @@ extern void find_and_call_menu_selection P_ ((FRAME_PTR, int,
Lisp_Object, void *));
#endif
#ifdef HAVE_X_WINDOWS
extern void mouse_position_for_popup (FRAME_PTR f, int *x, int *y);
#endif
extern Lisp_Object w32_menu_show (FRAME_PTR, int, int, int, int,
Lisp_Object, char **);
extern Lisp_Object ns_menu_show (FRAME_PTR, int, int, int, int,
Lisp_Object, char **);
extern Lisp_Object xmenu_show (FRAME_PTR, int, int, int, int,
Lisp_Object, char **, EMACS_UINT);
#endif /* MENU_H */
/* arch-tag: c32b2778-724d-4e85-81d7-45f98530a988
......
......@@ -36,6 +36,7 @@
#include "nsterm.h"
#include "termhooks.h"
#include "keyboard.h"
#include "menu.h"
#define NSMENUPROFILE 0
......@@ -63,8 +64,6 @@
extern Lisp_Object Qundefined, Qmenu_enable, Qmenu_bar_update_hook;
extern Lisp_Object QCtoggle, QCradio;
extern Lisp_Object Vmenu_updating_frame;
Lisp_Object Qdebug_on_next_call;
extern Lisp_Object Voverriding_local_map, Voverriding_local_map_menu_flag,
Qoverriding_local_map, Qoverriding_terminal_local_map;
......@@ -771,188 +770,17 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
========================================================================== */
static Lisp_Object
cleanup_popup_menu (Lisp_Object arg)
{
discard_menu_items ();
return Qnil;
}
static Lisp_Object
ns_popup_menu (Lisp_Object position, Lisp_Object menu)
Lisp_Object
ns_menu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
Lisp_Object title, char **error)
{
EmacsMenu *pmenu;
struct frame *f = NULL;
NSPoint p;
Lisp_Object window, x, y, tem, keymap, title;
struct gcpro gcpro1;
int specpdl_count = SPECPDL_INDEX (), specpdl_count2;
char *error_name = NULL;
int keymaps = 0;
Lisp_Object window, tem, keymap;
int specpdl_count = SPECPDL_INDEX ();
widget_value *wv, *first_wv = 0;
NSTRACE (ns_popup_menu);
if (!NILP (position))
{
check_ns ();
if (EQ (position, Qt)
|| (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
|| EQ (XCAR (position), Qtool_bar))))
{
/* Use the mouse's current position. */
struct frame *new_f = SELECTED_FRAME ();
if (FRAME_TERMINAL (new_f)->mouse_position_hook)
(*FRAME_TERMINAL (new_f)->mouse_position_hook)
(&new_f, 0, 0, 0, &x, &y, 0);
if (new_f != 0)
XSETFRAME (window, new_f);
else
{
window = selected_window;
x = make_number (0);
y = make_number (0);
}
}
else
{
CHECK_CONS (position);
tem = Fcar (position);
if (XTYPE (tem) == Lisp_Cons)
{
window = Fcar (Fcdr (position));
x = Fcar (tem);
y = Fcar (Fcdr (tem));
}
else
{
tem = Fcar (Fcdr (position));
window = Fcar (tem);
tem = Fcar (Fcdr (Fcdr (tem)));
x = Fcar (tem);
y = Fcdr (tem);
}
}
CHECK_NUMBER (x);
CHECK_NUMBER (y);
if (FRAMEP (window))
{
f = XFRAME (window);
p.x = 0;
p.y = 0;
}
else
{
struct window *win = XWINDOW (window);
CHECK_LIVE_WINDOW (window);
f = XFRAME (WINDOW_FRAME (win));
p.x = FRAME_COLUMN_WIDTH (f) * WINDOW_LEFT_EDGE_COL (win);
p.y = FRAME_LINE_HEIGHT (f) * WINDOW_TOP_EDGE_LINE (win);
}
p.x += XINT (x); p.y += XINT (y);
XSETFRAME (Vmenu_updating_frame, f);
}
else
{ /* no position given */
/* FIXME: if called during dump, we need to stop precomputation of
key equivalents (see below) because the keydefs in ns-win.el have
not been loaded yet. */
if (noninteractive)
return Qnil;
Vmenu_updating_frame = Qnil;
}
/* now parse the lisp menus */
record_unwind_protect (unuse_menu_items, Qnil);
title = Qnil;
GCPRO1 (title);
/* Decode the menu items from what was specified. */
keymap = get_keymap (menu, 0, 0);
if (CONSP (keymap))
{
/* We were given a keymap. Extract menu info from the keymap. */
Lisp_Object prompt;
/* Extract the detailed info to make one pane. */
keymap_panes (&menu, 1, NILP (position));
/* Search for a string appearing directly as an element of the keymap.
That string is the title of the menu. */
prompt = Fkeymap_prompt (keymap);
title = NILP (prompt) ? build_string ("Select") : prompt;
/* Make that be the pane title of the first pane. */
if (!NILP (prompt) && menu_items_n_panes >= 0)
XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt;
keymaps = 1;
}
else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
{
/* We were given a list of keymaps. */
int nmaps = XFASTINT (Flength (menu));
Lisp_Object *maps
= (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
int i;
title = Qnil;
/* The first keymap that has a prompt string
supplies the menu title. */
for (tem = menu, i = 0; CONSP (tem); tem = XCDR (tem))
{
Lisp_Object prompt;
maps[i++] = keymap = get_keymap (XCAR (tem), 1, 0);
prompt = Fkeymap_prompt (keymap);
if (NILP (title) && !NILP (prompt))
title = prompt;
}
/* Extract the detailed info to make one pane. */
keymap_panes (maps, nmaps, NILP (position));
/* Make the title be the pane title of the first pane. */
if (!NILP (title) && menu_items_n_panes >= 0)
XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title;
keymaps = 1;
}
else
{
/* We were given an old-fashioned menu. */
title = Fcar (menu);
CHECK_STRING (title);
list_of_panes (Fcdr (menu));
keymaps = 0;
}
unbind_to (specpdl_count, Qnil);
/* If no position given, that was a signal to just precompute and cache
key equivalents, which was a side-effect of what we just did. */
if (NILP (position))
{
discard_menu_items ();
UNGCPRO;
return Qnil;
}
record_unwind_protect (cleanup_popup_menu, Qnil);
BLOCK_INPUT;
p.x = x; p.y = y;
/* now parse stage 2 as in ns_update_menubar */
wv = xmalloc_widget_value ();
......@@ -963,8 +791,6 @@ key equivalents (see below) because the keydefs in ns-win.el have
wv->help = Qnil;
first_wv = wv;
specpdl_count2 = SPECPDL_INDEX ();
#if 0
/* FIXME: a couple of one-line differences prevent reuse */
wv = digest_single_submenu (0, menu_items_used, Qnil);
......@@ -1150,25 +976,17 @@ key equivalents (see below) because the keydefs in ns-win.el have
[NSString stringWithUTF8String: SDATA (title)]];
[pmenu fillWithWidgetValue: first_wv->contents];
free_menubar_widget_value_tree (first_wv);
unbind_to (specpdl_count2, Qnil);
unbind_to (specpdl_count, Qnil);
popup_activated_flag = 1;
tem = [pmenu runMenuAt: p forFrame: f keymaps: keymaps];
popup_activated_flag = 0;
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
UNBLOCK_INPUT;
discard_menu_items ();
unbind_to (specpdl_count, Qnil);
UNGCPRO;
if (error_name) error (error_name);
return tem;
}
/* ==========================================================================
Toolbar: externally-called functions
......@@ -1931,46 +1749,6 @@ - (Lisp_Object)runDialogAt: (NSPoint)p
}
DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
doc: /* Pop up a deck-of-cards menu and return user's selection.
POSITION is a position specification. This is either a mouse button event
or a list ((XOFFSET YOFFSET) WINDOW)
where XOFFSET and YOFFSET are positions in pixels from the top left
corner of WINDOW. (WINDOW may be a window or a frame object.)
This controls the position of the top left of the menu as a whole.
If POSITION is t, it means to use the current mouse position.
MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
The menu items come from key bindings that have a menu string as well as
a definition; actually, the \"definition\" in such a key binding looks like
\(STRING . REAL-DEFINITION). To give the menu a title, put a string into
the keymap as a top-level element.
If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
Otherwise, REAL-DEFINITION should be a valid key binding definition.
You can also use a list of keymaps as MENU.
Then each keymap makes a separate pane.
When MENU is a keymap or a list of keymaps, the return value is the
list of events corresponding to the user's choice. Note that
`x-popup-menu' does not actually execute the command bound to that
sequence of events.
Alternatively, you can specify a menu of multiple panes
with a list of the form (TITLE PANE1 PANE2...),
where each pane is a list of form (TITLE ITEM1 ITEM2...).
Each ITEM is normally a cons cell (STRING . VALUE);
but a string can appear as an item--that makes a nonselectable line
in the menu.
With this form of menu, the return value is VALUE from the chosen item. */)
(position, menu)
Lisp_Object position, menu;
{
return ns_popup_menu (position, menu);
}
DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
doc: /* Pop up a dialog box and return user's selection.
POSITION specifies which frame to use.
......@@ -2016,12 +1794,9 @@ Each ITEM is a cons cell (STRING . VALUE).
void
syms_of_nsmenu ()
{
defsubr (&Sx_popup_menu);
defsubr (&Sx_popup_dialog);
defsubr (&Sns_reset_menu);
defsubr (&Smenu_or_popup_active_p);
staticpro (&menu_items);
menu_items = Qnil;
Qdebug_on_next_call = intern ("debug-on-next-call");
staticpro (&Qdebug_on_next_call);
......
......@@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "charset.h"
#include "character.h"
#include "coding.h"
#include "menu.h"
/* This may include sys/types.h, and that somehow loses
if this is not done before the other system files. */
......@@ -78,8 +79,6 @@ AppendMenuW_Proc unicode_append_menu = NULL;
Lisp_Object Qdebug_on_next_call;
extern Lisp_Object Vmenu_updating_frame;
extern Lisp_Object Qmenu_bar;
extern Lisp_Object QCtoggle, QCradio;
......@@ -99,8 +98,6 @@ static Lisp_Object w32_dialog_show P_ ((FRAME_PTR, int, Lisp_Object, char**));
static int is_simple_dialog P_ ((Lisp_Object));
static Lisp_Object simple_dialog_show P_ ((FRAME_PTR, Lisp_Object, Lisp_Object));
#endif
static Lisp_Object w32_menu_show P_ ((FRAME_PTR, int, int, int, int,
Lisp_Object, char **));
void w32_free_menu_strings P_((HWND));
......@@ -139,247 +136,6 @@ menubar_id_to_frame (id)
return 0;
}
DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
doc: /* Pop up a deck-of-cards menu and return user's selection.
POSITION is a position specification. This is either a mouse button
event or a list ((XOFFSET YOFFSET) WINDOW) where XOFFSET and YOFFSET
are positions in pixels from the top left corner of WINDOW's frame
\(WINDOW may be a frame object instead of a window). This controls the
position of the center of the first line in the first pane of the
menu, not the top left of the menu as a whole. If POSITION is t, it
means to use the current mouse position.
MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
The menu items come from key bindings that have a menu string as well as
a definition; actually, the \"definition\" in such a key binding looks like
\(STRING . REAL-DEFINITION). To give the menu a title, put a string into
the keymap as a top-level element.
If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
Otherwise, REAL-DEFINITION should be a valid key binding definition.
You can also use a list of keymaps as MENU. Then each keymap makes a
separate pane. When MENU is a keymap or a list of keymaps, the return
value is a list of events.
Alternatively, you can specify a menu of multiple panes with a list of
the form (TITLE PANE1 PANE2...), where each pane is a list of
form (TITLE ITEM1 ITEM2...).
Each ITEM is normally a cons cell (STRING . VALUE); but a string can
appear as an item--that makes a nonselectable line in the menu.
With this form of menu, the return value is VALUE from the chosen item.
If POSITION is nil, don't display the menu at all, just precalculate the
cached information about equivalent key sequences. */)
(position, menu)
Lisp_Object position, menu;
{
Lisp_Object keymap, tem;
int xpos = 0, ypos = 0;
Lisp_Object title;
char *error_name;
Lisp_Object selection;
FRAME_PTR f = NULL;
Lisp_Object x, y, window;
int keymaps = 0;
int for_click = 0;
int specpdl_count = SPECPDL_INDEX ();
struct gcpro gcpro1;
#ifdef HAVE_MENUS
if (! NILP (position))
{
check_w32 ();
/* Decode the first argument: find the window and the coordinates. */
if (EQ (position, Qt)
|| (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
|| EQ (XCAR (position), Qtool_bar))))
{
/* Use the mouse's current position. */
FRAME_PTR new_f = SELECTED_FRAME ();
Lisp_Object bar_window;
enum scroll_bar_part part;
unsigned long time;
if (FRAME_TERMINAL (new_f)->mouse_position_hook)
(*FRAME_TERMINAL (new_f)->mouse_position_hook) (&new_f, 1, &bar_window,
&part, &x, &y, &time);
if (new_f != 0)
XSETFRAME (window, new_f);
else
{
window = selected_window;
XSETFASTINT (x, 0);
XSETFASTINT (y, 0);
}
}
else
{
tem = Fcar (position);
if (CONSP (tem))
{
window = Fcar (Fcdr (position));
x = Fcar (tem);
y = Fcar (Fcdr (tem));
}
else
{
for_click = 1;
tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
window = Fcar (tem); /* POSN_WINDOW (tem) */
tem = Fcar (Fcdr (Fcdr (tem))); /* POSN_WINDOW_POSN (tem) */
x = Fcar (tem);
y = Fcdr (tem);
}
}
CHECK_NUMBER (x);
CHECK_NUMBER (y);
/* Decode where to put the menu. */
if (FRAMEP (window))
{
f = XFRAME (window);
xpos = 0;
ypos = 0;
}
else if (WINDOWP (window))
{
CHECK_LIVE_WINDOW (window);
f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
xpos = WINDOW_LEFT_EDGE_X (XWINDOW (window));
ypos = WINDOW_TOP_EDGE_Y (XWINDOW (window));
}
else
/* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
but I don't want to make one now. */
CHECK_WINDOW (window);
xpos += XINT (x);
ypos += XINT (y);
XSETFRAME (Vmenu_updating_frame, f);
}
else
Vmenu_updating_frame = Qnil;
#endif /* HAVE_MENUS */
record_unwind_protect (unuse_menu_items, Qnil);
title = Qnil;
GCPRO1 (title);
/* Decode the menu items from what was specified. */
keymap = get_keymap (menu, 0, 0);
if (CONSP (keymap))
{
/* We were given a keymap. Extract menu info from the keymap. */
Lisp_Object prompt;
/* Extract the detailed info to make one pane. */
keymap_panes (&menu, 1, NILP (position));
/* Search for a string appearing directly as an element of the keymap.
That string is the title of the menu. */
prompt = Fkeymap_prompt (keymap);
if (NILP (title) && !NILP (prompt))
title = prompt;
/* Make that be the pane title of the first pane. */
if (!NILP (prompt) && menu_items_n_panes >= 0)
ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt);
keymaps = 1;
}
else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
{
/* We were given a list of keymaps. */
int nmaps = XFASTINT (Flength (menu));
Lisp_Object *maps
= (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
int i;
title = Qnil;
/* The first keymap that has a prompt string
supplies the menu title. */
for (tem = menu, i = 0; CONSP (tem); tem = Fcdr (tem))
{
Lisp_Object prompt;
maps[i++] = keymap = get_keymap (Fcar (tem), 1, 0);
prompt = Fkeymap_prompt (keymap);
if (NILP (title) && !NILP (prompt))
title = prompt;
}
/* Extract the detailed info to make one pane. */
keymap_panes (maps, nmaps, NILP (position));
/* Make the title be the pane title of the first pane. */
if (!NILP (title) && menu_items_n_panes >= 0)
ASET (menu_items, MENU_ITEMS_PANE_NAME, title);
keymaps = 1;
}
else
{
/* We were given an old-fashioned menu. */
title = Fcar (menu);
CHECK_STRING (title);
list_of_panes (Fcdr (menu));
keymaps = 0;
}
unbind_to (specpdl_count, Qnil);
if (NILP (position))
{
discard_menu_items ();
FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
UNGCPRO;
return Qnil;
}
#ifdef HAVE_MENUS
/* If resources from a previous popup menu still exist, does nothing
until the `menu_free_timer' has freed them (see w32fns.c). This
can occur if you press ESC or click outside a menu without selecting
a menu item.
*/
if (current_popup_menu)
{
discard_menu_items ();
FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
UNGCPRO;
return Qnil;
}
/* Display them in a menu. */
BLOCK_INPUT;
selection = w32_menu_show (f, xpos, ypos, for_click,
keymaps, title, &error_name);
UNBLOCK_INPUT;
discard_menu_items ();
FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
#endif /* HAVE_MENUS */
UNGCPRO;
if (error_name) error (error_name);
return selection;
}
#ifdef HAVE_MENUS
DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
......@@ -936,15 +692,9 @@ free_frame_menubar (f)
ERROR is a place to store an error message string in case of failure.
(We return nil on failure, but the value doesn't actually matter.) */
static Lisp_Object
w32_menu_show (f, x, y, for_click, keymaps, title, error)
FRAME_PTR f;
int x;
int y;