Index: gtk+/gtk/gtk.def
===================================================================
--- gtk+/gtk/gtk.def	(revision 1588)
+++ gtk+/gtk/gtk.def	(working copy)
@@ -2545,7 +2545,8 @@
 	gtk_tree_view_get_model
 	gtk_tree_view_get_path_at_pos
 	gtk_tree_view_get_reorderable
-	gtk_tree_view_get_row_separator_func
+	gtk_tree_view_get_row_separator_func
+	gtk_tree_view_get_row_background_color_func
 	gtk_tree_view_get_rules_hint
 	gtk_tree_view_get_search_column
 	gtk_tree_view_get_search_equal_func
@@ -2580,7 +2581,8 @@
 	gtk_tree_view_set_hover_selection
 	gtk_tree_view_set_model
 	gtk_tree_view_set_reorderable
-	gtk_tree_view_set_row_separator_func
+	gtk_tree_view_set_row_separator_func
+	gtk_tree_view_set_row_background_color_func
 	gtk_tree_view_set_rules_hint
 	gtk_tree_view_set_search_column
 	gtk_tree_view_set_search_equal_func
Index: gtk+/gtk/gtktreeprivate.h
===================================================================
--- gtk+/gtk/gtktreeprivate.h	(revision 1588)
+++ gtk+/gtk/gtktreeprivate.h	(working copy)
@@ -232,6 +232,10 @@
   GtkTreeViewRowSeparatorFunc row_separator_func;
   gpointer row_separator_data;
   GtkDestroyNotify row_separator_destroy;
+
+  GtkTreeViewRowBackgroundColorFunc row_background_color_func;
+  gpointer row_background_color_data;
+  GtkDestroyNotify row_background_color_destroy;
 };
 
 #ifdef __GNUC__
Index: gtk+/gtk/gtktreeview.c
===================================================================
--- gtk+/gtk/gtktreeview.c	(revision 1588)
+++ gtk+/gtk/gtktreeview.c	(working copy)
@@ -1407,9 +1407,19 @@
   if (tree_view->priv->row_separator_destroy)
     {
       (* tree_view->priv->row_separator_destroy) (tree_view->priv->row_separator_data);
+      tree_view->priv->row_separator_func = NULL;
       tree_view->priv->row_separator_data = NULL;
+      tree_view->priv->row_separator_destroy = NULL;
     }
   
+  if (tree_view->priv->row_background_color_destroy)
+    {
+      (* tree_view->priv->row_background_color_destroy) (tree_view->priv->row_background_color_data);
+      tree_view->priv->row_background_color_func = NULL;
+      tree_view->priv->row_background_color_data = NULL;
+      tree_view->priv->row_background_color_destroy = NULL;
+    }
+
   gtk_tree_view_set_model (tree_view, NULL);
 
   if (tree_view->priv->hadjustment)
@@ -3572,6 +3582,8 @@
 	  GtkTreeViewColumn *column = list->data;
 	  const gchar *detail = NULL;
 	  GtkStateType state;
+	  gboolean has_custom_color;
+	  GdkColor custom_color;
 
 	  if (!column->visible)
             continue;
@@ -3614,49 +3626,6 @@
 						   GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT),
 						   node->children?TRUE:FALSE);
 
-          /* Select the detail for drawing the cell.  relevant
-           * factors are parity, sortedness, and whether to
-           * display rules.
-           */
-          if (allow_rules && tree_view->priv->has_rules)
-            {
-              if ((flags & GTK_CELL_RENDERER_SORTED) &&
-		  n_visible_columns >= 3)
-                {
-                  if (parity)
-                    detail = "cell_odd_ruled_sorted";
-                  else
-                    detail = "cell_even_ruled_sorted";
-                }
-              else
-                {
-                  if (parity)
-                    detail = "cell_odd_ruled";
-                  else
-                    detail = "cell_even_ruled";
-                }
-            }
-          else
-            {
-              if ((flags & GTK_CELL_RENDERER_SORTED) &&
-		  n_visible_columns >= 3)
-                {
-                  if (parity)
-                    detail = "cell_odd_sorted";
-                  else
-                    detail = "cell_even_sorted";
-                }
-              else
-                {
-                  if (parity)
-                    detail = "cell_odd";
-                  else
-                    detail = "cell_even";
-                }
-            }
-
-          g_assert (detail);
-
 	  if (widget->state == GTK_STATE_INSENSITIVE)
 	    state = GTK_STATE_INSENSITIVE;	    
 	  if (flags & GTK_CELL_RENDERER_SELECTED)
@@ -3664,19 +3633,93 @@
 	  else
 	    state = GTK_STATE_NORMAL;
 
-	  /* Draw background */
-          gtk_paint_flat_box (widget->style,
-                              event->window,
-			      state,
-                              GTK_SHADOW_NONE,
-                              &event->area,
-                              widget,
-                              detail,
-                              background_area.x,
-                              background_area.y,
-                              background_area.width,
-                              background_area.height);
+	  has_custom_color = tree_view->priv->row_background_color_func
+	                     && tree_view->priv->row_background_color_func (tree_view->priv->model,
+									    &iter,
+									    state == GTK_STATE_SELECTED,
+									    &custom_color,
+									    tree_view->priv->row_background_color_data);
 
