Index: gtk/gtk.symbols
===================================================================
--- gtk/gtk.symbols	(revision 4004)
+++ gtk/gtk.symbols	(working copy)
@@ -4267,6 +4267,7 @@
 gtk_tree_view_get_model
 gtk_tree_view_get_path_at_pos
 gtk_tree_view_get_reorderable
+gtk_tree_view_get_row_background_func
 gtk_tree_view_get_row_separator_func
 gtk_tree_view_get_rubber_banding
 gtk_tree_view_get_rules_hint
@@ -4308,6 +4309,7 @@
 gtk_tree_view_set_hover_selection
 gtk_tree_view_set_model
 gtk_tree_view_set_reorderable
+gtk_tree_view_set_row_background_func
 gtk_tree_view_set_row_separator_func
 gtk_tree_view_set_rubber_banding
 gtk_tree_view_set_rules_hint
Index: gtk/gtktreeprivate.h
===================================================================
--- gtk/gtktreeprivate.h	(revision 4004)
+++ gtk/gtktreeprivate.h	(working copy)
@@ -263,6 +263,10 @@
 
   gboolean tree_lines_enabled;
   GdkGC *tree_line_gc;
+
+  GtkTreeViewRowBackgroundFunc row_background_func;
+  gpointer row_background_data;
+  GtkDestroyNotify row_background_destroy;
 };
 
 #ifdef __GNUC__
Index: gtk/gtktreeview.c
===================================================================
--- gtk/gtktreeview.c	(revision 4017)
+++ gtk/gtktreeview.c	(working copy)
@@ -1604,6 +1604,12 @@
       (* tree_view->priv->row_separator_destroy) (tree_view->priv->row_separator_data);
       tree_view->priv->row_separator_data = NULL;
     }
+
+  if (tree_view->priv->row_background_destroy && tree_view->priv->row_background_data)
+    {
+      (* tree_view->priv->row_background_destroy) (tree_view->priv->row_background_data);
+      tree_view->priv->row_background_data = NULL;
+    }
   
   gtk_tree_view_set_model (tree_view, NULL);
 
@@ -4263,6 +4269,8 @@
 	  GtkTreeViewColumn *column = list->data;
 	  const gchar *detail = NULL;
 	  GtkStateType state;
+	  gboolean has_custom_background;
+	  GdkColor custom_background;
 
 	  if (!column->visible)
             continue;
@@ -4329,6 +4337,11 @@
 						   GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT),
 						   node->children?TRUE:FALSE);
 
+	  has_custom_background = tree_view->priv->row_background_func
+	                          && tree_view->priv->row_background_func (tree_view,
+									   &iter,
+									   &custom_background,
+									   tree_view->priv->row_background_data);
           /* Select the detail for drawing the cell.  relevant
            * factors are parity, sortedness, and whether to
            * display rules.
@@ -4380,8 +4393,28 @@
 	    state = GTK_STATE_NORMAL;
 
 	  /* Draw background */
-	  if (row_ending_details)
+	  if (has_custom_background)
 	    {
+	      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_background);
+		  gdk_draw_rectangle (event->window,
+				      gc,
+				      TRUE,
+				      draw.x,
+				      draw.y,
+				      draw.width,
+				      draw.height);
+		  g_object_unref (gc);
+		}
+	    }
+	  else if (row_ending_details)
+	    {
 	      char new_detail[128];
 
 	      is_first = (rtl ? !list->next : !list->prev);
@@ -14748,5 +14781,53 @@
     }
 }
 
+/**
+ * gtk_tree_view_get_row_background_func:
+ * @tree_view: a #GtkTreeView
+ * 
+ * Returns the current row background function.
+ * 
+ * Return value: the current row background function.
+ *
+ * Since: 2.12
+ **/
+GtkTreeViewRowBackgroundFunc
+gtk_tree_view_get_row_background_func (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
+
+  return tree_view->priv->row_background_func;
+}
+
+/**
+ * gtk_tree_view_set_row_background_func:
+ * @tree_view: a #GtkTreeView
+ * @func: a #GtkTreeViewRowBackgroundFunc
+ * @data: user data to pass to @func, or %NULL
+ * @destroy: destroy notifier for @data, or %NULL
+ * 
+ * Sets the row background function, which is used to define custom
+ * background colors for rows. If the row background function is %NULL
+ * (the default value), or the function returns %FALSE, then the
+ * normal colors are used.
+ *
+ * Since: 2.12
+ **/
+void
+gtk_tree_view_set_row_background_func (GtkTreeView                 *tree_view,
+				       GtkTreeViewRowBackgroundFunc func,
+				       gpointer                     data,
+				       GtkDestroyNotify             destroy)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+  if (tree_view->priv->row_background_destroy && tree_view->priv->row_background_data)
+    (* tree_view->priv->row_background_destroy) (tree_view->priv->row_background_data);
+
+  tree_view->priv->row_background_func = func;
+  tree_view->priv->row_background_data = data;
+  tree_view->priv->row_background_destroy = destroy;
+}
+
 #define __GTK_TREE_VIEW_C__
 #include "gtkaliasdef.c"
Index: gtk/gtktreeview.h
===================================================================
--- gtk/gtktreeview.h	(revision 4004)
+++ gtk/gtktreeview.h	(working copy)
@@ -131,6 +131,10 @@
 typedef void     (*GtkTreeViewSearchPositionFunc) (GtkTreeView  *tree_view,
 						   GtkWidget    *search_dialog,
 						   gpointer      user_data);
+typedef gboolean (*GtkTreeViewRowBackgroundFunc) (GtkTreeView  *tree_view,
+						  GtkTreeIter  *iter,
+						  GdkColor     *color,
+						  gpointer      data);
 
 
 /* Creators */
@@ -359,6 +363,13 @@
 void                        gtk_tree_view_set_enable_tree_lines  (GtkTreeView                *tree_view,
 								  gboolean                    enabled);
 
+GtkTreeViewRowBackgroundFunc gtk_tree_view_get_row_background_func (GtkTreeView                 *tree_view);
+void                         gtk_tree_view_set_row_background_func (GtkTreeView                 *tree_view,
+								    GtkTreeViewRowBackgroundFunc func,
+								    gpointer                     data,
+								    GtkDestroyNotify             destroy);
+
+
 G_END_DECLS
 
 
