aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2001-12-09 16:48:03 +0000
committerJason Rumney2001-12-09 16:48:03 +0000
commitd1fffd1db877af2266bf064b101c3b0cf1ccebc2 (patch)
tree7082d3c6d7609bcdb10c50aea76057c7870b4dc5 /src
parentf1a85b8926f3b464bb353ec418b0c04de4053cf4 (diff)
downloademacs-d1fffd1db877af2266bf064b101c3b0cf1ccebc2.tar.gz
emacs-d1fffd1db877af2266bf064b101c3b0cf1ccebc2.zip
(_widget_value): Make `help' field a Lisp_Object. Add
comment to explain where the struct came from. (single_submenu, w32_menu_show): Set `help' field as Lisp_Object. (add_menu_item): Process pop-up menus first to avoid memory leak. (add_menu_item, w32_menu_display_help): Use `help' field as Lisp_Object. (w32_free_submenu_strings): Only free owner-drawn strings.
Diffstat (limited to 'src')
-rw-r--r--src/w32menu.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/src/w32menu.c b/src/w32menu.c
index 3f1b3d07ddb..99376360187 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -61,6 +61,8 @@ enum button_type
61 BUTTON_TYPE_RADIO 61 BUTTON_TYPE_RADIO
62}; 62};
63 63
64/* This structure is based on the one in ../lwlib/lwlib.h, modified
65 for Windows. */
64typedef struct _widget_value 66typedef struct _widget_value
65{ 67{
66 /* name of widget */ 68 /* name of widget */
@@ -69,8 +71,10 @@ typedef struct _widget_value
69 char* value; 71 char* value;
70 /* keyboard equivalent. no implications for XtTranslations */ 72 /* keyboard equivalent. no implications for XtTranslations */
71 char* key; 73 char* key;
72 /* Help string or null if none. */ 74 /* Help string or nil if none.
73 char *help; 75 GC finds this string through the frame's menu_bar_vector
76 or through menu_items. */
77 Lisp_Object help;
74 /* true if enabled */ 78 /* true if enabled */
75 Boolean enabled; 79 Boolean enabled;
76 /* true if selected */ 80 /* true if selected */
@@ -1269,10 +1273,10 @@ single_submenu (item_key, item_name, maps)
1269 abort (); 1273 abort ();
1270 1274
1271 wv->selected = !NILP (selected); 1275 wv->selected = !NILP (selected);
1272 if (STRINGP (help)) 1276 if (!STRINGP (help))
1273 wv->help = (char *) XSTRING (help)->data; 1277 help = Qnil;
1274 else 1278
1275 wv->help = NULL; 1279 wv->help = help;
1276 1280
1277 prev_wv = wv; 1281 prev_wv = wv;
1278 1282
@@ -1727,8 +1731,10 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error)
1727 abort (); 1731 abort ();
1728 1732
1729 wv->selected = !NILP (selected); 1733 wv->selected = !NILP (selected);
1730 if (STRINGP (help)) 1734 if (!STRINGP (help))
1731 wv->help = XSTRING (help)->data; 1735 help = Qnil;
1736
1737 wv->help = help;
1732 1738
1733 prev_wv = wv; 1739 prev_wv = wv;
1734 1740
@@ -2083,13 +2089,18 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2083 else 2089 else
2084 out_string = wv->name; 2090 out_string = wv->name;
2085 2091
2086 if (wv->title || wv->call_data == 0) 2092 if (item != NULL)
2093 fuFlags = MF_POPUP;
2094 else if (wv->title || wv->call_data == 0)
2087 { 2095 {
2088 /* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since 2096 /* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since
2089 we can't deallocate the memory otherwise. */ 2097 we can't deallocate the memory otherwise. */
2090 if (get_menu_item_info) 2098 if (get_menu_item_info)
2091 { 2099 {
2092 out_string = LocalAlloc (LPTR, strlen (wv->name) + 1); 2100 out_string = (char *) LocalAlloc (LPTR, strlen (wv->name) + 1);
2101#ifdef MENU_DEBUG
2102 DebPrint ("Menu: allocing %ld for owner-draw", info.dwItemData);
2103#endif
2093 strcpy (out_string, wv->name); 2104 strcpy (out_string, wv->name);
2094 fuFlags = MF_OWNERDRAW | MF_DISABLED; 2105 fuFlags = MF_OWNERDRAW | MF_DISABLED;
2095 } 2106 }
@@ -2105,9 +2116,6 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2105 fuFlags |= MF_UNCHECKED; 2116 fuFlags |= MF_UNCHECKED;
2106 } 2117 }
2107 2118
2108 if (item != NULL)
2109 fuFlags = MF_POPUP;
2110
2111 return_value = 2119 return_value =
2112 AppendMenu (menu, 2120 AppendMenu (menu,
2113 fuFlags, 2121 fuFlags,
@@ -2124,15 +2132,11 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item)
2124 info.cbSize = sizeof (info); 2132 info.cbSize = sizeof (info);
2125 info.fMask = MIIM_DATA; 2133 info.fMask = MIIM_DATA;
2126 2134
2127 /* Set help string for menu item. Allocate new memory 2135 /* Set help string for menu item. Leave it as a Lisp_Object
2128 from the heap for it, since garbage collection can 2136 until it is ready to be displayed, since GC can happen while
2129 occur while menus are active. */ 2137 menus are active. */
2130 if (wv->help) 2138 if (wv->help)
2131 { 2139 info.dwItemData = (DWORD) wv->help;
2132 info.dwItemData
2133 = (DWORD) LocalAlloc (LPTR, strlen(wv->help) + 1);
2134 strcpy (info.dwItemData, wv->help);
2135 }
2136 2140
2137 if (wv->button_type == BUTTON_TYPE_RADIO) 2141 if (wv->button_type == BUTTON_TYPE_RADIO)
2138 { 2142 {
@@ -2213,7 +2217,7 @@ w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags)
2213 info.fMask = MIIM_DATA; 2217 info.fMask = MIIM_DATA;
2214 get_menu_item_info (menu, item, FALSE, &info); 2218 get_menu_item_info (menu, item, FALSE, &info);
2215 2219
2216 help = info.dwItemData ? build_string ((char *)info.dwItemData) : Qnil; 2220 help = info.dwItemData ? (Lisp_Object) info.dwItemData : Qnil;
2217 } 2221 }
2218 2222
2219 /* Store the help echo in the keyboard buffer as the X toolkit 2223 /* Store the help echo in the keyboard buffer as the X toolkit
@@ -2232,7 +2236,7 @@ w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags)
2232 } 2236 }
2233} 2237}
2234 2238
2235/* Free memory used by owner-drawn and help_echo strings. */ 2239/* Free memory used by owner-drawn strings. */
2236static void 2240static void
2237w32_free_submenu_strings (menu) 2241w32_free_submenu_strings (menu)
2238 HMENU menu; 2242 HMENU menu;
@@ -2243,13 +2247,18 @@ w32_free_submenu_strings (menu)
2243 MENUITEMINFO info; 2247 MENUITEMINFO info;
2244 2248
2245 info.cbSize = sizeof (info); 2249 info.cbSize = sizeof (info);
2246 info.fMask = MIIM_DATA | MIIM_SUBMENU; 2250 info.fMask = MIIM_DATA | MIIM_TYPE | MIIM_SUBMENU;
2247 2251
2248 get_menu_item_info (menu, i, TRUE, &info); 2252 get_menu_item_info (menu, i, TRUE, &info);
2249 2253
2250 /* Both owner-drawn names and help strings are held in dwItemData. */ 2254 /* Owner-drawn names are held in dwItemData. */
2251 if (info.dwItemData) 2255 if ((info.fType & MF_OWNERDRAW) && info.dwItemData)
2252 LocalFree (info.dwItemData); 2256 {
2257#ifdef MENU_DEBUG
2258 DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData);
2259#endif
2260 LocalFree (info.dwItemData);
2261 }
2253 2262
2254 /* Recurse down submenus. */ 2263 /* Recurse down submenus. */
2255 if (info.hSubMenu) 2264 if (info.hSubMenu)