Index: gtktreemodel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreemodel.c,v
retrieving revision 1.104
diff -u -p -r1.104 gtktreemodel.c
--- gtktreemodel.c	7 Apr 2003 00:16:40 -0000	1.104
+++ gtktreemodel.c	11 Jul 2003 18:20:14 -0000
@@ -36,6 +36,7 @@
       (Iter)->user_data3 = NULL; \
     }G_STMT_END
 
+#define ROW_REF_DATA_STRING "gtk-tree-row-refs"
 
 enum {
   ROW_CHANGED,
@@ -48,15 +49,29 @@ enum {
 
 static guint tree_model_signals[LAST_SIGNAL] = { 0 };
 
-
 struct _GtkTreePath
 {
   gint depth;
   gint *indices;
 };
 
-static void gtk_tree_model_base_init (gpointer g_class);
+typedef struct
+{
+  GSList *list;
+} RowRefList;
+
+static void      gtk_tree_model_base_init   (gpointer     g_class);
+static GClosure *create_local_closure       (gint         signal);
 
+static void      gtk_tree_row_ref_inserted  (RowRefList  *refs,
+                                             GtkTreePath *path,
+                                             GtkTreeIter *iter);
+static void      gtk_tree_row_ref_deleted   (RowRefList  *refs,
+                                             GtkTreePath *path);
+static void      gtk_tree_row_ref_reordered (RowRefList  *refs,
+                                             GtkTreePath *path,
+                                             GtkTreeIter *iter,
+                                             gint        *new_order);
 
 GType
 gtk_tree_model_get_type (void)
@@ -95,6 +110,12 @@ gtk_tree_model_base_init (gpointer g_cla
 
   if (! initialized)
     {
+      GType row_inserted_params[] = { GTK_TYPE_TREE_PATH, GTK_TYPE_TREE_ITER };
+      GType row_deleted_params[] = { GTK_TYPE_TREE_PATH };
+      GType rows_reordered_params[] = { GTK_TYPE_TREE_PATH,
+                                        GTK_TYPE_TREE_ITER,
+                                        G_TYPE_POINTER };
+
       tree_model_signals[ROW_CHANGED] =
         g_signal_new ("row_changed",
                       GTK_TYPE_TREE_MODEL,
@@ -106,15 +127,14 @@ gtk_tree_model_base_init (gpointer g_cla
                       GTK_TYPE_TREE_PATH,
                       GTK_TYPE_TREE_ITER);
       tree_model_signals[ROW_INSERTED] =
-        g_signal_new ("row_inserted",
-                      GTK_TYPE_TREE_MODEL,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (GtkTreeModelIface, row_inserted),
-                      NULL, NULL,
-                      _gtk_marshal_VOID__BOXED_BOXED,
-                      G_TYPE_NONE, 2,
-                      GTK_TYPE_TREE_PATH,
-                      GTK_TYPE_TREE_ITER);
+        g_signal_newv ("row_inserted",
+                       GTK_TYPE_TREE_MODEL,
+                       G_SIGNAL_RUN_FIRST,
+                       create_local_closure (ROW_INSERTED),
+                       NULL, NULL,
+                       _gtk_marshal_VOID__BOXED_BOXED,
+                       G_TYPE_NONE, 2,
+                       row_inserted_params);
       tree_model_signals[ROW_HAS_CHILD_TOGGLED] =
         g_signal_new ("row_has_child_toggled",
                       GTK_TYPE_TREE_MODEL,
@@ -126,29 +146,140 @@ gtk_tree_model_base_init (gpointer g_cla
                       GTK_TYPE_TREE_PATH,
                       GTK_TYPE_TREE_ITER);
       tree_model_signals[ROW_DELETED] =
-        g_signal_new ("row_deleted",
-                      GTK_TYPE_TREE_MODEL,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (GtkTreeModelIface, row_deleted),
-                      NULL, NULL,
-                      _gtk_marshal_VOID__BOXED,
-                      G_TYPE_NONE, 1,
-                      GTK_TYPE_TREE_PATH);
+        g_signal_newv ("row_deleted",
+                       GTK_TYPE_TREE_MODEL,
+                       G_SIGNAL_RUN_FIRST,
+                       create_local_closure (ROW_DELETED),
+                       NULL, NULL,
+                       _gtk_marshal_VOID__BOXED,
+                       G_TYPE_NONE, 1,
+                       row_deleted_params);
       tree_model_signals[ROWS_REORDERED] =
-        g_signal_new ("rows_reordered",
-                      GTK_TYPE_TREE_MODEL,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (GtkTreeModelIface, rows_reordered),
-                      NULL, NULL,
-                      _gtk_marshal_VOID__BOXED_BOXED_POINTER,
-                      G_TYPE_NONE, 3,
-                      GTK_TYPE_TREE_PATH,
-                      GTK_TYPE_TREE_ITER,
-                      G_TYPE_POINTER);
+        g_signal_newv ("rows_reordered",
+                       GTK_TYPE_TREE_MODEL,
+                       G_SIGNAL_RUN_FIRST,
+                       create_local_closure (ROWS_REORDERED),
+                       NULL, NULL,
+                       _gtk_marshal_VOID__BOXED_BOXED_POINTER,
+                       G_TYPE_NONE, 3,
+                       rows_reordered_params);
       initialized = TRUE;
     }
 }
 
+static void
+row_inserted_marshal (GClosure          *closure,
+                      GValue /* out */  *return_value,
+                      guint              n_param_values,
+                      const GValue      *param_values,
+                      gpointer           invocation_hint,
+                      gpointer           marshal_data)
+{
+  GTypeClass *class;
+  gpointer callback;
+  gpointer model = g_value_peek_pointer (param_values + 0);
+
+  gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
+                             (GtkTreePath *)g_value_peek_pointer (param_values + 1),
+                             (GtkTreeIter *)g_value_peek_pointer (param_values + 2));
+
+  /* emit signal */
+  class = G_TYPE_INSTANCE_GET_INTERFACE (model, GTK_TYPE_TREE_MODEL, GTypeClass);
+  callback = G_STRUCT_MEMBER (gpointer, class,
+                              G_STRUCT_OFFSET (GtkTreeModelIface,
+                                               row_inserted));
+  if (callback)
+    closure->marshal (closure,
+                      return_value,
+                      n_param_values, param_values,
+                      invocation_hint,
+                      callback);
+}
+
+static void
+row_deleted_marshal (GClosure          *closure,
+                     GValue /* out */  *return_value,
+                     guint              n_param_values,
+                     const GValue      *param_values,
+                     gpointer           invocation_hint,
+                     gpointer           marshal_data)
+{
+  GTypeClass *class;
+  gpointer callback;
+  gpointer model = g_value_peek_pointer (param_values + 0);
+
+  gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
+                            (GtkTreePath *)g_value_peek_pointer (param_values + 1));
+
+  /* emit signal */
+  class = G_TYPE_INSTANCE_GET_INTERFACE (model, GTK_TYPE_TREE_MODEL, GTypeClass);
+  callback = G_STRUCT_MEMBER (gpointer, class,
+                              G_STRUCT_OFFSET (GtkTreeModelIface,
+                                               row_deleted));
+  if (callback)
+    closure->marshal (closure,
+                      return_value,
+                      n_param_values, param_values,
+                      invocation_hint,
+                      callback);
+}
+
+static void
+rows_reordered_marshal (GClosure          *closure,
+                        GValue /* out */  *return_value,
+                        guint              n_param_values,
+                        const GValue      *param_values,
+                        gpointer           invocation_hint,
+                        gpointer           marshal_data)
+{
+  GTypeClass *class;
+  gpointer callback;
+  gpointer model = g_value_peek_pointer (param_values + 0);
+
+  gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
+                              (GtkTreePath *)g_value_peek_pointer (param_values + 1),
+                              (GtkTreeIter *)g_value_peek_pointer (param_values + 2),
+                              (gint *)g_value_peek_pointer (param_values + 3));
+
+  /* emit signal */
+  class = G_TYPE_INSTANCE_GET_INTERFACE (model, GTK_TYPE_TREE_MODEL, GTypeClass);
+  callback = G_STRUCT_MEMBER (gpointer, class,
+                              G_STRUCT_OFFSET (GtkTreeModelIface,
+                                               rows_reordered));
+  if (callback)
+    closure->marshal (closure,
+                      return_value,
+                      n_param_values, param_values,
+                      invocation_hint,
+                      callback);
+}
+
+static GClosure *
+create_local_closure (gint signal)
+{
+  GClosure *closure;
+
+  closure = g_closure_new_simple (sizeof (GClosure),
+                                  (gpointer) GTK_TYPE_TREE_MODEL);
+
+  switch (signal)
+    {
+      case ROW_INSERTED:
+        g_closure_set_marshal (closure, row_inserted_marshal);
+        break;
+
+      case ROW_DELETED:
+        g_closure_set_marshal (closure, row_deleted_marshal);
+        break;
+
+      case ROWS_REORDERED:
+        g_closure_set_marshal (closure, rows_reordered_marshal);
+        break;
+    };
+
+  return closure;
+}
+
 /**
  * gtk_tree_path_new:
  *
@@ -1359,8 +1490,6 @@ gtk_tree_row_reference_get_type (void)
 }
 
 
-#define ROW_REF_DATA_STRING "gtk-tree-row-refs"
-
 struct _GtkTreeRowReference
 {
   GObject *proxy;
@@ -1368,11 +1497,6 @@ struct _GtkTreeRowReference
   GtkTreePath *path;
 };
 
-typedef struct
-{
-  GSList *list;
-} RowRefList;
-
 
 static void
 release_row_references (gpointer data)
@@ -1399,13 +1523,10 @@ release_row_references (gpointer data)
 }
 
 static void
-gtk_tree_row_ref_inserted_callback (GObject     *object,
-				    GtkTreePath *path,
-				    GtkTreeIter *iter,
-				    gpointer     data)
+gtk_tree_row_ref_inserted (RowRefList  *refs,
+			   GtkTreePath *path,
+			   GtkTreeIter *iter)
 {
-  RowRefList *refs = g_object_get_data (data, ROW_REF_DATA_STRING);
-
   GSList *tmp_list;
 
   if (refs == NULL)
@@ -1454,11 +1575,9 @@ gtk_tree_row_ref_inserted_callback (GObj
 }
 
 static void
-gtk_tree_row_ref_deleted_callback (GObject     *object,
-				   GtkTreePath *path,
-				   gpointer     data)
+gtk_tree_row_ref_deleted (RowRefList  *refs,
+			  GtkTreePath *path)
 {
-  RowRefList *refs = g_object_get_data (data, ROW_REF_DATA_STRING);
   GSList *tmp_list;
 
   if (refs == NULL)
@@ -1515,13 +1634,11 @@ next:
 }
 
 static void
-gtk_tree_row_ref_reordered_callback (GObject     *object,
-				     GtkTreePath *path,
-				     GtkTreeIter *iter,
-				     gint        *new_order,
-				     gpointer     data)
+gtk_tree_row_ref_reordered (RowRefList  *refs,
+			    GtkTreePath *path,
+			    GtkTreeIter *iter,
+			    gint        *new_order)
 {
-  RowRefList *refs = g_object_get_data (data, ROW_REF_DATA_STRING);
   GSList *tmp_list;
   gint length;
 
@@ -1563,26 +1680,7 @@ gtk_tree_row_ref_reordered_callback (GOb
 
       tmp_list = g_slist_next (tmp_list);
     }
-  
 }
-     
-static void
-connect_ref_callbacks (GtkTreeModel *model)
-{
-  g_signal_connect (model,
-		    "row_inserted",
-		    G_CALLBACK (gtk_tree_row_ref_inserted_callback),
-		    model);
-  g_signal_connect (model,
-		    "row_deleted",
-		    G_CALLBACK (gtk_tree_row_ref_deleted_callback),
-		    model);
-  g_signal_connect (model,
-		    "rows_reordered",
-		    G_CALLBACK (gtk_tree_row_ref_reordered_callback),
-		    model);
-}
-
 
 /* We do this recursively so that we can unref children nodes before their parent */
 static void
@@ -1617,26 +1715,6 @@ gtk_tree_row_reference_unref_path (GtkTr
   gtk_tree_model_unref_node (model, &iter);
 }
 
-static void
-disconnect_ref_callbacks (GtkTreeModel *model)
-{
-  g_signal_handlers_disconnect_matched (model,
-                                        G_SIGNAL_MATCH_FUNC,
-                                        0, 0, NULL,
-					gtk_tree_row_ref_inserted_callback,
-					NULL);
-  g_signal_handlers_disconnect_matched (model,
-                                        G_SIGNAL_MATCH_FUNC,
-                                        0, 0, NULL,
-					gtk_tree_row_ref_deleted_callback,
-					NULL);
-  g_signal_handlers_disconnect_matched (model,
-                                        G_SIGNAL_MATCH_FUNC,
-                                        0, 0, NULL,
-					gtk_tree_row_ref_reordered_callback,
-					NULL);
-}
-
 /**
  * gtk_tree_row_reference_new:
  * @model: A #GtkTreeModel
@@ -1728,9 +1806,6 @@ gtk_tree_row_reference_new_proxy (GObjec
       refs = g_new (RowRefList, 1);
       refs->list = NULL;
 
-      if (G_OBJECT (model) == proxy)
-	connect_ref_callbacks (model);
-
       g_object_set_data_full (G_OBJECT (proxy),
 			      ROW_REF_DATA_STRING,
                               refs, release_row_references);
@@ -1827,9 +1902,6 @@ gtk_tree_row_reference_free (GtkTreeRowR
 
   if (refs->list == NULL)
     {
-      if (G_OBJECT (reference->model) == reference->proxy)
-	disconnect_ref_callbacks (reference->model);
-
       g_object_set_data (G_OBJECT (reference->proxy),
 			 ROW_REF_DATA_STRING,
 			 NULL);
@@ -1860,8 +1932,7 @@ gtk_tree_row_reference_inserted (GObject
 {
   g_return_if_fail (G_IS_OBJECT (proxy));
 
-  gtk_tree_row_ref_inserted_callback (NULL, path, NULL, proxy);
-  
+  gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, NULL);
 }
 
 /**
@@ -1878,7 +1949,7 @@ gtk_tree_row_reference_deleted (GObject 
 {
   g_return_if_fail (G_IS_OBJECT (proxy));
 
-  gtk_tree_row_ref_deleted_callback (NULL, path, proxy);
+  gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path);
 }
 
 /**
@@ -1899,7 +1970,5 @@ gtk_tree_row_reference_reordered (GObjec
 {
   g_return_if_fail (G_IS_OBJECT (proxy));
 
-  gtk_tree_row_ref_reordered_callback (NULL, path, iter, new_order, proxy);
+  gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, iter, new_order);
 }
-  
-
