diff --git a/lwlib/lwlib-widget.h b/lwlib/lwlib-widget.h index cd9b579436f..de52abf329e 100644 --- a/lwlib/lwlib-widget.h +++ b/lwlib/lwlib-widget.h @@ -24,6 +24,7 @@ along with GNU Emacs. If not, see . */ #define LWLIB_WIDGET_H #include "../src/lisp.h" +#include "../src/gc-handles.h" typedef enum { @@ -53,10 +54,8 @@ typedef struct _widget_value Lisp_Object lkey; char *key; - /* Help string or nil if none. - GC finds this string through the frame's menu_bar_vector - or through menu_items. */ - Lisp_Object help; + /* Help string or nil if none. */ + gc_handle help; /* True if enabled. */ bool enabled; diff --git a/lwlib/lwlib.c b/lwlib/lwlib.c index c7b80a83338..f7986775f26 100644 --- a/lwlib/lwlib.c +++ b/lwlib/lwlib.c @@ -102,6 +102,7 @@ free_widget_value_tree (widget_value *wv) xfree (wv->name); xfree (wv->value); xfree (wv->key); + free_gc_handle (wv->help); wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; @@ -139,7 +140,7 @@ copy_widget_value_tree (widget_value *val, change_type change) copy->name = xstrdup (val->name); copy->value = val->value ? xstrdup (val->value) : NULL; copy->key = val->key ? xstrdup (val->key) : NULL; - copy->help = val->help; + copy->help = gc_handle_for_gc_handle (val->help); copy->enabled = val->enabled; copy->button_type = val->button_type; copy->selected = val->selected; @@ -384,12 +385,13 @@ merge_widget_value (widget_value *val1, change = max (change, VISIBLE_CHANGE); dupstring (&val1->key, val2->key); } - if (! EQ (val1->help, val2->help)) + if (!EQ (gc_handle_value (val1->help), + gc_handle_value (val2->help))) { EXPLAIN (val1->name, change, VISIBLE_CHANGE, "help change", val1->help, val2->help); change = max (change, VISIBLE_CHANGE); - val1->help = val2->help; + gc_handle_assign (&val1->help, val2->help); } if (val1->enabled != val2->enabled) { diff --git a/src/gc-handles.c b/src/gc-handles.c index eef307f4f69..c223b3cc676 100644 --- a/src/gc-handles.c +++ b/src/gc-handles.c @@ -154,6 +154,19 @@ gc_handle_for_pvec (union vectorlike_header *h) return gc_handle_for (obj); } +gc_handle +gc_handle_for_gc_handle (gc_handle gch) +{ + return gc_handle_for (gc_handle_value (gch)); +} + +void +gc_handle_assign (gc_handle *dst, gc_handle src) +{ + free_gc_handle (*dst); + *dst = gc_handle_for_gc_handle (src); +} + DEFUN ("gc-handles-info", Fgc_handles_info, Sgc_handles_info, 0, 0, 0, doc: /* Return information about registered GC handles. Return value is an list with the following entries: diff --git a/src/gc-handles.h b/src/gc-handles.h index 3abdd06fe48..4c1bcc46664 100644 --- a/src/gc-handles.h +++ b/src/gc-handles.h @@ -27,9 +27,12 @@ typedef struct gc_handle_struct *gc_handle; gc_handle gc_handle_for (Lisp_Object); gc_handle gc_handle_for_pvec (union vectorlike_header *); +gc_handle gc_handle_for_gc_handle (gc_handle src); void free_gc_handle (gc_handle); Lisp_Object gc_handle_value (gc_handle); +void gc_handle_assign (gc_handle *dst, gc_handle src); + void syms_of_gc_handles (void); #endif diff --git a/src/gtkutil.c b/src/gtkutil.c index ec6615f6ed2..0afd9b4a91b 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -3354,8 +3354,11 @@ make_menu_item (const char *utf8_label, if (! item->enabled) gtk_widget_set_sensitive (w, FALSE); #ifdef HAVE_PGTK - if (!NILP (item->help)) - gtk_widget_set_tooltip_text (w, SSDATA (item->help)); + { + Lisp_Object help = gc_handle_value (item->help); + if (!NILP (help)) + gtk_widget_set_tooltip_text (w, SSDATA (help)); + } #endif return w; @@ -3401,7 +3404,7 @@ xg_create_one_menuitem (widget_value *item, xg_list_insert (&xg_menu_item_cb_list, &cb_data->ptrs); cb_data->select_id = 0; - cb_data->help = gc_handle_for (item->help); + cb_data->help = gc_handle_for_gc_handle (item->help); cb_data->cl_data = cl_data; cb_data->call_data = item->call_data; @@ -3985,8 +3988,7 @@ xg_update_menu_item (widget_value *val, if (cb_data) { cb_data->call_data = val->call_data; - free_gc_handle (cb_data->help); - cb_data->help = gc_handle_for (val->help); + gc_handle_assign (&cb_data->help, val->help); cb_data->cl_data = cl_data; /* We assume the callback functions don't change. */ diff --git a/src/menu.c b/src/menu.c index 69fd3867002..c66e03a33e3 100644 --- a/src/menu.c +++ b/src/menu.c @@ -581,7 +581,7 @@ make_widget_value (const char *name, char *value, wv->name = (char *) name; wv->value = value; wv->enabled = enabled; - wv->help = help; + wv->help = gc_handle_for (help); return wv; } @@ -596,6 +596,7 @@ free_menubar_widget_value_tree (widget_value *wv) if (! wv) return; wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; + free_gc_handle (wv->help); if (wv->contents && (wv->contents != (widget_value *) 1)) { diff --git a/src/xmenu.c b/src/xmenu.c index 29e4ea51d75..eafed9a512c 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -772,7 +772,7 @@ static void menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data) { widget_value *wv = call_data; - Lisp_Object help = wv ? wv->help : Qnil; + Lisp_Object help = wv ? gc_handle_value (wv->help) : Qnil; /* Determine the frame for the help event. */ struct frame *f = menubar_id_to_frame (id);