Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libglade/ChangeLog,v
retrieving revision 1.333
diff -u -p -r1.333 ChangeLog
--- ChangeLog	28 Feb 2005 00:16:32 -0000	1.333
+++ ChangeLog	28 Feb 2005 19:00:55 -0000
@@ -1,3 +1,15 @@
+2005-02-28  Tristan Van Berkom <tvb@cvs.gnome.org>
+
+	* glade-init.c: Fix for applications to load properly under win32
+	  (Ivan Wong <email@ivanwong.info>)
+	
+	* glade-xml.c: Non widget fix (This implements non-widgets cleanly
+	  but does not change function signatures and variable names library wide
+	  from "GtkWidget *widget" to "GObject *object").
+
+	* glade-private.[ch], glade-xml.c: Implementation of g_module_lookup for
+	  signal handler user_data arguments.
+	
 2005-02-28  Tor Lillqvist  <tml@novell.com>
 
 	* libglade-zip.in: New file, for building zipfile-based Win32
Index: glade/glade-init.c
===================================================================
RCS file: /cvs/gnome/libglade/glade/glade-init.c,v
retrieving revision 1.19
diff -u -p -r1.19 glade-init.c
--- glade/glade-init.c	19 Aug 2002 13:39:23 -0000	1.19
+++ glade/glade-init.c	28 Feb 2005 19:00:55 -0000
@@ -100,7 +100,13 @@ get_module_path (void)
     if (exe_prefix)
 	default_dir = g_build_filename (exe_prefix, "lib", "libglade", "2.0", NULL);
     else