+	  if (has_custom_color)
+	    {
+	      /* Draw background in custom color */
+	      GdkRectangle draw;
+	      GdkGC *gc;
+
+	      if (gdk_rectangle_intersect (&event->area, &background_area, &draw))
+		{
+		  gc = gdk_gc_new (event->window);
+		  gdk_gc_copy (gc, widget->style->base_gc[state]);
+		  gdk_gc_set_rgb_fg_color (gc, &custom_color);
+		  gdk_draw_rectangle (event->window,
+				      gc,
+				      TRUE,
+				      draw.x,
+				      draw.y,
+				      draw.width,
+				      draw.height);
+		  g_object_unref (gc);
+		}
+	    }
+	  else
+	    {
+	      /* Select the detail for drawing the cell.  relevant
+	       * factors are parity, sortedness, and whether to
+	       * display rules.
+	       */
+	      if (allow_rules && tree_view->priv->has_rules)
+		{
+		  if ((flags & GTK_CELL_RENDERER_SORTED) &&
+		      n_visible_columns >= 3)
+		    {
+		      if (parity)
+			detail = "cell_odd_ruled_sorted";
+		      else
+			detail = "cell_even_ruled_sorted";
+		    }
+		  else
+		    {
+		      if (parity)
+			detail = "cell_odd_ruled";
+		      else
+			detail = "cell_even_ruled";
+		    }
+		}
+	      else
+		{
+		  if ((flags & GTK_CELL_RENDERER_SORTED) &&
+		      n_visible_columns >= 3)
+		    {
+		      if (parity)
+			detail = "cell_odd_sorted";
+		      else
+			detail = "cell_even_sorted";
+		    }
+		  else
+		    {
+		      if (parity)
+			detail = "cell_odd";
+		      else
+			detail = "cell_even";
+		    }
+		}
+
+	      g_assert (detail);
+
+	      /* Draw background */
+	      gtk_paint_flat_box (widget->style,
+				  event->window,
+				  state,
+				  GTK_SHADOW_NONE,
+				  &event->area,
+				  widget,
+				  detail,
+				  background_area.x,
+				  background_area.y,
+				  background_area.width,
+				  background_area.height);
+	    }
+
 	  if (gtk_tree_view_is_expander_column (tree_view, column) &&
               TREE_VIEW_DRAW_EXPANDERS(tree_view))
 	    {
@@ -13058,6 +13101,54 @@
   tree_view->priv->row_separator_destroy = destroy;
 }
 
+/**
+ * gtk_tree_view_get_row_background_color_func:
+ * @tree_view: a #GtkTreeView
+ * 
+ * Returns the current row background color function.
+ * 
+ * Return value: the current row background color function.
+ *
+ * Since: 2.10
+ **/
+GtkTreeViewRowBackgroundColorFunc
+gtk_tree_view_get_row_background_color_func (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
+
+  return tree_view->priv->row_background_color_func;
+}
+
+/**
+ * gtk_tree_view_set_row_background_color_func:
+ * @tree_view: a #GtkTreeView
+ * @func: a #GtkTreeViewRowBackgroundColorFunc
+ * @data: user data to pass to @func, or %NULL
+ * @destroy: destroy notifier for @data, or %NULL
+ * 
+ * Sets the row background color function, which is used to define
+ * custom background colors for rows. If the row background color
+ * function is %NULL (the default value), or the function returns
+ * %FALSE, then the normal colors are used.
+ *
+ * Since: 2.10
+ **/
+void
+gtk_tree_view_set_row_background_color_func (GtkTreeView     *tree_view,
+					     GtkTreeViewRowBackgroundColorFunc func,
+					     gpointer         data,
+					     GtkDestroyNotify destroy)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+  if (tree_view->priv->row_background_color_destroy)
+    (* tree_view->priv->row_background_color_destroy) (tree_view->priv->row_background_color_data);
+
+  tree_view->priv->row_background_color_func = func;
+  tree_view->priv->row_background_color_data = data;
+  tree_view->priv->row_background_color_destroy = destroy;
+}
+
   
 static void
 gtk_tree_view_grab_notify (GtkWidget *widget,
Index: gtk+/gtk/gtktreeview.h
===================================================================
--- gtk+/gtk/gtktreeview.h	(revision 1588)
+++ gtk+/gtk/gtktreeview.h	(working copy)
@@ -127,6 +127,11 @@
 typedef gboolean (*GtkTreeViewRowSeparatorFunc) (GtkTreeModel      *model,
 						 GtkTreeIter       *iter,
 						 gpointer           data);
+typedef gboolean (*GtkTreeViewRowBackgroundColorFunc) (GtkTreeModel *model,
+						       GtkTreeIter  *iter,
+						       gboolean      selected,
+						       GdkColor     *color,
+						       gpointer      data);
 
 
 /* Creators */
@@ -332,6 +337,13 @@
 								  gpointer                    data,
 								  GtkDestroyNotify            destroy);
 
+GtkTreeViewRowBackgroundColorFunc
+     gtk_tree_view_get_row_background_color_func (GtkTreeView     *tree_view);
+void gtk_tree_view_set_row_background_color_func (GtkTreeView     *tree_view,
+						  GtkTreeViewRowBackgroundColorFunc func,
+						  gpointer         data,
+						  GtkDestroyNotify destroy);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
