39892 backport
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt.c
index 71dc328..92deaf7 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/swt.c
@@ -412,6 +412,16 @@
 }
 #endif
 
+#ifndef NO_g_1list_1data
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_g_1list_1data
+	(JNIEnv *env, jclass that, jint arg0)
+{
+	DEBUG_CALL("g_1list_1data\n")
+	
+	return (jint)((GList *)arg0)->data;
+}
+#endif
+
 #ifndef NO_g_1list_1free
 JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_g_1list_1free
 	(JNIEnv *env, jclass that, jint arg0)
@@ -4722,6 +4732,16 @@
 }
 #endif
 
+#ifndef NO_gtk_1tree_1model_1get_1iter_1first
+JNIEXPORT jboolean JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1tree_1model_1get_1iter_1first
+	(JNIEnv *env, jclass that, jint arg0, jint arg1)
+{
+	DEBUG_CALL("gtk_1tree_1model_1get_1iter_1first\n")
+
+	return (jboolean)gtk_tree_model_get_iter_first((GtkTreeModel *)arg0, (GtkTreeIter *)arg1);
+}
+#endif
+
 #ifndef NO_gtk_1tree_1model_1get_1n_1columns
 JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1tree_1model_1get_1n_1columns
 	(JNIEnv *env, jclass that, jint arg0)
@@ -5102,6 +5122,42 @@
 }
 #endif
 