-	default_dir = g_build_filename (GLADE_LIBDIR, "libglade", "2.0", NULL);
+#ifndef G_OS_WIN32
+        default_dir = g_build_filename (GLADE_LIBDIR, "libglade", "2.0", NULL);
+#else
+        default_dir = g_win32_get_package_installation_subdirectory (NULL,
+                                                                     "libglade-2.0-0.dll",
+                                                                     "/lib/libglade/2.0");
+#endif
     
     module_path = g_strconcat (module_path_env ? module_path_env : "",
 			       module_path_env ? G_SEARCHPATH_SEPARATOR_S : "",
Index: glade/glade-parser.c
===================================================================
RCS file: /cvs/gnome/libglade/glade/glade-parser.c,v
retrieving revision 1.32
diff -u -p -r1.32 glade-parser.c
--- glade/glade-parser.c	11 Nov 2004 08:46:29 -0000	1.32
+++ glade/glade-parser.c	28 Feb 2005 19:00:55 -0000
@@ -327,6 +327,8 @@ handle_signal(GladeParseState *state, co
 	    info.handler = alloc_string(state->interface, attrs[i+1]);
 	else if (!strcmp(attrs[i], "after"))
 	    info.after = attrs[i+1][0] == 'y';
+	else if (!strcmp(attrs[i], "lookup"))
+	    info.lookup = attrs[i+1][0] == 'y';
 	else if (!strcmp(attrs[i], "object"))
 	    info.object = alloc_string(state->interface, attrs[i+1]);
 	else if (!strcmp(attrs[i], "last_modification_time"))
Index: glade/glade-parser.h
===================================================================
RCS file: /cvs/gnome/libglade/glade/glade-parser.h,v
retrieving revision 1.8
diff -u -p -r1.8 glade-parser.h
--- glade/glade-parser.h	25 Apr 2002 15:49:30 -0000	1.8
+++ glade/glade-parser.h	28 Feb 2005 19:00:55 -0000
@@ -38,8 +38,10 @@ typedef struct _GladeSignalInfo GladeSig
 struct _GladeSignalInfo {
     gchar *name;
     gchar *handler;
-    gchar *object; /* NULL if this isn't a connect_object signal */
+    gchar *object; /* represents userdata, if lookup is FALSE, then do connect_object with a
+                    * widget looked up by name, otherwise g_module_lookup() */
     guint after : 1;
+    guint lookup : 1;
 };
 
 typedef struct _GladeAtkActionInfo GladeAtkActionInfo;
Index: glade/glade-private.h
===================================================================
RCS file: /cvs/gnome/libglade/glade/glade-private.h,v
retrieving revision 1.23
diff -u -p -r1.23 glade-private.h
--- glade/glade-private.h	5 Feb 2002 23:26:52 -0000	1.23
+++ glade/glade-private.h	28 Feb 2005 19:00:55 -0000
@@ -64,6 +64,7 @@ struct _GladeSignalData {
     GObject *signal_object;
     char *signal_name;
     char *connect_object; /* or NULL if there is none */
+    gboolean lookup_userdata;
     gboolean signal_after;
 };
 
Index: glade/glade-xml.c
===================================================================
RCS file: /cvs/gnome/libglade/glade/glade-xml.c,v
retrieving revision 1.111
diff -u -p -r1.111 glade-xml.c
--- glade/glade-xml.c	29 Nov 2004 11:05:16 -0000	1.111
+++ glade/glade-xml.c	28 Feb 2005 19:00:55 -0000
@@ -41,6 +41,12 @@
 #  include <libintl.h>
 #endif
 
+/* Used for bookkeeping on the name hash */
+typedef struct {
+    gchar    *name;
+    GladeXML *xml;
+} DestroyData;
+
 static const gchar *glade_xml_tree_key     = "GladeXML::tree";
 static GQuark       glade_xml_tree_id      = 0;
 static const gchar *glade_xml_name_key     = "GladeXML::name";
@@ -48,7 +54,6 @@ static GQuark       glade_xml_name_id   
 static const gchar *glade_xml_tooltips_key = "GladeXML::tooltips";
 static GQuark       glade_xml_tooltips_id  = 0;
 
-
 static void glade_xml_init(GladeXML *xml);
 static void glade_xml_class_init(GladeXMLClass *class);
 
@@ -280,28 +285,40 @@ autoconnect_foreach(const char *signal_h
     if (!g_module_symbol(allsymbols, signal_handler, (gpointer)&func))
 	g_warning("could not find signal handler '%s'.", signal_handler);
     else
-	for (; signals != NULL; signals = signals->next) {
-	    GladeSignalData *data = signals->data;
-	    if (data->connect_object) {
-		GladeXML *self = glade_get_widget_tree(
-					GTK_WIDGET(data->signal_object));
-		GObject *other = g_hash_table_lookup(self->priv->name_hash,
-						       data->connect_object);
-
-		g_signal_connect_object(data->signal_object, data->signal_name,
-			func, other, (data->signal_after ? G_CONNECT_AFTER : 0)
-					| G_CONNECT_SWAPPED);
-	    } else {
-		/* the signal_data argument is just a string, but may
-		 * be helpful for someone */
-		if (data->signal_after)
-		    g_signal_connect_after(data->signal_object,
-					   data->signal_name, func, NULL);
-		else
-		    g_signal_connect(data->signal_object, data->signal_name,
-				     func, NULL);
-	    }
-	}
+        for (; signals != NULL; signals = signals->next) {
+            GladeSignalData *data = signals->data;
+            if (data->connect_object && !data->lookup_userdata) {
+                GladeXML *self = glade_get_widget_tree
+                    (GTK_WIDGET(data->signal_object));
+                GObject *other = g_hash_table_lookup(self->priv->name_hash,
+                                                     data->connect_object);
+ 
+                g_signal_connect_object(data->signal_object, data->signal_name,
+                                        func, other, (data->signal_after ? G_CONNECT_AFTER : 0)
+                                        | G_CONNECT_SWAPPED);
+            } else if (data->connect_object && data->lookup_userdata) {
+                gpointer userdata;
+ 
+                if (!g_module_symbol(allsymbols, data->connect_object, &userdata))
+                    g_warning("could not find user data '%s' for signal handler '%s'.",
+                              data->connect_object, signal_handler);
+                else if (data->signal_after)
+                    g_signal_connect_after(data->signal_object,
+                                           data->signal_name, func, userdata);
+                else
+                    g_signal_connect(data->signal_object, data->signal_name,
+                                     func, userdata);
+            } else {
+                /* the signal_data argument is just a string, but may
+                 * be helpful for someone */
+                if (data->signal_after)
+                    g_signal_connect_after(data->signal_object,
+                                           data->signal_name, func, NULL);
+                else
+                    g_signal_connect(data->signal_object, data->signal_name,
+                                     func, NULL);
+            }
+        }
 }
 
 /**
@@ -727,6 +744,7 @@ glade_xml_add_signals(GladeXML *xml, Gtk
 	data->signal_object = G_OBJECT(w);
 	data->signal_name = sig->name;
 	data->connect_object = sig->object;
+        data->lookup_userdata = sig->lookup;
 	data->signal_after = sig->after;
 
 	list = g_hash_table_lookup(xml->priv->signals, sig->handler);
@@ -1213,7 +1231,7 @@ glade_register_widget(GType type,
     GladeWidgetBuildData *data;
     gpointer old_data;
 
-    g_return_if_fail(g_type_is_a(type, GTK_TYPE_WIDGET));
+    g_return_if_fail(g_type_is_a(type, G_TYPE_OBJECT));
 
     if (glade_build_data_id == 0)
 	glade_build_data_id = g_quark_from_static_string(glade_build_data_key);
@@ -1973,6 +1991,16 @@ glade_xml_handle_internal_child(GladeXML
     glade_xml_set_common_params(self, child, child_info->child);
 }
 
+static void
+glade_xml_finalize_notify (DestroyData *dd, GObject *was_an_object)
+{
+    if (dd->xml) {
+        g_object_remove_weak_pointer (G_OBJECT (dd->xml), (gpointer *)&(dd->xml));
+        g_hash_table_remove(dd->xml->priv->name_hash, dd->name);
+    }
+    g_free (dd->name);
+    g_free (dd);
+}
 
 static void
 glade_xml_widget_destroy(GtkObject *object, GladeXML *xml)
@@ -2007,6 +2035,7 @@ glade_xml_set_common_params(GladeXML *se
 			    GladeWidgetInfo *info)
 {
     GList *tmp;
+    DestroyData *dd;
     const GladeWidgetBuildData *data;
     static GQuark visible_id = 0;
 
@@ -2015,8 +2044,10 @@ glade_xml_set_common_params(GladeXML *se
     glade_xml_add_signals(self, widget, info);
     glade_xml_add_accels(self, widget, info);
 
-    gtk_widget_set_name(widget, info->name);
-    glade_xml_add_accessibility_info(self, widget, info);
+    if (GTK_IS_WIDGET (widget)) {
+        gtk_widget_set_name(widget, info->name);
+        glade_xml_add_accessibility_info(self, widget, info);
+    }
 
     /* store this information as data of the widget. */
     g_object_set_qdata(G_OBJECT(widget), glade_xml_tree_id, self);
@@ -2024,14 +2055,17 @@ glade_xml_set_common_params(GladeXML *se
     /* store widgets in hash table, for easy lookup */
     g_hash_table_insert(self->priv->name_hash, info->name, widget);
 
-    /* set up function to remove widget from GladeXML object's
-     * name_hash on destruction. Use connect_object so the handler is
-     * automatically removed on finalization of the GladeXML
-     * object. */
-    g_signal_connect_object(G_OBJECT(widget), "destroy",
-			    G_CALLBACK(glade_xml_widget_destroy),
-			    G_OBJECT(self), 0);
 
+    /* set up function to remove object from GladeXML object's
+     * name_hash on destruction. Use a weak pointer to ensure
+     * that the GladeXML object isn't accessed after its destruction.
+     */
+    dd        = g_new (DestroyData, 1);
+    dd->name  = g_strdup (info->name);
+    dd->xml   = self;
+    g_object_weak_ref (G_OBJECT (widget), (GWeakNotify)glade_xml_finalize_notify, dd);
+    g_object_add_weak_pointer (G_OBJECT (self), (gpointer *)&(dd->xml));
+    
     /* handle any deferred properties using this widget */
     tmp = self->priv->deferred_props;
     while (tmp) {
@@ -2068,18 +2102,16 @@ glade_xml_set_common_params(GladeXML *se
     }
 
     if (data && data->build_children && info->children) {
-	if (GTK_IS_CONTAINER (widget))
-	    data->build_children(self, widget, info);
-	else
-	    g_warning ("widget %s (%s) has children, but is not a GtkContainer.",
-		       info->name, g_type_name (G_TYPE_FROM_INSTANCE (widget)));
+        data->build_children(self, widget, info);
     }
 
-    if (visible_id == 0)
-	visible_id = g_quark_from_static_string("Libglade::visible");
+    if (GTK_IS_WIDGET (widget)) {
+        if (visible_id == 0)
+            visible_id = g_quark_from_static_string("Libglade::visible");
 
-    if (g_object_get_qdata(G_OBJECT(widget), visible_id))
-	gtk_widget_show(widget);
+        if (g_object_get_qdata(G_OBJECT(widget), visible_id))
+            gtk_widget_show(widget);
+    }
 }
 
 /**
