[vte] vtebg: Cache backgrounds as cairo surfaces



commit 5f4f67f579c9530af716573d6aaafc9cdb060e09
Author: Kristian Høgsberg <krh bitplanet net>
Date:   Tue Jan 12 10:57:45 2010 -0500

    vtebg: Cache backgrounds as cairo surfaces

 src/vtebg.c   |  385 +++++++++++++++++----------------------------------------
 src/vtebg.h   |   15 ++-
 src/vtedraw.c |   33 ++----
 3 files changed, 134 insertions(+), 299 deletions(-)
---
diff --git a/src/vtebg.c b/src/vtebg.c
index d9a5041..8767ea7 100644
--- a/src/vtebg.c
+++ b/src/vtebg.c
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <gtk/gtk.h>
+#include <cairo-xlib.h>
 #include "debug.h"
 #include "marshal.h"
 #include "vtebg.h"
@@ -39,16 +40,14 @@ struct VteBgCacheItem {
 
 	PangoColor tint_color;
 	double saturation;
-
-	GdkPixmap *pixmap;
-	GdkPixbuf *pixbuf;
+	cairo_surface_t *surface;
 };
 
 
-static GdkPixbuf *_vte_bg_resize_pixbuf(GdkPixbuf *pixbuf,
-					gint min_width, gint min_height);
 static void vte_bg_cache_item_free(struct VteBgCacheItem *item);
 static void vte_bg_cache_prune_int(VteBg *bg, gboolean root);
+static const cairo_user_data_key_t item_surface_key;
+
 
 #if 0
 static const char *
@@ -115,47 +114,66 @@ _vte_property_get_pixmaps(GdkWindow *window, GdkAtom atom,
 				(guchar**) pixmaps);
 }
 
