summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/cairo-x-visual.patch
blob: 29f6c737e8c811f184bbeb22ae1425c81a0cbe3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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.
  *