diff options
| author | Jason Rumney | 2001-12-01 11:16:54 +0000 |
|---|---|---|
| committer | Jason Rumney | 2001-12-01 11:16:54 +0000 |
| commit | ace9b2986c742b8eb5b7ae239baccf55d9189aaa (patch) | |
| tree | dd2b2ec5d33ecc3f21604606f988be1a04be2cc0 /src | |
| parent | 9eb16b6264445b2281d46711221210b0452a6d46 (diff) | |
| download | emacs-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/ChangeLog | 21 | ||||
| -rw-r--r-- | src/w32menu.c | 124 |
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 @@ | |||
| 1 | 2001-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 | |||
| 1 | 2001-12-01 Kim F. Storm <storm@cua.dk> | 22 | 2001-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 | ||
| 122 | static HMENU current_popup_menu; | ||
| 123 | |||
| 124 | FARPROC get_menu_item_info; | ||
| 125 | FARPROC set_menu_item_info; | ||
| 126 | |||
| 122 | Lisp_Object Vmenu_updating_frame; | 127 | Lisp_Object Vmenu_updating_frame; |
| 123 | 128 | ||
| 124 | Lisp_Object Qdebug_on_next_call; | 129 | Lisp_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 | ||
| 1839 | static char * button_names [] = { | 1848 | static 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 () | |||
| 2183 | void | 2196 | void |
| 2184 | w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags) | 2197 | w32_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. */ | ||
| 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; | ||
| 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 | |||
| 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 | } | ||
| 2219 | 2279 | ||
| 2220 | #endif /* HAVE_MENUS */ | 2280 | #endif /* HAVE_MENUS */ |
| 2281 | |||
| 2221 | 2282 | ||
| 2222 | syms_of_w32menu () | 2283 | syms_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 | ||