Index: gtk/gtkcellrendererpixbuf.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcellrendererpixbuf.c,v
retrieving revision 1.36
diff -u -r1.36 gtkcellrendererpixbuf.c
--- gtk/gtkcellrendererpixbuf.c	30 Oct 2004 02:57:23 -0000	1.36
+++ gtk/gtkcellrendererpixbuf.c	18 Jan 2005 21:25:26 -0000
@@ -60,7 +60,8 @@
 	PROP_PIXBUF_EXPANDER_CLOSED,
 	PROP_STOCK_ID,
 	PROP_STOCK_SIZE,
-	PROP_STOCK_DETAIL
+	PROP_STOCK_DETAIL,
+	PROP_COLORIZE
 };
 
 static gpointer parent_class;
@@ -74,6 +75,7 @@
   gchar *stock_id;
   GtkIconSize stock_size;
   gchar *stock_detail;
+  gboolean colorize;
 };
 
 
@@ -182,6 +184,14 @@
 							P_("Render detail to pass to the theme engine"),
 							NULL,
 							G_PARAM_READWRITE));
+  g_object_class_install_property (object_class,
+				   PROP_COLORIZE,
+				   g_param_spec_boolean ("colorize",
+ 							 P_("Colorize"),
+ 							 P_("Whether the rendered pixbuf should be colorized according to the state"),
+ 							 FALSE,
+ 							 G_PARAM_READWRITE));
+
 
   g_type_class_add_private (object_class, sizeof (GtkCellRendererPixbufPrivate));
 }
@@ -240,6 +250,9 @@
     case PROP_STOCK_DETAIL:
       g_value_set_string (value, priv->stock_detail);
       break;
+    case PROP_COLORIZE:
+      g_value_set_boolean (value, priv->colorize);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -305,6 +318,9 @@
         g_free (priv->stock_detail);
       priv->stock_detail = g_strdup (g_value_get_string (value));
       break;
+    case PROP_COLORIZE:
+      priv->colorize = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -353,6 +369,53 @@
                                                priv->stock_detail);
 }
 
+static GdkPixbuf *
+create_colorized_pixbuf (GdkPixbuf *src, 
+			 GdkColor  *new_color)
+{
+  gint i, j;
+  gint width, height, has_alpha, src_row_stride, dst_row_stride;
+  gint red_value, green_value, blue_value;
+  guchar *target_pixels;
+  guchar *original_pixels;
+  guchar *pixsrc;
+  guchar *pixdest;
+  GdkPixbuf *dest;
+  
+  red_value = new_color->red / 255.0;
+  green_value = new_color->green / 255.0;
+  blue_value = new_color->blue / 255.0;
+  
+  dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
+			 gdk_pixbuf_get_has_alpha (src),
+			 gdk_pixbuf_get_bits_per_sample (src),
+			 gdk_pixbuf_get_width (src),
+			 gdk_pixbuf_get_height (src));
+  
+  has_alpha = gdk_pixbuf_get_has_alpha (src);
+  width = gdk_pixbuf_get_width (src);
+  height = gdk_pixbuf_get_height (src);
+  src_row_stride = gdk_pixbuf_get_rowstride (src);
+  dst_row_stride = gdk_pixbuf_get_rowstride (dest);
+  target_pixels = gdk_pixbuf_get_pixels (dest);
+  original_pixels = gdk_pixbuf_get_pixels (src);
+  
+  for (i = 0; i < height; i++) {
+    pixdest = target_pixels + i*dst_row_stride;
+    pixsrc = original_pixels + i*src_row_stride;
+    for (j = 0; j < width; j++) {		
+      *pixdest++ = (*pixsrc++ * red_value) >> 8;
+      *pixdest++ = (*pixsrc++ * green_value) >> 8;
+      *pixdest++ = (*pixsrc++ * blue_value) >> 8;
+      if (has_alpha) {
+	*pixdest++ = *pixsrc++;
+      }
+    }
+  }
+  return dest;
+}
+
+
 static void
 gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
 				   GtkWidget       *widget,
@@ -434,6 +497,7 @@
   GtkCellRendererPixbufPrivate *priv;
   GdkPixbuf *pixbuf;
   GdkPixbuf *invisible = NULL;
+  GdkPixbuf *colorized = NULL;
   GdkRectangle pix_rect;
   GdkRectangle draw_rect;
   gboolean stock_pixbuf = FALSE;
@@ -470,6 +534,10 @@
   pix_rect.width  -= cell->xpad * 2;
   pix_rect.height -= cell->ypad * 2;
 
+  if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) ||
+      !gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
+    return;
+
   if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !cell->sensitive)
     {
       GtkIconSource *source;
@@ -496,22 +564,43 @@
      
      pixbuf = invisible;
     }
+  else if (priv->colorize && 
+	   (flags & (GTK_CELL_RENDERER_SELECTED|GTK_CELL_RENDERER_PRELIT) != 0))
+    {
+      GtkStateType state;
 
-  if (gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) &&
-      gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
-    gdk_draw_pixbuf (window,
-		     widget->style->black_gc,
-		     pixbuf,
-		     /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
-		     draw_rect.x - pix_rect.x,
-		     draw_rect.y - pix_rect.y,
-		     draw_rect.x,
-		     draw_rect.y,
-		     draw_rect.width,
-		     draw_rect.height,
-		     GDK_RGB_DITHER_NORMAL,
-		     0, 0);
+      if (flags & GTK_CELL_RENDERER_SELECTED != 0)
+	{
+	  if (GTK_WIDGET_HAS_FOCUS (widget))
+	    state = GTK_STATE_SELECTED;
+	  else
+	    state = GTK_STATE_ACTIVE;
+	}
+      else
+	state = GTK_STATE_PRELIGHT;
+
+      colorized = create_colorized_pixbuf (pixbuf,
+					   &widget->style->base[state]);
+
+      pixbuf = colorized;
+    }
+
+  gdk_draw_pixbuf (window,
+		   widget->style->black_gc,
+		   pixbuf,
+		   /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
+		   draw_rect.x - pix_rect.x,
+		   draw_rect.y - pix_rect.y,
+		   draw_rect.x,
+		   draw_rect.y,
+		   draw_rect.width,
+		   draw_rect.height,
+		   GDK_RGB_DITHER_NORMAL,
+		   0, 0);
   
   if (invisible)
     g_object_unref (invisible);
+
+  if (colorized)
+    g_object_unref (colorized);
 }