-static GdkPixmap *
-vte_bg_root_pixmap(VteBg *bg)
+static cairo_surface_t *
+vte_bg_root_surface(VteBg *bg)
 {
 	GdkPixmap *pixmap;
 	GdkAtom prop_type;
 	int prop_size;
+	Window root;
 	XID *pixmaps;
+	int x, y;
+	unsigned int width, height, border_width, depth;
+	cairo_surface_t *surface = NULL;
+	Display *display;
+	Screen *screen;
 
 	pixmap = NULL;
 	pixmaps = NULL;
 	gdk_error_trap_push();
-	if (_vte_property_get_pixmaps(bg->native->window, bg->native->atom,
+	if (!_vte_property_get_pixmaps(bg->native->window, bg->native->atom,
 				      &prop_type, &prop_size,
-				      &pixmaps)) {
-		if ((prop_type == GDK_TARGET_PIXMAP) &&
-		    (prop_size >= (int)sizeof(XID) &&
-		    (pixmaps != NULL))) {
-			pixmap = gdk_pixmap_foreign_new_for_display(bg->native->display, pixmaps[0]);
-			_VTE_DEBUG_IF(VTE_DEBUG_MISC|VTE_DEBUG_EVENTS) {
-				gint pwidth, pheight;
-				gdk_drawable_get_size(pixmap,
-						&pwidth, &pheight);
-				g_printerr("New background image %dx%d\n",
-						pwidth, pheight);
-			}
-		}
-		g_free(pixmaps);
+				      &pixmaps))
+		goto out;
+
+	if ((prop_type != GDK_TARGET_PIXMAP) ||
+	    (prop_size < (int)sizeof(XID) ||
+	     (pixmaps == NULL)))
+		goto out_pixmaps;
+		
+	if (!XGetGeometry (GDK_DISPLAY_XDISPLAY (bg->native->display),
+			   pixmaps[0], &root,
+			   &x, &y, &width, &height, &border_width, &depth))
+		goto out_pixmaps;
+
+	display = gdk_x11_display_get_xdisplay (bg->native->display);
+	screen = gdk_x11_screen_get_xscreen (bg->screen);
+	surface = cairo_xlib_surface_create (display,
+					     pixmaps[0],
+					     DefaultVisualOfScreen(screen),
+					     width, height);
+
+	_VTE_DEBUG_IF(VTE_DEBUG_MISC|VTE_DEBUG_EVENTS) {
+		g_printerr("New background image %dx%d\n", width, height);
 	}
+
+ out_pixmaps:
+	g_free(pixmaps);
+ out:
 	_vte_bg_display_sync(bg);
 	gdk_error_trap_pop();
-	return pixmap;
+
+	return surface;
 }
 
 static void
-vte_bg_set_root_pixmap(VteBg *bg, GdkPixmap *pixmap)
+vte_bg_set_root_surface(VteBg *bg, cairo_surface_t *surface)
 {
-	if (bg->root_pixmap != NULL) {
-		g_object_unref(bg->root_pixmap);
+	if (bg->root_surface != NULL) {
+		cairo_surface_destroy (bg->root_surface);
 	}
-	bg->root_pixmap = pixmap;
-	vte_bg_cache_prune_int(bg, TRUE);
+	bg->root_surface = surface;
+	vte_bg_cache_prune_int (bg, TRUE);
 	g_signal_emit_by_name(bg, "root-pixmap-changed");
 }
 
@@ -165,15 +183,15 @@ vte_bg_root_filter(GdkXEvent *native, GdkEvent *event, gpointer data)
 {
 	XEvent *xevent = (XEvent*) native;
 	VteBg *bg;
-	GdkPixmap *pixmap;
+	cairo_surface_t *surface;
 
 	switch (xevent->type) {
 	case PropertyNotify:
 		bg = VTE_BG(data);
 		if ((xevent->xproperty.window == bg->native->native_window) &&
 		    (xevent->xproperty.atom == bg->native->native_atom)) {
-			pixmap = vte_bg_root_pixmap(bg);
-			vte_bg_set_root_pixmap(bg, pixmap);
+			surface = vte_bg_root_surface(bg);
+			vte_bg_set_root_surface(bg, surface);
 		}
 		break;
 	default:
@@ -280,7 +298,7 @@ vte_bg_get_for_screen(GdkScreen *screen)
 		bg->screen = screen;
 		window = gdk_screen_get_root_window(screen);
 		bg->native = vte_bg_native_new(window);
-		bg->root_pixmap = vte_bg_root_pixmap(bg);
+		bg->root_surface = vte_bg_root_surface(bg);
 		events = gdk_window_get_events(window);
 		events |= GDK_PROPERTY_CHANGE_MASK;
 		gdk_window_set_events(window, events);
@@ -290,45 +308,6 @@ vte_bg_get_for_screen(GdkScreen *screen)
 	return bg;
 }
 
-/* Generate lookup tables for desaturating an image toward a given color.  The
- * saturation value is a floating point number between 0 and 1. */
-static void
-_vte_bg_generate_desat_tables(const PangoColor *color, double saturation,
-			      guchar red[256],
-			      guchar green[256],
-			      guchar blue[256])
-{
-	int i;
-	/* Zero saturation -> exactly match the tinting color. */
-	if (saturation == 0) {
-		for (i = 0; i < 256; i++) {
-			red[i] = color->red >> 8;
-			green[i] = color->green >> 8;
-			blue[i] = color->blue >> 8;
-		}
-		return;
-	}
-	/* 100% saturation -> exactly match the original color. */
-	if (saturation == 1) {
-		for (i = 0; i < 256; i++) {
-			red[i] = green[i] = blue[i] = 1;
-		}
-		return;
-	}
-	/* 0-100% saturation -> weighted average */
-	for (i = 0; i < 256; i++) {
-		red[i] = CLAMP(((1.0 - saturation) * (color->red >> 8)) +
-			       (saturation * i),
-			       0, 255);
-		green[i] = CLAMP(((1.0 - saturation) * (color->green >> 8)) +
-				 (saturation * i),
-				 0, 255);
-		blue[i] = CLAMP(((1.0 - saturation) * (color->blue >> 8)) +
-				(saturation * i),
-				0, 255);
-	}
-}
-
 static gboolean
 vte_bg_colors_equal(const PangoColor *a, const PangoColor *b)
 {
@@ -346,14 +325,10 @@ vte_bg_cache_item_free(struct VteBgCacheItem *item)
 				(gpointer*)(void*)&item->source_pixbuf);
 	}
 	g_free(item->source_file);
-	if (item->pixmap != NULL) {
-		g_object_remove_weak_pointer(G_OBJECT(item->pixmap),
-				(gpointer*)(void*)&item->pixmap);
-	}
-	if (item->pixbuf != NULL) {
-		g_object_remove_weak_pointer(G_OBJECT(item->pixbuf),
-				(gpointer*)(void*)&item->pixbuf);
-	}
+
+	if (item->surface != NULL)
+		cairo_surface_set_user_data (item->surface,
+					     &item_surface_key, NULL, NULL);
 
 	g_slice_free(struct VteBgCacheItem, item);
 }
@@ -365,12 +340,11 @@ vte_bg_cache_prune_int(VteBg *bg, gboolean root)
 	for (i = bg->pvt->cache; i != NULL; i = next) {
 		struct VteBgCacheItem *item = i->data;
 		next = g_list_next (i);
-		/* Prune the item if either
-		 * it is a "root pixmap" item and we want to prune them, or
-		 * its pixmap and pixbuf fields are both NULL because whichever
-		 * object it created has been destroyoed. */
+		/* Prune the item if either it is a "root pixmap" item and
+		 * we want to prune them, or its surface is NULL because
+		 * whichever object it created has been destroyed. */
 		if ((root && (item->source_type == VTE_BG_SOURCE_ROOT)) ||
-		    ((item->pixmap == NULL) && (item->pixbuf == NULL))) {
+		    item->surface == NULL) {
 			vte_bg_cache_item_free (item);
 			bg->pvt->cache = g_list_delete_link(bg->pvt->cache, i);
 		}
@@ -383,53 +357,11 @@ vte_bg_cache_prune(VteBg *bg)
 	vte_bg_cache_prune_int(bg, FALSE);
 }
 
-/**
- * _vte_bg_resize_pixbuf:
- * @pixmap: a #GdkPixbuf, or %NULL
- * @min_width: the requested minimum_width
- * @min_height: the requested minimum_height
- *
- * The background pixbuf may be tiled, and if it is tiled, it may be very, very
- * small.  This function creates a pixbuf consisting of the passed-in pixbuf
- * tiled to a usable size.
- *
- * Returns: a new #GdkPixbuf, unrefs @pixbuf.
- */
-static GdkPixbuf *
-_vte_bg_resize_pixbuf(GdkPixbuf *pixbuf, gint min_width, gint min_height)
+static void item_surface_destroy_func(void *data)
 {
-	GdkPixbuf *tmp;
-	gint src_width, src_height;
-	gint dst_width, dst_height;
-	gint x, y;
-
-	src_width = gdk_pixbuf_get_width(pixbuf);
-	src_height = gdk_pixbuf_get_height(pixbuf);
-	dst_width = (((min_width - 1) / src_width) + 1) * src_width;
-	dst_height = (((min_height - 1) / src_height) + 1) * src_height;
-	if ((dst_width == src_width) && (dst_height == src_height)) {
-		return pixbuf;
-	}
-
-	_vte_debug_print(VTE_DEBUG_MISC|VTE_DEBUG_EVENTS,
-		"Resizing (root?) pixbuf from %dx%d to %dx%d\n",
-			src_width, src_height, dst_width, dst_height);
-
-	tmp = gdk_pixbuf_new(gdk_pixbuf_get_colorspace(pixbuf),
-			     gdk_pixbuf_get_has_alpha(pixbuf),
-			     gdk_pixbuf_get_bits_per_sample(pixbuf),
-			     dst_width, dst_height);
-	for (y = 0; y < dst_height; y += src_height) {
-		for (x = 0; x < dst_width; x += src_width) {
-			gdk_pixbuf_copy_area(pixbuf,
-					     0, 0, src_width, src_height,
-					     tmp,
-					     x, y);
-		}
-	}
+	struct VteBgCacheItem *item = data;
 
-	g_object_unref(pixbuf);
-	return tmp;
+	item->surface = NULL;
 }
 
 /* Add an item to the cache, instructing all of the objects therein to clear
@@ -443,70 +375,23 @@ vte_bg_cache_add(VteBg *bg, struct VteBgCacheItem *item)
 		g_object_add_weak_pointer(G_OBJECT(item->source_pixbuf),
 					  (gpointer*)(void*)&item->source_pixbuf);
 	}
-	if (item->pixbuf != NULL) {
-		g_object_add_weak_pointer(G_OBJECT(item->pixbuf),
-					  (gpointer*)(void*)&item->pixbuf);
-	}
-	if (item->pixmap != NULL) {
-		g_object_add_weak_pointer(G_OBJECT(item->pixmap),
-					  (gpointer*)(void*)&item->pixmap);
-	}
-}
 
-/* Desaturate a pixbuf in the direction of a specified color. */
-static void
-vte_bg_desaturate_pixbuf(GdkPixbuf *pixbuf,
-			 const PangoColor *tint, double saturation)
-{
-	guchar red[256], green[256], blue[256];
-	long stride, width, height, channels, x, y;
-	guchar *pixels;
-
-	_vte_bg_generate_desat_tables(tint, saturation, red, green, blue);
-
-	stride = gdk_pixbuf_get_rowstride(pixbuf);
-	width = gdk_pixbuf_get_width(pixbuf);
-	height = gdk_pixbuf_get_height(pixbuf);
-	channels = gdk_pixbuf_get_n_channels(pixbuf);
-
-	for (y = 0; y < height; y++) {
-		pixels = gdk_pixbuf_get_pixels(pixbuf) +
-			 y * stride;
-		for (x = 0; x < width * channels; x++) {
-			switch(x % channels) {
-			case 0:
-				pixels[x] = red[pixels[x]];
-				break;
-			case 1:
-				pixels[x] = green[pixels[x]];
-				break;
-			case 2:
-				pixels[x] = blue[pixels[x]];
-				break;
-			default:
-				break;
-			}
-		}
-	}
+	cairo_surface_set_user_data (item->surface, &item_surface_key, item,
+				     item_surface_destroy_func);
 }
 
 /* Search for a match in the cache, and if found, return an object with an
    additional ref. */
-static gpointer
+static cairo_surface_t *
 vte_bg_cache_search(VteBg *bg,
 		    enum VteBgSourceType source_type,
 		    const GdkPixbuf *source_pixbuf,
 		    const char *source_file,
 		    const PangoColor *tint,
-		    double saturation,
-		    GdkVisual *visual,
-		    gboolean pixbuf,
-		    gboolean pixmap)
+		    double saturation)
 {
 	GList *i;
 
-	g_assert((pixmap && !pixbuf) || (!pixmap && pixbuf));
-
 	vte_bg_cache_prune(bg);
 	for (i = bg->pvt->cache; i != NULL; i = g_list_next(i)) {
 		struct VteBgCacheItem *item = i->data;
@@ -530,33 +415,27 @@ vte_bg_cache_search(VteBg *bg,
 				g_assert_not_reached();
 				break;
 			}
-			if (pixbuf && item->pixbuf != NULL) {
-				return g_object_ref(item->pixbuf);
-			}
-			if (pixmap && item->pixmap != NULL &&
-					gdk_drawable_get_visual (item->pixmap) == visual) {
-				return g_object_ref(item->pixmap);
-			}
+
+			return cairo_surface_reference(item->surface);
 		}
 	}
 	return NULL;
 }
 
