gfx/cairo/cairo-x-visual.patch
author Gregory Szorc <gps@mozilla.com>
Wed, 28 Jan 2015 13:37:00 -0800
branchMOBILE90_2011121217_RELBRANCH
changeset 120109 1f9976832e10e2758e4b12f7e973334169d3def7
parent 43766 598c5f8d295cb5e1456e55cd512758d6c3498df2
permissions -rw-r--r--
Close old release branch MOBILE90_2011121217_RELBRANCH

diff -r c1195334f839 gfx/cairo/cairo/src/cairo-xlib-surface.c
--- a/gfx/cairo/cairo/src/cairo-xlib-surface.c	Fri May 21 17:42:55 2010 +0300
+++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c	Fri May 21 19:12:29 2010 +0300
@@ -189,16 +189,57 @@ static const XTransform identity = { {
 
 #define CAIRO_SURFACE_RENDER_HAS_PDF_OPERATORS(surface)	CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 11)
 
 #define CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR(surface, op)	\
      ((op) <= CAIRO_OPERATOR_SATURATE ||			\
       (CAIRO_SURFACE_RENDER_HAS_PDF_OPERATORS(surface) &&	\
        (op) <= CAIRO_OPERATOR_HSL_LUMINOSITY))
 
+static Visual *
+_visual_for_xrender_format(Screen *screen,
+			    XRenderPictFormat *xrender_format)
+{
+    int d, v;
+    for (d = 0; d < screen->ndepths; d++) {
+	Depth *d_info = &screen->depths[d];
+	if (d_info->depth != xrender_format->depth)
+	    continue;
+
+	for (v = 0; v < d_info->nvisuals; v++) {
+	    Visual *visual = &d_info->visuals[v];
+
+	    switch (visual->class) {
+	    case TrueColor:
+		if (xrender_format->type != PictTypeDirect)
+		    continue;
+		break;
+	    case DirectColor:
+		/* Prefer TrueColor to DirectColor.
+		   (XRenderFindVisualFormat considers both TrueColor and
+		   DirectColor Visuals to match the same PictFormat.) */
+		continue;
+	    case StaticGray:
+	    case GrayScale:
+	    case StaticColor:
+	    case PseudoColor:
+		if (xrender_format->type != PictTypeIndexed)
+		    continue;
+		break;
+	    }
+
+	    if (xrender_format ==
+		XRenderFindVisualFormat (DisplayOfScreen(screen), visual))
+		return visual;
+	}
+    }
+
+    return NULL;
+}
+
 static cairo_status_t
 _cairo_xlib_surface_set_clip_region (cairo_xlib_surface_t *surface,
 				     cairo_region_t *region)
 {
     cairo_bool_t had_clip_rects = surface->clip_region != NULL;
 
     if (had_clip_rects == FALSE && region == NULL)
 	return CAIRO_STATUS_SUCCESS;
@@ -313,16 +354,19 @@ _cairo_xlib_surface_create_similar (void
 	 * visual/depth etc. as possible. */
 	pix = XCreatePixmap (src->dpy, src->drawable,
 			     width <= 0 ? 1 : width, height <= 0 ? 1 : height,
 			     xrender_format->depth);
 
 	visual = NULL;
 	if (xrender_format == src->xrender_format)
 	    visual = src->visual;
+	else
+	    visual = _visual_for_xrender_format(src->screen->screen,
+					        xrender_format);
 
 	surface = (cairo_xlib_surface_t *)
 		  _cairo_xlib_surface_create_internal (src->screen, pix,
 						       visual,
 						       xrender_format,
 						       width, height,
 						       xrender_format->depth);
     }
@@ -3178,28 +3222,32 @@ cairo_xlib_surface_create_with_xrender_f
 					       Screen		    *scr,
 					       XRenderPictFormat    *format,
 					       int		    width,
 					       int		    height)
 {
     cairo_xlib_screen_t *screen;
     cairo_surface_t *surface;
     cairo_status_t status;
+    Visual *visual;
 
     if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
 	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
 
     status = _cairo_xlib_screen_get (dpy, scr, &screen);
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
 
     X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable));
 
+    if (format)
+    visual = _visual_for_xrender_format (scr, format);
+
     surface = _cairo_xlib_surface_create_internal (screen, drawable,
-						   NULL, format,
+						   visual, format,
 						   width, height, 0);
     _cairo_xlib_screen_destroy (screen);
 
     return surface;
 }
 slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
 
 /**
@@ -3413,33 +3461,37 @@ cairo_xlib_surface_get_screen (cairo_sur
 
     return surface->screen->screen;
 }
 
 /**
  * cairo_xlib_surface_get_visual:
  * @surface: a #cairo_xlib_surface_t
  *
- * Get the X Visual used for underlying X Drawable.
+ * Gets the X Visual associated with @surface, suitable for use with the
+ * underlying X Drawable.  If @surface was created by
+ * cairo_xlib_surface_create(), the return value is the Visual passed to that
+ * constructor.
  *
- * Return value: the visual.
+ * Return value: the Visual or %NULL if there is no appropriate Visual for
+ * @surface.
  *
  * Since: 1.2
  **/
 Visual *
-cairo_xlib_surface_get_visual (cairo_surface_t *abstract_surface)
+cairo_xlib_surface_get_visual (cairo_surface_t *surface)
 {
-    cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
-
-    if (! _cairo_surface_is_xlib (abstract_surface)) {
+    cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
+
+    if (! _cairo_surface_is_xlib (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return NULL;
     }
 
-    return surface->visual;
+    return xlib_surface->visual;
 }
 
 /**
  * cairo_xlib_surface_get_depth:
  * @surface: a #cairo_xlib_surface_t
  *
  * Get the number of bits used to represent each pixel value.
  *