119 |
#define FALSE 0 |
#define FALSE 0 |
120 |
#endif /* no TRUE */ |
#endif /* no TRUE */ |
121 |
|
|
122 |
|
static HMENU current_popup_menu; |
123 |
|
|
124 |
|
FARPROC get_menu_item_info; |
125 |
|
FARPROC set_menu_item_info; |
126 |
|
|
127 |
Lisp_Object Vmenu_updating_frame; |
Lisp_Object Vmenu_updating_frame; |
128 |
|
|
129 |
Lisp_Object Qdebug_on_next_call; |
Lisp_Object Qdebug_on_next_call; |
1421 |
} |
} |
1422 |
|
|
1423 |
/* Now GC cannot happen during the lifetime of the widget_value, |
/* Now GC cannot happen during the lifetime of the widget_value, |
1424 |
so it's safe to store data from a Lisp_String. */ |
so it's safe to store data from a Lisp_String, as long as |
1425 |
|
local copies are made when the actual menu is created. |
1426 |
|
Windows takes care of this for normal string items, but |
1427 |
|
not for owner-drawn items or additional item-info. */ |
1428 |
wv = first_wv->contents; |
wv = first_wv->contents; |
1429 |
for (i = 0; i < XVECTOR (items)->size; i += 4) |
for (i = 0; i < XVECTOR (items)->size; i += 4) |
1430 |
{ |
{ |
1760 |
} |
} |
1761 |
|
|
1762 |
/* Actually create the menu. */ |
/* Actually create the menu. */ |
1763 |
menu = CreatePopupMenu (); |
current_popup_menu = menu = CreatePopupMenu (); |
1764 |
fill_in_menu (menu, first_wv->contents); |
fill_in_menu (menu, first_wv->contents); |
1765 |
|
|
1766 |
/* Adjust coordinates to be root-window-relative. */ |
/* Adjust coordinates to be root-window-relative. */ |
1844 |
} |
} |
1845 |
|
|
1846 |
|
|
1847 |
|
#ifdef HAVE_DIALOGS |
1848 |
static char * button_names [] = { |
static char * button_names [] = { |
1849 |
"button1", "button2", "button3", "button4", "button5", |
"button1", "button2", "button3", "button4", "button5", |
1850 |
"button6", "button7", "button8", "button9", "button10" }; |
"button6", "button7", "button8", "button9", "button10" }; |
1968 |
} |
} |
1969 |
|
|
1970 |
/* Actually create the dialog. */ |
/* Actually create the dialog. */ |
|
#ifdef HAVE_DIALOGS |
|
1971 |
dialog_id = widget_id_tick++; |
dialog_id = widget_id_tick++; |
1972 |
menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, |
menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, |
1973 |
f->output_data.w32->widget, 1, 0, |
f->output_data.w32->widget, 1, 0, |
1974 |
dialog_selection_callback, 0); |
dialog_selection_callback, 0); |
1975 |
lw_modify_all_widgets (dialog_id, first_wv->contents, TRUE); |
lw_modify_all_widgets (dialog_id, first_wv->contents, TRUE); |
|
#endif |
|
1976 |
|
|
1977 |
/* Free the widget_value objects we used to specify the contents. */ |
/* Free the widget_value objects we used to specify the contents. */ |
1978 |
free_menubar_widget_value_tree (first_wv); |
free_menubar_widget_value_tree (first_wv); |
1981 |
menu_item_selection = 0; |
menu_item_selection = 0; |
1982 |
|
|
1983 |
/* Display the menu. */ |
/* Display the menu. */ |
|
#ifdef HAVE_DIALOGS |
|
1984 |
lw_pop_up_all_widgets (dialog_id); |
lw_pop_up_all_widgets (dialog_id); |
1985 |
popup_activated_flag = 1; |
popup_activated_flag = 1; |
1986 |
|
|
1988 |
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id); |
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id); |
1989 |
|
|
1990 |
lw_destroy_all_widgets (dialog_id); |
lw_destroy_all_widgets (dialog_id); |
|
#endif |
|
1991 |
|
|
1992 |
/* Find the selected item, and its pane, to return |
/* Find the selected item, and its pane, to return |
1993 |
the proper value. */ |
the proper value. */ |
2028 |
|
|
2029 |
return Qnil; |
return Qnil; |
2030 |
} |
} |
2031 |
|
#endif /* HAVE_DIALOGS */ |
2032 |
|
|
2033 |
|
|
2034 |
/* Is this item a separator? */ |
/* Is this item a separator? */ |
2083 |
else |
else |
2084 |
out_string = wv->name; |
out_string = wv->name; |
2085 |
|
|
2086 |
if (wv->title) |
if (wv->title || wv->call_data == 0) |
2087 |
{ |
{ |
2088 |
#if 0 /* no GC while popup menu is active */ |
/* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since |
2089 |
out_string = LocalAlloc (0, strlen (wv->name) + 1); |
we can't deallocate the memory otherwise. */ |
2090 |
strcpy (out_string, wv->name); |
if (get_menu_item_info) |
2091 |
#endif |
{ |
2092 |
fuFlags = MF_OWNERDRAW | MF_DISABLED; |
out_string = LocalAlloc (LPTR, strlen (wv->name) + 1); |
2093 |
|
strcpy (out_string, wv->name); |
2094 |
|
fuFlags = MF_OWNERDRAW | MF_DISABLED; |
2095 |
|
} |
2096 |
|
else |
2097 |
|
fuFlags = MF_DISABLED; |
2098 |
} |
} |
|
else if (wv->call_data == 0) |
|
|
fuFlags |= MF_DISABLED; |
|
2099 |
|
|
2100 |
/* Draw radio buttons and tickboxes. */ |
/* Draw radio buttons and tickboxes. */ |
2101 |
else if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE || |
else if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE || |
2117 |
/* This must be done after the menu item is created. */ |
/* This must be done after the menu item is created. */ |
2118 |
if (!wv->title && wv->call_data != 0) |
if (!wv->title && wv->call_data != 0) |
2119 |
{ |
{ |
|
HMODULE user32 = GetModuleHandle ("user32.dll"); |
|
|
FARPROC set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA"); |
|
|
|
|
2120 |
if (set_menu_item_info) |
if (set_menu_item_info) |
2121 |
{ |
{ |
2122 |
MENUITEMINFO info; |
MENUITEMINFO info; |
2124 |
info.cbSize = sizeof (info); |
info.cbSize = sizeof (info); |
2125 |
info.fMask = MIIM_DATA; |
info.fMask = MIIM_DATA; |
2126 |
|
|
2127 |
/* Set help string for menu item. */ |
/* Set help string for menu item. Allocate new memory |
2128 |
info.dwItemData = (DWORD)wv->help; |
from the heap for it, since garbage collection can |
2129 |
|
occur while menus are active. */ |
2130 |
|
if (wv->help) |
2131 |
|
{ |
2132 |
|
info.dwItemData |
2133 |
|
= (DWORD) LocalAlloc (LPTR, strlen(wv->help) + 1); |
2134 |
|
strcpy (info.dwItemData, wv->help); |
2135 |
|
} |
2136 |
|
|
2137 |
if (wv->button_type == BUTTON_TYPE_RADIO) |
if (wv->button_type == BUTTON_TYPE_RADIO) |
2138 |
{ |
{ |
2196 |
void |
void |
2197 |
w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags) |
w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags) |
2198 |
{ |
{ |
|
HMODULE user32 = GetModuleHandle ("user32.dll"); |
|
|
FARPROC get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA"); |
|
|
|
|
2199 |
if (get_menu_item_info) |
if (get_menu_item_info) |
2200 |
{ |
{ |
|
MENUITEMINFO info; |
|
2201 |
struct frame *f = x_window_to_frame (&one_w32_display_info, owner); |
struct frame *f = x_window_to_frame (&one_w32_display_info, owner); |
2202 |
Lisp_Object frame, help; |
Lisp_Object frame, help; |
2203 |
|
|
2204 |
bzero (&info, sizeof (info)); |
// No help echo on owner-draw menu items. |
2205 |
info.cbSize = sizeof (info); |
if (flags & MF_OWNERDRAW || flags & MF_POPUP) |
2206 |
info.fMask = MIIM_DATA; |
help = Qnil; |
2207 |
get_menu_item_info (menu, item, FALSE, &info); |
else |
2208 |
|
{ |
2209 |
|
MENUITEMINFO info; |
2210 |
|
|
2211 |
|
bzero (&info, sizeof (info)); |
2212 |
|
info.cbSize = sizeof (info); |
2213 |
|
info.fMask = MIIM_DATA; |
2214 |
|
get_menu_item_info (menu, item, FALSE, &info); |
2215 |
|
|
2216 |
help = info.dwItemData ? build_string ((char *)info.dwItemData) : Qnil; |
help = info.dwItemData ? build_string ((char *)info.dwItemData) : Qnil; |
2217 |
|
} |
2218 |
|
|
2219 |
/* Store the help echo in the keyboard buffer as the X toolkit |
/* Store the help echo in the keyboard buffer as the X toolkit |
2220 |
version does, rather than directly showing it. This seems to |
version does, rather than directly showing it. This seems to |
2232 |
} |
} |
2233 |
} |
} |
2234 |
|
|
2235 |
|
/* Free memory used by owner-drawn and help_echo strings. */ |
2236 |
|
static void |
2237 |
|
w32_free_submenu_strings (menu) |
2238 |
|
HMENU menu; |
2239 |
|
{ |
2240 |
|
int i, num = GetMenuItemCount (menu); |
2241 |
|
for (i = 0; i < num; i++) |
2242 |
|
{ |
2243 |
|
MENUITEMINFO info; |
2244 |
|
|
2245 |
|
info.cbSize = sizeof (info); |
2246 |
|
info.fMask = MIIM_DATA | MIIM_SUBMENU; |
2247 |
|
|
2248 |
|
get_menu_item_info (menu, i, TRUE, &info); |
2249 |
|
|
2250 |
|
/* Both owner-drawn names and help strings are held in dwItemData. */ |
2251 |
|
if (info.dwItemData) |
2252 |
|
LocalFree (info.dwItemData); |
2253 |
|
|
2254 |
|
/* Recurse down submenus. */ |
2255 |
|
if (info.hSubMenu) |
2256 |
|
w32_free_submenu_strings (info.hSubMenu); |
2257 |
|
} |
2258 |
|
} |
2259 |
|
|
2260 |
|
void |
2261 |
|
w32_free_menu_strings (hwnd) |
2262 |
|
HWND hwnd; |
2263 |
|
{ |
2264 |
|
HMENU menu = current_popup_menu; |
2265 |
|
|
2266 |
|
if (get_menu_item_info) |
2267 |
|
{ |
2268 |
|
/* If there is no popup menu active, free the strings from the frame's |
2269 |
|
menubar. */ |
2270 |
|
if (!menu) |
2271 |
|
menu = GetMenu (hwnd); |
2272 |
|
|
2273 |
|
if (menu) |
2274 |
|
w32_free_submenu_strings (menu); |
2275 |
|
} |
2276 |
|
|
2277 |
|
current_popup_menu = NULL; |
2278 |
|
} |
2279 |
|
|
2280 |
#endif /* HAVE_MENUS */ |
#endif /* HAVE_MENUS */ |
2281 |
|
|
2282 |
|
|
2283 |
syms_of_w32menu () |
syms_of_w32menu () |
2284 |
{ |
{ |
2285 |
|
/* See if Get/SetMenuItemInfo functions are available. */ |
2286 |
|
HMODULE user32 = GetModuleHandle ("user32.dll"); |
2287 |
|
get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA"); |
2288 |
|
set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA"); |
2289 |
|
|
2290 |
staticpro (&menu_items); |
staticpro (&menu_items); |
2291 |
menu_items = Qnil; |
menu_items = Qnil; |
2292 |
|
|
2293 |
|
current_popup_menu = NULL; |
2294 |
|
|
2295 |
Qdebug_on_next_call = intern ("debug-on-next-call"); |
Qdebug_on_next_call = intern ("debug-on-next-call"); |
2296 |
staticpro (&Qdebug_on_next_call); |
staticpro (&Qdebug_on_next_call); |
2297 |
|
|