-GdkPixmap *
-vte_bg_get_pixmap(VteBg *bg,
-		  enum VteBgSourceType source_type,
-		  GdkPixbuf *source_pixbuf,
-		  const char *source_file,
-		  const PangoColor *tint,
-		  double saturation,
-		  GdkColormap *colormap)
+cairo_surface_t *
+vte_bg_get_surface(VteBg *bg,
+		   enum VteBgSourceType source_type,
+		   GdkPixbuf *source_pixbuf,
+		   const char *source_file,
+		   const PangoColor *tint,
+		   double saturation,
+		   cairo_surface_t *other)
 {
 	struct VteBgCacheItem *item;
-	gpointer cached;
-	GdkColormap *rcolormap;
-	GdkPixmap *pixmap;
 	GdkPixbuf *pixbuf;
-	char *file;
+	cairo_surface_t *cached, *source;
+	cairo_t *cr;
+	int width, height;
 
 	if (source_type == VTE_BG_SOURCE_NONE) {
 		return NULL;
@@ -564,9 +443,7 @@ vte_bg_get_pixmap(VteBg *bg,
 
 	cached = vte_bg_cache_search(bg, source_type,
 				     source_pixbuf, source_file,
-				     tint, saturation,
-				     gdk_colormap_get_visual (colormap),
-				     FALSE, TRUE);
+				     tint, saturation);
 	if (cached != NULL) {
 		return cached;
 	}
@@ -577,59 +454,19 @@ vte_bg_get_pixmap(VteBg *bg,
 	item->source_file = NULL;
 	item->tint_color = *tint;
 	item->saturation = saturation;
-	item->pixmap = NULL;
-	item->pixbuf = NULL;
+	source = NULL;
 	pixbuf = NULL;
-	pixmap = NULL;
-	file = NULL;
 
 	switch (source_type) {
 	case VTE_BG_SOURCE_ROOT:
-		if (GDK_IS_PIXMAP(bg->root_pixmap)) {
-			int width, height;
-			/* Tell GTK+ that this foreign pixmap shares the
-			 * root window's colormap. */
-			rcolormap = gdk_drawable_get_colormap(gdk_screen_get_root_window(bg->screen));
-			if (gdk_drawable_get_colormap(bg->root_pixmap) == NULL) {
-				gdk_drawable_set_colormap(bg->root_pixmap,
-							  rcolormap);
-			}
-
-			/* Retrieve the pixmap's size. */
-			gdk_error_trap_push();
-			width = height = -1;
-			gdk_drawable_get_size(bg->root_pixmap, &width, &height);
-			_vte_bg_display_sync(bg);
-			gdk_error_trap_pop();
-
-			/* If the pixmap gave us a valid size, retrieve its
-			 * contents. */
-			if ((width > 0) && (height > 0)) {
-				gdk_error_trap_push();
-				pixbuf = gdk_pixbuf_get_from_drawable(NULL,
-								      bg->root_pixmap,
-								      NULL,
-								      0, 0,
-								      0, 0,
-								      width, height);
-				_vte_bg_display_sync(bg);
-				gdk_error_trap_pop();
-			}
-		}
 		break;
 	case VTE_BG_SOURCE_PIXBUF:
-		if (GDK_IS_PIXBUF(source_pixbuf)) {
-                        /* If we're going to modify the pixbuf below, make a copy first! */
-                        if (saturation != 1.0) {
-                                pixbuf = gdk_pixbuf_copy(source_pixbuf);
-                        } else {
-                                pixbuf = g_object_ref(source_pixbuf);
-                        }
-		}
+		item->source_pixbuf = g_object_ref (source_pixbuf);
+		pixbuf = g_object_ref (source_pixbuf);
 		break;
 	case VTE_BG_SOURCE_FILE:
 		if ((source_file != NULL) && (strlen(source_file) > 0)) {
-			file = g_strdup(source_file);
+			item->source_file = g_strdup(source_file);
 			pixbuf = gdk_pixbuf_new_from_file(source_file, NULL);
 		}
 		break;
@@ -638,35 +475,41 @@ vte_bg_get_pixmap(VteBg *bg,
 		break;
 	}
 
-	item->source_pixbuf = source_pixbuf;
-	if (G_IS_OBJECT(item->source_pixbuf)) {
-		g_object_ref(item->source_pixbuf);
+	if (pixbuf) {
+		width = gdk_pixbuf_get_width(pixbuf);
+		height = gdk_pixbuf_get_height(pixbuf);
+	} else {
+		width = cairo_xlib_surface_get_width(bg->root_surface);
+		height = cairo_xlib_surface_get_height(bg->root_surface);
 	}
-	item->source_file = file;
 
-	if (GDK_IS_PIXBUF(pixbuf)) {
-		if (saturation != 1.0) {
-			vte_bg_desaturate_pixbuf(pixbuf, tint, saturation);
-		}
+	item->surface =
+		cairo_surface_create_similar(other, CAIRO_CONTENT_COLOR_ALPHA,
+					     width, height);
+
+	cr = cairo_create (item->surface);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+	if (pixbuf)
+		gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+	else
+		cairo_set_source_surface (cr, bg->root_surface, 0, 0);
+	cairo_paint (cr);
+
+	if (saturation != 1.0) {
+		cairo_set_source_rgba (cr, 
+				       tint->red / 65535.,
+				       tint->green / 65535.,
+				       tint->blue / 65535.,
+				       saturation);
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+		cairo_paint (cr);
 	}
-
-	pixmap = NULL;
-	if (GDK_IS_PIXBUF(pixbuf)) {
-		/* If the image is smaller than 256x256 then tile it into a
-		 * pixbuf that is at least this large.  This is done because
-		 * tiling a 1x1 pixmap onto the screen using thousands of calls
-		 * to XCopyArea is very slow. */
-		pixbuf = _vte_bg_resize_pixbuf(pixbuf, 256, 256);
-		gdk_pixbuf_render_pixmap_and_mask_for_colormap(pixbuf,
-							       colormap,
-							       &pixmap, NULL,
-							       0);
-		g_object_unref(pixbuf);
-	}
-
-	item->pixmap = pixmap;
+	cairo_destroy (cr);
 
 	vte_bg_cache_add(bg, item);
 
-	return item->pixmap;
+	if (pixbuf)
+		g_object_unref (pixbuf);
+
+	return item->surface;
 }
diff --git a/src/vtebg.h b/src/vtebg.h
index 1a1e25d..19f5391 100644
--- a/src/vtebg.h
+++ b/src/vtebg.h
@@ -30,7 +30,7 @@ typedef struct _VteBg VteBg;
 struct _VteBg {
 	GObject parent;
 	GdkScreen *screen;
-	GdkPixmap *root_pixmap;
+	cairo_surface_t *root_surface;
 	struct VteBgNative *native;
 	struct VteBgPrivate *pvt;
 };
@@ -59,11 +59,14 @@ enum VteBgSourceType {
 	VTE_BG_SOURCE_FILE
 };
 
-GdkPixmap *vte_bg_get_pixmap(VteBg *bg, enum VteBgSourceType source_type,
-			     GdkPixbuf *source_pixbuf,
-			     const char *source_file,
-			     const PangoColor *tint, double saturation,
-			     GdkColormap *colormap);
+cairo_surface_t *
+vte_bg_get_surface(VteBg *bg,
+		   enum VteBgSourceType source_type,
+		   GdkPixbuf *source_pixbuf,
+		   const char *source_file,
+		   const PangoColor *tint,
+		   double saturation,
+		   cairo_surface_t *other);
 
 G_END_DECLS
 
diff --git a/src/vtedraw.c b/src/vtedraw.c
index 70b6dd9..0e23408 100644
--- a/src/vtedraw.c
+++ b/src/vtedraw.c
@@ -887,40 +887,29 @@ _vte_draw_set_background_image (struct _vte_draw *draw,
 			        const PangoColor *color,
 			        double saturation)
 {
-	GdkPixmap *pixmap;
 	cairo_surface_t *surface;
-	cairo_t *cr;
 
 	if (type != VTE_BG_SOURCE_NONE)
 		draw->requires_clear = TRUE;
 
-	pixmap = vte_bg_get_pixmap (vte_bg_get_for_screen (gtk_widget_get_screen (draw->widget)),
-				    type, pixbuf, filename,
-				    color, saturation,
-				    gtk_widget_get_colormap (draw->widget));
+	/* Need a valid draw->cr for cairo_get_target () */
+	_vte_draw_start (draw);
+
+	surface = vte_bg_get_surface (vte_bg_get_for_screen (gtk_widget_get_screen (draw->widget)),
+				     type, pixbuf, filename,
+				     color, saturation,
+				     cairo_get_target(draw->cr));
 
-	if (!pixmap)
+	_vte_draw_end (draw);
+
+	if (!surface)
 		return;
 
 	if (draw->bg_pattern)
 		cairo_pattern_destroy (draw->bg_pattern);
 
-	/* Ugh... We need to create a dummy cairo_t */
-	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
-	cr = cairo_create (surface);
-
-	gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0);
-	draw->bg_pattern = cairo_pattern_reference (cairo_get_source (cr));
-
-	cairo_destroy (cr);
+	draw->bg_pattern = cairo_pattern_create_for_surface (surface);
 	cairo_surface_destroy (surface);
-
-	/* Transfer the pixmap ownership to the pattern */
-	cairo_pattern_set_user_data (draw->bg_pattern,
-				     (cairo_user_data_key_t *) draw,
-				     pixmap,
-				     (cairo_destroy_func_t) g_object_unref);
-
 	cairo_pattern_set_extend (draw->bg_pattern, CAIRO_EXTEND_REPEAT);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]