aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2001-12-01 11:16:54 +0000
committerJason Rumney2001-12-01 11:16:54 +0000
commitace9b2986c742b8eb5b7ae239baccf55d9189aaa (patch)
treedd2b2ec5d33ecc3f21604606f988be1a04be2cc0 /src
parent9eb16b6264445b2281d46711221210b0452a6d46 (diff)
downloademacs-ace9b2986c742b8eb5b7ae239baccf55d9189aaa.tar.gz
emacs-ace9b2986c742b8eb5b7ae239baccf55d9189aaa.zip
(current_popup_menu, get_menu_item_info):
(set_menu_item_info): New vars. (set_frame_menubar): Doc fix clarifying GC interaction with menus. (w32_menu_show): Set current_popup_menu. (add_menu_item): Allocate new strings for owner-drawn menu items and help strings. Use owner-draw for disabled menu items again. (w32_menu_display_help): Ignore owner-drawn items and popup menus. (w32_free_submenu_strings, w32_free_menu_strings): New functions.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog21
-rw-r--r--src/w32menu.c124
2 files changed, 117 insertions, 28 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 43424369357..ac7a87f554a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,24 @@
12001-12-01 Jason Rumney <jasonr@gnu.org>
2
3 * w32menu.c (current_popup_menu, get_menu_item_info):
4 (set_menu_item_info): New vars.
5 (set_frame_menubar): Doc fix clarifying GC interaction with menus.
6 (w32_menu_show): Set current_popup_menu.
7 (add_menu_item): Allocate new strings for owner-drawn menu items
8 and help strings.
9 Use owner-draw for disabled menu items again.
10 (w32_menu_display_help): Ignore owner-drawn items and popup menus.
11 (w32_free_submenu_strings, w32_free_menu_strings): New functions.
12
13 * w32fns.c (trackmouse_window, track_mouse_event_fn): New vars.
14 (w32_wnd_proc) <WM_MOUSEMOVE>: Notice when mouse enters frame.
15 <WM_EXITMENULOOP>: Free menu strings.
16 <WM_MOUSELEAVE>: Stop tracking mouse.
17 (x_create_tip_frame): Specify no minibuffer, modeline or fringes.
18
19 * w32term.c (w32_read_socket) <WM_MOUSELEAVE>: Cancel help echo
20 and mouse face.
21
12001-12-01 Kim F. Storm <storm@cua.dk> 222001-12-01 Kim F. Storm <storm@cua.dk>
2 23
3 The following changes add left-fringe and right-fringe 24 The following changes add left-fringe and right-fringe
diff --git a/src/w32menu.c b/src/w32menu.c
index 638d85b2ea0..3f1b3d07ddb 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -119,6 +119,11 @@ typedef struct _widget_value
119#define FALSE 0 119#define FALSE 0
120#endif /* no TRUE */ 120#endif /* no TRUE */
121 121
122static HMENU current_popup_menu;
123
124FARPROC get_menu_item_info;
125FARPROC set_menu_item_info;
126
122Lisp_Object Vmenu_updating_frame; 127Lisp_Object Vmenu_updating_frame;
123 128
124Lisp_Object Qdebug_on_next_call; 129Lisp_Object Qdebug_on_next_call;
@@ -1416,7 +1421,10 @@ set_frame_menubar (f, first_time, deep_p)
1416 } 1421 }
1417 1422
1418 /* Now GC cannot happen during the lifetime of the widget_value, 1423 /* Now GC cannot happen during the lifetime of the widget_value,
1419 so it's safe to store data from a Lisp_String. */ 1424 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. */
1420 wv = first_wv->contents; 1428 wv = first_wv->contents;
1421 for (i = 0; i < XVECTOR (items)->size; i += 4) 1429 for (i = 0; i < XVECTOR (items)->size; i += 4)
1422 { 1430 {
@@ -1752,7 +1760,7 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1752 } 1760 }
1753 1761
1754 /* Actually create the menu. */ 1762 /* Actually create the menu. */
1755 menu = CreatePopupMenu (); 1763 current_popup_menu = menu = CreatePopupMenu ();
1756 fill_in_menu (menu, first_wv->contents); 1764 fill_in_menu (menu, first_wv->contents);
1757 1765
1758 /* Adjust coordinates to be root-window-relative. */ 1766 /* Adjust coordinates to be root-window-relative. */
@@ -1836,6 +1844,7 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1836} 1844}
1837 1845
1838 1846
1847#ifdef HAVE_DIALOGS
1839static char * button_names [] = { 1848static char * button_names [] = {
1840 "button1", "button2", "button3", "button4", "button5", 1849 "button1", "button2", "button3", "button4", "button5",
1841 "button6", "button7", "button8", "button9", "button10" }; 1850 "button6", "button7", "button8", "button9", "button10" };
@@ -1959,13 +1968,11 @@ w32_dialog_show (f, keymaps, title, error)
1959 } 1968 }
1960 1969
1961 /* Actually create the dialog. */ 1970 /* Actually create the dialog. */
1962#ifdef HAVE_DIALOGS
1963 dialog_id = widget_id_tick++; 1971 dialog_id = widget_id_tick++;
1964 menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, 1972 menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
1965 f->output_data.w32->widget, 1, 0, 1973 f->output_data.w32->widget, 1, 0,
1966 dialog_selection_callback, 0); 1974 dialog_selection_callback, 0);
1967 lw_modify_all_widgets (dialog_id, first_wv->contents, TRUE); 1975 lw_modify_all_widgets (dialog_id, first_wv->contents, TRUE);
1968#endif
1969 1976
1970 /* Free the widget_value objects we used to specify the contents. */ 1977 /* Free the widget_value objects we used to specify the contents. */
1971 free_menubar_widget_value_tree (first_wv); 1978 free_menubar_widget_value_tree (first_wv);
@@ -1974,7 +1981,6 @@ w32_dialog_show (f, keymaps, title, error)
1974 menu_item_selection = 0; 1981 menu_item_selection = 0;
1975 1982
1976 /* Display the menu. */ 1983 /* Display the menu. */
1977#ifdef HAVE_DIALOGS
1978 lw_pop_up_all_widgets (dialog_id); 1984 lw_pop_up_all_widgets (dialog_id);
1979 popup_activated_flag = 1; 1985 popup_activated_flag = 1;
1980 1986
@@ -1982,7 +1988,6 @@ w32_dialog_show (f, keymaps, title, error)
1982 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id); 1988 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id);
1983 1989
1984 lw_destroy_all_widgets (dialog_id); 1990 lw_destroy_all_widgets (dialog_id);
1985#endif
1986 1991
1987 /* Find the selected item, and its pane, to return 1992 /* Find the selected item, and its pane, to return
1988 the proper value. */ 1993 the proper value. */
@@ -2023,6 +2028,7 @@ w32_dialog_show (f, keymaps, title, error)
2023 2028
2024 return Qnil; 2029 return Qnil;
2025} 2030}
2031#endif /* HAVE_DIALOGS */
2026 2032
2027 2033
2028/* Is this item a separator? */ 2034/* Is this item a separator? */
@@ -2077,16 +2083,19 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2077 else 2083 else
2078 out_string = wv->name; 2084 out_string = wv->name;
2079 2085
2080 if (wv->title) 2086 if (wv->title || wv->call_data == 0)
2081 { 2087 {
2082#if 0 /* no GC while popup menu is active */ 2088 /* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since
2083 out_string = LocalAlloc (0, strlen (wv->name) + 1); 2089 we can't deallocate the memory otherwise. */
2084 strcpy (out_string, wv->name); 2090 if (get_menu_item_info)
2085#endif 2091 {
2086 fuFlags = MF_OWNERDRAW | MF_DISABLED; 2092 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;
2087 } 2098 }
2088 else if (wv->call_data == 0)
2089 fuFlags |= MF_DISABLED;
2090 2099
2091 /* Draw radio buttons and tickboxes. */ 2100 /* Draw radio buttons and tickboxes. */
2092 else if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE || 2101 else if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
@@ -2108,9 +2117,6 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2108 /* This must be done after the menu item is created. */ 2117 /* This must be done after the menu item is created. */
2109 if (!wv->title && wv->call_data != 0) 2118 if (!wv->title && wv->call_data != 0)
2110 { 2119 {
2111 HMODULE user32 = GetModuleHandle ("user32.dll");
2112 FARPROC set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA");
2113
2114 if (set_menu_item_info) 2120 if (set_menu_item_info)
2115 { 2121 {
2116 MENUITEMINFO info; 2122 MENUITEMINFO info;
@@ -2118,8 +2124,15 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2118 info.cbSize = sizeof (info); 2124 info.cbSize = sizeof (info);
2119 info.fMask = MIIM_DATA; 2125 info.fMask = MIIM_DATA;
2120 2126
2121 /* Set help string for menu item. */ 2127 /* Set help string for menu item. Allocate new memory
2122 info.dwItemData = (DWORD)wv->help; 2128 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 }
2123 2136
2124 if (wv->button_type == BUTTON_TYPE_RADIO) 2137 if (wv->button_type == BUTTON_TYPE_RADIO)
2125 { 2138 {
@@ -2183,21 +2196,25 @@ popup_activated ()
2183void 2196void
2184w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags) 2197w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags)
2185{ 2198{
2186 HMODULE user32 = GetModuleHandle ("user32.dll");
2187 FARPROC get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA");
2188
2189 if (get_menu_item_info) 2199 if (get_menu_item_info)
2190 { 2200 {
2191 MENUITEMINFO info;
2192 struct frame *f = x_window_to_frame (&one_w32_display_info, owner); 2201 struct frame *f = x_window_to_frame (&one_w32_display_info, owner);
2193 Lisp_Object frame, help; 2202 Lisp_Object frame, help;
2194 2203
2195 bzero (&info, sizeof (info)); 2204 // No help echo on owner-draw menu items.
2196 info.cbSize = sizeof (info); 2205 if (flags & MF_OWNERDRAW || flags & MF_POPUP)
2197 info.fMask = MIIM_DATA; 2206 help = Qnil;
2198 get_menu_item_info (menu, item, FALSE, &info); 2207 else
2208 {
2209 MENUITEMINFO info;
2199 2210
2200 help = info.dwItemData ? build_string ((char *)info.dwItemData) : Qnil; 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;
2217 }
2201 2218
2202 /* Store the help echo in the keyboard buffer as the X toolkit 2219 /* Store the help echo in the keyboard buffer as the X toolkit
2203 version does, rather than directly showing it. This seems to 2220 version does, rather than directly showing it. This seems to
@@ -2215,15 +2232,66 @@ w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags)
2215 } 2232 }
2216} 2233}
2217 2234
2235/* Free memory used by owner-drawn and help_echo strings. */
2236static void
2237w32_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;
2218 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
2260void
2261w32_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}
2219 2279
2220#endif /* HAVE_MENUS */ 2280#endif /* HAVE_MENUS */
2281
2221 2282
2222syms_of_w32menu () 2283syms_of_w32menu ()
2223{ 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
2224 staticpro (&menu_items); 2290 staticpro (&menu_items);
2225 menu_items = Qnil; 2291 menu_items = Qnil;
2226 2292
2293 current_popup_menu = NULL;
2294
2227 Qdebug_on_next_call = intern ("debug-on-next-call"); 2295 Qdebug_on_next_call = intern ("debug-on-next-call");
2228 staticpro (&Qdebug_on_next_call); 2296 staticpro (&Qdebug_on_next_call);
2229 2297