Index: gobject/gobject.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.c,v
retrieving revision 1.82
diff -u -p -r1.82 gobject.c
--- gobject/gobject.c	30 Sep 2006 13:59:01 -0000	1.82
+++ gobject/gobject.c	29 Nov 2006 17:44:53 -0000
@@ -263,6 +263,8 @@ g_object_do_class_init (GObjectClass *cl
   class->dispose = g_object_real_dispose;
   class->finalize = g_object_finalize;
   class->dispatch_properties_changed = g_object_dispatch_properties_changed;
+  class->connect_closure = _g_signal_real_connect_closure_by_node;
+  class->handler_disconnect = _g_signal_real_handler_disconnect;
   class->notify = NULL;
 
   gobject_signals[NOTIFY] =
Index: gobject/gobject.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.h,v
retrieving revision 1.38
diff -u -p -r1.38 gobject.h
--- gobject/gobject.h	23 Aug 2006 08:46:21 -0000	1.38
+++ gobject/gobject.h	29 Nov 2006 17:44:53 -0000
@@ -110,9 +110,18 @@ struct  _GObjectClass
   /* signals */
   void	     (*notify)			(GObject	*object,
 					 GParamSpec	*pspec);
+
+  /* signal connect/disconnect hooks */
+  gulong     (*connect_closure)         (gpointer        instance,
+					 GSignalNode	*node,
+					 GQuark		 detail,
+					 GClosure	*closure,
+					 gboolean	 after);
+  void	     (*handler_disconnect)	(gpointer	 instance,
+      					 gulong		 handler_id);
   /*< private >*/
   /* padding */
-  gpointer	pdummy[8];
+  gpointer	pdummy[6];
 };
 struct _GObjectConstructParam
 {
Index: gobject/gsignal.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gsignal.c,v
retrieving revision 1.67
diff -u -p -r1.67 gsignal.c
--- gobject/gsignal.c	30 Sep 2006 13:59:01 -0000	1.67
+++ gobject/gsignal.c	29 Nov 2006 17:44:53 -0000
@@ -1533,6 +1533,42 @@ g_signal_get_invocation_hint (gpointer i
 }
 
 gulong
+_g_signal_real_connect_closure_by_node (gpointer     instance,
+					GSignalNode *gnode,
+					GQuark       detail,
+					GClosure    *closure,
+					gboolean     after)
+{
+  SignalNode *node = (SignalNode *) gnode;
+  Handler *handler = handler_new (after);
+  gulong handler_seq_no = 0;
+  
+  handler_seq_no = handler->sequential_number;
+  handler->detail = detail;
+  handler->closure = g_closure_ref (closure);
+  g_closure_sink (closure);
+  handler_insert (node->signal_id, instance, handler);
+  if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
+    g_closure_set_marshal (closure, node->c_marshaller);
+  
+  return handler_seq_no;
+}
+
+static gulong
+g_signal_connect_closure_by_node (gpointer     instance,
+				  SignalNode *node,
+				  GQuark       detail,
+				  GClosure    *closure,
+				  gboolean     after)
+{
+  return G_OBJECT_GET_CLASS (instance)->connect_closure (instance,
+							 (GSignalNode *) node,
+							 detail,
+							 closure,
+							 after);
+}
+
+gulong
 g_signal_connect_closure_by_id (gpointer  instance,
 				guint     signal_id,
 				GQuark    detail,
@@ -1555,17 +1591,11 @@ g_signal_connect_closure_by_id (gpointer
       else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
 	g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
       else
-	{
-	  Handler *handler = handler_new (after);
-	  
-	  handler_seq_no = handler->sequential_number;
-	  handler->detail = detail;
-	  handler->closure = g_closure_ref (closure);
-	  g_closure_sink (closure);
-	  handler_insert (signal_id, instance, handler);
-	  if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
-	    g_closure_set_marshal (closure, node->c_marshaller);
-	}
+	handler_seq_no = g_signal_connect_closure_by_node (instance,
+                                                           node,
+                                                           detail,
+                                                           closure,
+                                                           after);
     }
   else
     g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
@@ -1601,17 +1631,11 @@ g_signal_connect_closure (gpointer     i
       else if (!g_type_is_a (itype, node->itype))
 	g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
       else
-	{
-	  Handler *handler = handler_new (after);
-
-	  handler_seq_no = handler->sequential_number;
-	  handler->detail = detail;
-	  handler->closure = g_closure_ref (closure);
-	  g_closure_sink (closure);
-	  handler_insert (signal_id, instance, handler);
-	  if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
-	    g_closure_set_marshal (handler->closure, node->c_marshaller);
-	}
+	handler_seq_no = g_signal_connect_closure_by_node (instance,
+							   node,
+							   detail,
+							   closure,
+							   after);
     }
   else
     g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
@@ -1654,15 +1678,18 @@ g_signal_connect_data (gpointer       in
 	g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
       else
 	{
-	  Handler *handler = handler_new (after);
+	  GClosure *closure;
 
-	  handler_seq_no = handler->sequential_number;
-	  handler->detail = detail;
-	  handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
-	  g_closure_sink (handler->closure);
-	  handler_insert (signal_id, instance, handler);
-	  if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
-	    g_closure_set_marshal (handler->closure, node->c_marshaller);
+	  if (swapped)
+	    closure = g_cclosure_new_swap (c_handler, data, destroy_data);
+	  else
+	    closure = g_cclosure_new (c_handler, data, destroy_data);
+
+	  handler_seq_no = g_signal_connect_closure_by_node (instance,
+							     node,
+							     detail,
+							     closure,
+							     after);
 	}
     }
   else
@@ -1720,15 +1747,12 @@ g_signal_handler_unblock (gpointer insta
 }
 
 void
-g_signal_handler_disconnect (gpointer instance,
-                             gulong   handler_id)
+_g_signal_real_handler_disconnect (gpointer instance,
+                                   gulong   handler_id)
 {
   Handler *handler;
   guint signal_id;
   
-  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
-  g_return_if_fail (handler_id > 0);
-  
   SIGNAL_LOCK ();
   handler = handler_lookup (instance, handler_id, &signal_id);
   if (handler)
@@ -1740,6 +1764,16 @@ g_signal_handler_disconnect (gpointer in
   else
     g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id);
   SIGNAL_UNLOCK ();
+}
+
+void
+g_signal_handler_disconnect (gpointer instance,
+                             gulong   handler_id)
+{
+  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
+  g_return_if_fail (handler_id > 0);
+
+  G_OBJECT_GET_CLASS (instance)->handler_disconnect (instance, handler_id);
 }
 
 gboolean
Index: gobject/gsignal.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gsignal.h,v
retrieving revision 1.38
diff -u -p -r1.38 gsignal.h
--- gobject/gsignal.h	22 Sep 2005 10:48:04 -0000	1.38
+++ gobject/gsignal.h	29 Nov 2006 17:44:53 -0000
@@ -33,6 +33,7 @@ G_BEGIN_DECLS
 /* --- typedefs --- */
 typedef struct _GSignalQuery		 GSignalQuery;
 typedef struct _GSignalInvocationHint	 GSignalInvocationHint;
+typedef struct _GSignalNode		 GSignalNode;
 typedef GClosureMarshal			 GSignalCMarshaller;
 typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,
 					 guint			n_param_values,
@@ -91,6 +92,12 @@ struct _GSignalQuery
   guint		n_params;
   const GType  *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
 };
+struct _GSignalNode
+{
+  guint		signal_id;
+  GType		itype;
+  const gchar  *name;
+};
 
 
 /* --- signals --- */
@@ -264,7 +271,13 @@ gboolean g_signal_accumulator_true_handl
 /*< private >*/
 void	 g_signal_handlers_destroy	      (gpointer		  instance);
 void	 _g_signals_destroy		      (GType		  itype);
-
+gulong _g_signal_real_connect_closure_by_node (gpointer		  instance,
+					       GSignalNode	  *node,
+					       GQuark		   detail,
+					       GClosure		  *closure,
+					       gboolean		   after);
+void	 _g_signal_real_handler_disconnect    (gpointer		   instance,
+					       gulong              handler_id);
 G_END_DECLS
 
 #endif /* __G_SIGNAL_H__ */
