? my.patch
? mygtk.patch
Index: src/java/org/gnu/gtk/TreeStore.java
===================================================================
RCS file: /cvs/gnome/libgtk-java/src/java/org/gnu/gtk/TreeStore.java,v
retrieving revision 1.41
diff -u -r1.41 TreeStore.java
--- src/java/org/gnu/gtk/TreeStore.java	9 Jul 2006 16:23:57 -0000	1.41
+++ src/java/org/gnu/gtk/TreeStore.java	27 Feb 2007 15:55:10 -0000
@@ -877,6 +877,15 @@
         gtk_tree_store_reorder(getHandle(), iter.getHandle(), newOrder);
     }
 
+    protected void finalize () throws Throwable{
+	System.out.println("finalize " + this);
+	// we want to make sure the jave clear function
+	// is called so that any java objects which need
+	// to be freed are freed.
+	this.clear(); 
+	super.finalize();
+    }
+
     // native static final protected int getRoot(int cptr);
     // native final protected void setRoot(int cptr, int root);
     // native static final protected int getLast(int cptr);
Index: src/jni/org_gnu_gtk_TreeStore.c
===================================================================
RCS file: /cvs/gnome/libgtk-java/src/jni/org_gnu_gtk_TreeStore.c,v
retrieving revision 1.14
diff -u -r1.14 org_gnu_gtk_TreeStore.c
--- src/jni/org_gnu_gtk_TreeStore.c	28 Feb 2006 02:43:33 -0000	1.14
+++ src/jni/org_gnu_gtk_TreeStore.c	27 Feb 2007 15:55:11 -0000
@@ -12,12 +12,22 @@
 #include <gtk/gtk.h>
 #include <jg_jnu.h>
 #include "gtk_java.h"
-
+#include "gtk/gtktreemodel.h"
+          
 #include "org_gnu_gtk_TreeStore.h"
 #ifdef __cplusplus
 extern "C" 
 {
 #endif
+  
+static void free_if_java_object(JNIEnv *env, GtkTreeStore* treeStore, GtkTreeIter* iter, gint column);
+static gboolean foreach_function_free_if_java_object(GtkTreeModel *model,
+						     GtkTreePath *path,
+						     GtkTreeIter *iter,
+						     gpointer data);
+static void free_if_java_object_all_cols(JNIEnv *env, 
+					 GtkTreeStore* treeStore,
+					 GtkTreeIter* iter);
 
 static jobject getTreeIter(JNIEnv* env, GtkTreeIter* iter)
 {
@@ -275,6 +285,17 @@
     GtkTreeIter *iter_g = (GtkTreeIter *)getPointerFromHandle(env, iter);
     gint32 columnt_g = (gint32) columnt;
     GValue *value_g = (GValue *)getPointerFromHandle(env, value);
+    
+    
+    free_if_java_object(env, treeStore_g, iter_g, columnt_g);
+    
+    if ( G_VALUE_HOLDS_POINTER(value_g) ){
+      gpointer java_pointer = g_value_get_pointer (value_g);
+      if(java_pointer != NULL){
+	g_value_set_pointer (value_g, (*env)->NewGlobalRef(env, (jobject)java_pointer));
+      }
+    }
+
     gtk_tree_store_set_value (treeStore_g, iter_g, columnt_g, value_g);
 }
 
@@ -288,9 +309,13 @@
     GtkTreeStore *treeStore_g = 
         (GtkTreeStore *)getPointerFromHandle(env, treeStore);
     GtkTreeIter *iter_g = (GtkTreeIter *)getPointerFromHandle(env, iter);
+
+    free_if_java_object_all_cols(env, treeStore_g, iter_g);
+
     gtk_tree_store_remove (treeStore_g, iter_g);
 }
 
+
 /*
  * Class:     org.gnu.gtk.TreeStore
  * Method:    gtk_tree_store_insert
@@ -304,6 +329,7 @@
     GtkTreeIter *iter_g = (GtkTreeIter *)g_malloc(sizeof(GtkTreeIter));
     GtkTreeIter *parent_g = (GtkTreeIter *)getPointerFromHandle(env, parent);
     gint32 position_g = (gint32) position;
+
     gtk_tree_store_insert (treeStore_g, iter_g, parent_g, position_g);
     return getTreeIter(env, iter_g);
 }
@@ -411,6 +437,12 @@
 {
     GtkTreeStore *treeStore_g = 
         (GtkTreeStore *)getPointerFromHandle(env, treeStore);
+    
+    
+    gtk_tree_model_foreach ((GtkTreeModel*) treeStore_g,
+			    (GtkTreeModelForeachFunc)foreach_function_free_if_java_object ,
+			    (gpointer)env);
+
     gtk_tree_store_clear (treeStore_g);
 }
 
@@ -483,6 +515,46 @@
     gtk_tree_store_move_after(treeStore_g, iter_g, pos_g);
 }
 
+static gboolean foreach_function_free_if_java_object(GtkTreeModel *model,
+					      GtkTreePath *path,
+					      GtkTreeIter *iter,
+					      gpointer data){
+  
+  free_if_java_object_all_cols((JNIEnv*)data, (GtkTreeStore*)model, iter);
+}
+
+
+/*
+ * Calls free_if_java_object for each column in the row pointed to
+ * by iter
+ */
+static void free_if_java_object_all_cols(JNIEnv *env, GtkTreeStore* treeStore, GtkTreeIter* iter){
+  gint n = gtk_tree_model_get_n_columns((GtkTreeModel*)treeStore);
+  
+  int i;
+  for(i=0;i<n;i++){
+    free_if_java_object(env, treeStore, iter, i);
+  }
+}
+
+/*
+ * Check if the given tree iter points to a java object
+ * if so decrement the refrences to it.
+ */
+static void free_if_java_object(JNIEnv *env, GtkTreeStore* treeStore, GtkTreeIter* iter, gint column)
+{
+  //Check of the old value holds a java object which needs to be freed
+  GValue* old_value = (GValue*)g_malloc(sizeof(GValue));
+  old_value->g_type = 0;
+  gtk_tree_model_get_value((GtkTreeModel*)treeStore, iter, column, old_value);
+  if ( G_VALUE_HOLDS_POINTER(old_value) ){
+    gpointer java_pointer = g_value_get_pointer (old_value);
+    if(java_pointer != NULL){
+      (*env)->DeleteGlobalRef(env, (jobject)java_pointer);
+    }
+  }
+  g_free(old_value);
+}
 
 #ifdef __cplusplus
 }