+#ifndef NO_gtk_1tree_1view_1column_1cell_1get_1size
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1tree_1view_1column_1cell_1get_1size
+	(JNIEnv *env, jclass that, jint arg0, jobject arg1, jintArray arg2, jintArray arg3, jintArray arg4, jintArray arg5)
+{
+	GdkRectangle _arg1, *lparg1=NULL;
+	jint *lparg2=NULL;
+	jint *lparg3=NULL;
+	jint *lparg4=NULL;
+	jint *lparg5=NULL;
+	
+	DEBUG_CALL("gtk_1tree_1view_1column_1cell_1get_1size\n")
+	
+	if (arg1) lparg1 = getGdkRectangleFields(env, arg1, &_arg1);
+	if (arg2) lparg2 = (*env)->GetIntArrayElements(env, arg2, NULL);
+	if (arg3) lparg3 = (*env)->GetIntArrayElements(env, arg3, NULL);
+	if (arg4) lparg4 = (*env)->GetIntArrayElements(env, arg4, NULL);
+	if (arg5) lparg5 = (*env)->GetIntArrayElements(env, arg5, NULL);
+	gtk_tree_view_column_cell_get_size((GtkTreeViewColumn *)arg0, (GdkRectangle *)lparg1, (gint *)lparg2, (gint *)lparg3, (gint *)lparg4, (gint *)lparg5);
+	if (arg5) (*env)->ReleaseIntArrayElements(env, arg5, lparg5, 0);
+	if (arg4) (*env)->ReleaseIntArrayElements(env, arg4, lparg4, 0);
+	if (arg3) (*env)->ReleaseIntArrayElements(env, arg3, lparg3, 0);
+	if (arg2) (*env)->ReleaseIntArrayElements(env, arg2, lparg2, 0);
+	if (arg1) setGdkRectangleFields(env, arg1, lparg1);
+}
+#endif
+
+#ifndef NO_gtk_1tree_1view_1column_1cell_1set_1cell_1data
+JNIEXPORT void JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1tree_1view_1column_1cell_1set_1cell_1data
+	(JNIEnv *env, jclass that, jint arg0, jint arg1, jint arg2, jboolean arg3, jboolean arg4)
+{
+	DEBUG_CALL("gtk_1tree_1view_1column_1cell_1set_1cell_1data\n")
+	
+	gtk_tree_view_column_cell_set_cell_data((GtkTreeViewColumn *)arg0, (GtkTreeModel *)arg1, (GtkTreeIter *)arg2, arg3, arg4);
+}
+#endif
+
 #ifndef NO_gtk_1tree_1view_1column_1get_1cell_1renderers
 JNIEXPORT jint JNICALL Java_org_eclipse_swt_internal_gtk_OS_gtk_1tree_1view_1column_1get_1cell_1renderers
 	(JNIEnv *env, jclass that, jint arg0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index f9cbef2..ddce860 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -320,6 +320,7 @@
 public static final synchronized native int g_filename_from_utf8(int opsysstring, int len,  int[] bytes_read, int[] bytes_written, int[] error);
 public static final synchronized native void g_free(int mem);
 public static final synchronized native int g_list_append(int list, int data);
+public static final synchronized native int g_list_data(int list);
 public static final synchronized native void g_list_free(int list);
 public static final synchronized native void g_list_free_1(int list);
 public static final synchronized native int g_list_length(int list);
@@ -694,6 +695,7 @@
 public static final synchronized native void gtk_tooltips_set_tip(int tooltips, int widget, byte[] tip_text, byte[] tip_private);
 public static final synchronized native void gtk_tree_model_get(int tree_model, int iter, int column, int[] ptr, int terminator);
 public static final synchronized native boolean gtk_tree_model_get_iter(int tree_model, int iter, int path);
+public static final synchronized native boolean gtk_tree_model_get_iter_first(int tree_model, int iter);
 public static final synchronized native int gtk_tree_model_get_n_columns(int tree_model);
 public static final synchronized native int gtk_tree_model_get_path(int tree_model, int iter);
 public static final synchronized native boolean gtk_tree_model_iter_children(int model, int iter, int parent);
@@ -729,6 +731,8 @@
 public static final synchronized native boolean gtk_tree_view_collapse_row(int view, int path);
 public static final synchronized native void gtk_tree_view_column_add_attribute(int treeColumn, int cellRenderer, String attribute, int column);
 public static final synchronized native void gtk_tree_view_column_clear(int tree_column);
+public static final synchronized native void gtk_tree_view_column_cell_get_size(int tree_column, GdkRectangle cell_area, int[] x_offset, int[] y_offset, int[] width, int[] height);
+public static final synchronized native void gtk_tree_view_column_cell_set_cell_data(int tree_column, int tree_model, int iter, boolean is_expander, boolean is_expanded);
 public static final synchronized native int gtk_tree_view_column_get_cell_renderers(int tree_column);
 public static final synchronized native boolean gtk_tree_view_column_get_resizable(int column);
 public static final synchronized native int gtk_tree_view_column_get_spacing(int tree_column);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
index 32982db..325a5e7 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
@@ -448,13 +448,29 @@
  */
 public int getItemHeight () {
 	checkWidget();
-	int column = OS.gtk_tree_view_get_column (handle, 0);
-	int list = OS.gtk_tree_view_column_get_cell_renderers (column);
-	int renderer = OS.g_list_nth_data (list, 0);
-	OS.g_list_free (list);
-	int [] w = new int [1], h = new int [1];
-	OS.gtk_cell_renderer_get_size (renderer, handle, null, null, null, w, h);
-	return h [0];
+	int itemCount = OS.gtk_tree_model_iter_n_children (modelHandle, 0);
+	if (itemCount == 0) {
+		int column = OS.gtk_tree_view_get_column (handle, 0);
+		int [] w = new int [1], h = new int [1];
+		OS.gtk_tree_view_column_cell_get_size (column, null, null, null, w, h);
+		return h [0];
+	} else {
+		int iter = OS.g_malloc (OS.GtkTreeIter_sizeof ());
+		OS.gtk_tree_model_get_iter_first (modelHandle, iter);
+		int column = OS.gtk_tree_view_get_column (handle, 0);
+		int renderers = OS.gtk_tree_view_column_get_cell_renderers (column);
+		int list = renderers;
+		while (list != 0) {
+			int renderer = OS.g_list_data (list);
+			OS.gtk_tree_view_column_cell_set_cell_data (column, modelHandle, iter, false, false);
+			list = OS.g_list_next (list);
+		}
+		if (renderers != 0) OS.g_list_free (renderers);
+		int [] w = new int [1], h = new int [1];
+		OS.gtk_tree_view_column_cell_get_size (column, null, null, null, w, h);
+		OS.g_free (iter);
+		return h [0];
+	}
 }
 
 /**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
index 43f1ead..644ab5c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
@@ -754,17 +754,33 @@
  */
 public int getItemHeight () {
 	checkWidget();
-	// FIXME
-	// I (bgs) am not sure what to do with this.
-	// In GTK2, rows may have different heights, so asking
-	// this question will only make sense given the item.
-	if (itemCount == 0) return 15;
-	GdkRectangle rect = new GdkRectangle ();
-	int path = OS.gtk_tree_path_new_first ();
-	OS.gtk_widget_realize (handle);
-	OS.gtk_tree_view_get_cell_area (handle, path, 0, rect);
-	OS.gtk_tree_path_free (path);
-	return rect.height;
+	if (itemCount == 0) {
+		int column = OS.gtk_tree_view_get_column (handle, 0);
+		int [] w = new int [1], h = new int [1];
+		OS.gtk_tree_view_column_cell_get_size (column, null, null, null, w, h);
+		return h [0];
+	} else {
+		int height = 0;
+		int iter = OS.g_malloc (OS.GtkTreeIter_sizeof ());
+		OS.gtk_tree_model_get_iter_first (modelHandle, iter);
+		int columnColumn = Math.max (1, columnCount);
+		for (int i=0; i<columnCount; i++) {
+			int column = OS.gtk_tree_view_get_column (handle, i);
+			int renderers = OS.gtk_tree_view_column_get_cell_renderers (column);
+			int list = renderers;
+			while (list != 0) {
+				int renderer = OS.g_list_data (list);
+				OS.gtk_tree_view_column_cell_set_cell_data (column, modelHandle, iter, false, false);
+				list = OS.g_list_next (list);
+			}
+			if (renderers != 0) OS.g_list_free (renderers);
+			int [] w = new int [1], h = new int [1];
+			OS.gtk_tree_view_column_cell_get_size (column, null, null, null, w, h);
+			height = Math.max (height, h [0]);
+		}
+		OS.g_free (iter);
+		return height;
+	}
 }
 
 /**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
index e18dab3..dce71b0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
@@ -409,16 +409,29 @@
  */
 public int getItemHeight () {
 	checkWidget ();
-	// FIXME
-	// I (bgs) am not sure what to do with this.
-	// In GTK2, rows may have different heights, so asking
-	// this question will only make sense given the item.
-	if (OS.gtk_tree_model_iter_n_children (modelHandle, 0) == 0) return 18;
-	GdkRectangle rect = new GdkRectangle ();
-	int path = OS.gtk_tree_path_new_first ();
-	OS.gtk_tree_view_get_cell_area (handle, path, 0, rect);
-	OS.gtk_tree_path_free (path);
-	return rect.height;
+	int itemCount = OS.gtk_tree_model_iter_n_children (modelHandle, 0);
+	if (itemCount == 0) {
+		int column = OS.gtk_tree_view_get_column (handle, 0);
+		int [] w = new int [1], h = new int [1];
+		OS.gtk_tree_view_column_cell_get_size (column, null, null, null, w, h);
+		return h [0];
+	} else {
+		int iter = OS.g_malloc (OS.GtkTreeIter_sizeof ());
+		OS.gtk_tree_model_get_iter_first (modelHandle, iter);
+		int column = OS.gtk_tree_view_get_column (handle, 0);
+		int renderers = OS.gtk_tree_view_column_get_cell_renderers (column);
+		int list = renderers;
+		while (list != 0) {
+			int renderer = OS.g_list_data (list);
+			OS.gtk_tree_view_column_cell_set_cell_data (column, modelHandle, iter, false, false);
+			list = OS.g_list_next (list);
+		}
+		if (renderers != 0) OS.g_list_free (renderers);
+		int [] w = new int [1], h = new int [1];
+		OS.gtk_tree_view_column_cell_get_size (column, null, null, null, w, h);
+		OS.g_free (iter);
+		return h [0];
+	}
 }
 
 /**