char* name;
/* value (meaning depend on widget type) */
char* value;
- /* keyboard equivalent. no implications for XtTranslations */
+ /* keyboard equivalent. no implications for XtTranslations */
char* key;
/* Help string or nil if none.
GC finds this string through the frame's menu_bar_vector
static HMENU current_popup_menu;
-FARPROC get_menu_item_info;
-FARPROC set_menu_item_info;
+void syms_of_w32menu ();
+void globals_of_w32menu ();
+
+typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
+ IN HMENU,
+ IN UINT,
+ IN BOOL,
+ IN OUT LPMENUITEMINFOA
+ );
+typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
+ IN HMENU,
+ IN UINT,
+ IN BOOL,
+ IN LPCMENUITEMINFOA
+ );
+
+GetMenuItemInfoA_Proc get_menu_item_info=NULL;
+SetMenuItemInfoA_Proc set_menu_item_info=NULL;
Lisp_Object Vmenu_updating_frame;
\f
/* This is a subroutine of single_keymap_panes that handles one
keymap entry.
- KEY is a key in a keymap and ITEM is its binding.
+ KEY is a key in a keymap and ITEM is its binding.
PENDING_MAPS_PTR points to a list of keymaps waiting to be made into
separate panes.
If NOTREAL is nonzero, only check for equivalent key bindings, don't
Lisp_Object map, item_string, enabled;
struct gcpro gcpro1, gcpro2;
int res;
-
+
/* Parse the menu item and leave the result in item_properties. */
GCPRO2 (key, item);
res = parse_menu_item (item, notreal, 0);
return; /* Not a menu item. */
map = AREF (item_properties, ITEM_PROPERTY_MAP);
-
+
if (notreal)
{
/* We don't want to make a menu, just traverse the keymaps to
}
enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE);
- item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
+ item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
if (!NILP (map) && SREF (item_string, 0) == '@')
{
keymaps = 0;
}
-
+
if (NILP (position))
{
discard_menu_items ();
discard_menu_items ();
UNGCPRO;
return Qnil;
- }
-
+ }
+
/* Display them in a menu. */
BLOCK_INPUT;
But first we recompute the menu bar contents (the whole tree).
This way we can safely execute Lisp code. */
-
+
void
x_activate_menubar (f)
FRAME_PTR f;
widget_value *wv;
{
if (! wv) return;
-
+
wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
if (wv->contents && (wv->contents != (widget_value*)1))
Qnil, Qnil, Qnil, Qnil);
}
else
- single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
+ {
+ Lisp_Object prompt;
+ prompt = Fkeymap_prompt (mapvec[i]);
+ single_keymap_panes (mapvec[i],
+ !NILP (prompt) ? prompt : item_name,
+ item_key, 0, 10);
+ }
}
-
+
return top_level_items;
}
static widget_value *
digest_single_submenu (start, end, top_level_items)
- int start, end;
+ int start, end, top_level_items;
{
widget_value *wv, *prev_wv, *save_wv, *first_wv;
int i;
first_wv = wv;
save_wv = 0;
prev_wv = 0;
-
- /* Loop over all panes and items made during this call
- and construct a tree of widget_value objects.
- Ignore the panes and items made by previous calls to
- single_submenu, even though those are also in menu_items. */
+
+ /* Loop over all panes and items made by the preceding call
+ to parse_single_submenu and construct a tree of widget_value objects.
+ Ignore the panes and items used by previous calls to
+ digest_single_submenu, even though those are also in menu_items. */
i = start;
while (i < end)
{
#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
else
save_wv->contents = wv;
widget_value *wv, *first_wv, *prev_wv = 0;
int i, last_i;
int *submenu_start, *submenu_end;
- int *submenu_top_level_items;
+ int *submenu_top_level_items, *submenu_n_panes;
/* We must not change the menubar when actually in use. */
if (f->output_data.w32->menubar_active)
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+ submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
submenu_top_level_items
= (int *) alloca (XVECTOR (items)->size * sizeof (int *));
init_menu_items ();
menu_items_n_panes = 0;
submenu_top_level_items[i]
= parse_single_submenu (key, string, maps);
+ submenu_n_panes[i] = menu_items_n_panes;
submenu_end[i] = menu_items_used;
}
for (i = 0; i < last_i; i += 4)
{
+ menu_items_n_panes = submenu_n_panes[i];
wv = digest_single_submenu (submenu_start[i], submenu_end[i],
submenu_top_level_items[i]);
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
else
first_wv->contents = wv;
This value just has to be different from small integers. */
wv->call_data = (void *) (EMACS_INT) (-1);
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
else
first_wv->contents = wv;
f->output_data.w32->menubar_widget = menubar_widget;
SetMenu (FRAME_W32_WINDOW (f), f->output_data.w32->menubar_widget);
- /* Causes flicker when menu bar is updated
+ /* Causes flicker when menu bar is updated
DrawMenuBar (FRAME_W32_WINDOW (f)); */
/* Force the window size to be recomputed so that the frame's text
wv->help = Qnil;
first_wv = wv;
first_pane = 1;
-
+
/* Loop over all panes and items, filling in the tree. */
i = 0;
while (i < menu_items_used)
#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
- else
+ else
save_wv->contents = wv;
wv->name = (char *) SDATA (item_name);
if (!NILP (descrip))
menu_item_selection = 0;
/* Display the menu. */
- menu_item_selection = SendMessage (FRAME_W32_WINDOW (f),
+ menu_item_selection = SendMessage (FRAME_W32_WINDOW (f),
WM_EMACS_TRACKPOPUPMENU,
(WPARAM)menu, (LPARAM)&pos);
pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX);
pane_string = (NILP (pane_name)
- ? "" : (char *) SDATA (pane_name));
+ ? "" : (char *) SDATA (pane_name));
prev_wv = xmalloc_widget_value ();
prev_wv->value = pane_string;
if (keymaps && !NILP (prefix))
prev_wv->name = "message";
prev_wv->help = Qnil;
first_wv = prev_wv;
-
+
/* Loop over all panes and items, filling in the tree. */
i = MENU_ITEMS_PANE_LENGTH;
while (i < menu_items_used)
{
-
+
/* Create a new item within current pane. */
Lisp_Object item_name, enable, descrip, help;
enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
-
+
if (NILP (item_name))
{
free_menubar_widget_value_tree (first_wv);
/* Process events that apply to the menu. */
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id);
- lw_destroy_all_widgets (dialog_id);
+ lw_destroy_all_widgets (dialog_id);
/* Find the selected item, and its pane, to return
the proper value. */
fuFlags = MF_SEPARATOR;
out_string = NULL;
}
- else
+ else
{
if (wv->enabled)
fuFlags = MF_STRING;
#endif /* HAVE_MENUS */
-\f
-syms_of_w32menu ()
+void syms_of_w32menu ()
{
- /* See if Get/SetMenuItemInfo functions are available. */
- HMODULE user32 = GetModuleHandle ("user32.dll");
- get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA");
- set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA");
-
+ globals_of_w32menu ();
staticpro (&menu_items);
menu_items = Qnil;
defsubr (&Sx_popup_dialog);
#endif
}
+
+/*
+ globals_of_w32menu is used to initialize those global variables that
+ must always be initialized on startup even when the global variable
+ initialized is non zero (see the function main in emacs.c).
+ globals_of_w32menu is called from syms_of_w32menu when the global
+ variable initialized is 0 and directly from main when initialized
+ is non zero.
+ */
+void globals_of_w32menu ()
+{
+ /* See if Get/SetMenuItemInfo functions are available. */
+ HMODULE user32 = GetModuleHandle ("user32.dll");
+ get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
+ set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
+}