Mercurial > emacs
changeset 41908:4d8905b9ee49
(_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.
author | Jason Rumney <jasonr@gnu.org> |
---|---|
date | Sun, 09 Dec 2001 16:48:03 +0000 |
parents | bb217edc49d0 |
children | 59c24fd13803 |
files | src/w32menu.c |
diffstat | 1 files changed, 36 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/src/w32menu.c Sun Dec 09 16:47:16 2001 +0000 +++ b/src/w32menu.c Sun Dec 09 16:48:03 2001 +0000 @@ -61,6 +61,8 @@ BUTTON_TYPE_RADIO }; +/* This structure is based on the one in ../lwlib/lwlib.h, modified + for Windows. */ typedef struct _widget_value { /* name of widget */ @@ -69,8 +71,10 @@ char* value; /* keyboard equivalent. no implications for XtTranslations */ char* key; - /* Help string or null if none. */ - char *help; + /* Help string or nil if none. + GC finds this string through the frame's menu_bar_vector + or through menu_items. */ + Lisp_Object help; /* true if enabled */ Boolean enabled; /* true if selected */ @@ -1269,10 +1273,10 @@ abort (); wv->selected = !NILP (selected); - if (STRINGP (help)) - wv->help = (char *) XSTRING (help)->data; - else - wv->help = NULL; + if (!STRINGP (help)) + help = Qnil; + + wv->help = help; prev_wv = wv; @@ -1727,8 +1731,10 @@ abort (); wv->selected = !NILP (selected); - if (STRINGP (help)) - wv->help = XSTRING (help)->data; + if (!STRINGP (help)) + help = Qnil; + + wv->help = help; prev_wv = wv; @@ -2083,13 +2089,18 @@ else out_string = wv->name; - if (wv->title || wv->call_data == 0) + if (item != NULL) + fuFlags = MF_POPUP; + else if (wv->title || wv->call_data == 0) { /* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since we can't deallocate the memory otherwise. */ if (get_menu_item_info) { - out_string = LocalAlloc (LPTR, strlen (wv->name) + 1); + out_string = (char *) LocalAlloc (LPTR, strlen (wv->name) + 1); +#ifdef MENU_DEBUG + DebPrint ("Menu: allocing %ld for owner-draw", info.dwItemData); +#endif strcpy (out_string, wv->name); fuFlags = MF_OWNERDRAW | MF_DISABLED; } @@ -2105,9 +2116,6 @@ fuFlags |= MF_UNCHECKED; } - if (item != NULL) - fuFlags = MF_POPUP; - return_value = AppendMenu (menu, fuFlags, @@ -2124,15 +2132,11 @@ info.cbSize = sizeof (info); info.fMask = MIIM_DATA; - /* Set help string for menu item. Allocate new memory - from the heap for it, since garbage collection can - occur while menus are active. */ + /* Set help string for menu item. Leave it as a Lisp_Object + until it is ready to be displayed, since GC can happen while + menus are active. */ if (wv->help) - { - info.dwItemData - = (DWORD) LocalAlloc (LPTR, strlen(wv->help) + 1); - strcpy (info.dwItemData, wv->help); - } + info.dwItemData = (DWORD) wv->help; if (wv->button_type == BUTTON_TYPE_RADIO) { @@ -2213,7 +2217,7 @@ info.fMask = MIIM_DATA; get_menu_item_info (menu, item, FALSE, &info); - help = info.dwItemData ? build_string ((char *)info.dwItemData) : Qnil; + help = info.dwItemData ? (Lisp_Object) info.dwItemData : Qnil; } /* Store the help echo in the keyboard buffer as the X toolkit @@ -2232,7 +2236,7 @@ } } -/* Free memory used by owner-drawn and help_echo strings. */ +/* Free memory used by owner-drawn strings. */ static void w32_free_submenu_strings (menu) HMENU menu; @@ -2243,13 +2247,18 @@ MENUITEMINFO info; info.cbSize = sizeof (info); - info.fMask = MIIM_DATA | MIIM_SUBMENU; + info.fMask = MIIM_DATA | MIIM_TYPE | MIIM_SUBMENU; get_menu_item_info (menu, i, TRUE, &info); - /* Both owner-drawn names and help strings are held in dwItemData. */ - if (info.dwItemData) - LocalFree (info.dwItemData); + /* Owner-drawn names are held in dwItemData. */ + if ((info.fType & MF_OWNERDRAW) && info.dwItemData) + { +#ifdef MENU_DEBUG + DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData); +#endif + LocalFree (info.dwItemData); + } /* Recurse down submenus. */ if (info.hSubMenu)