2 * Copyright © 2005 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Red Hat, Inc. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission. Red Hat, Inc. makes no representations about the
12 * suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
15 * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
18 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
21 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: Carl D. Worth <cworth@cworth.org>
30 #include "cairo-xlib.h"
31 #include "cairo-test.h"
33 #include "cairo-boilerplate-xlib.h"
35 #include "buffer-diff.h"
38 #define OFFSCREEN_OFFSET 50
40 cairo_bool_t result
= 0;
42 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
44 #include "cairo-xlib-xrender.h"
46 /* Vladimir Vukicevic reported that surfaces were being created with
47 * mismatching Visuals and XRenderPictFormats.
50 surface_compare_visual_and_format (cairo_surface_t
*surface
)
54 XRenderPictFormat
*format
;
56 dpy
= cairo_xlib_surface_get_display (surface
);
58 visual
= cairo_xlib_surface_get_visual (surface
);
62 format
= cairo_xlib_surface_get_xrender_format (surface
);
66 return format
== XRenderFindVisualFormat (dpy
, visual
);
72 surface_compare_visual_and_format (cairo_surface_t
*surface
)
80 check_similar_visual_and_format (cairo_surface_t
*surface
)
82 cairo_surface_t
*similar
;
85 similar
= cairo_surface_create_similar (surface
,
86 CAIRO_CONTENT_COLOR_ALPHA
,
88 if (cairo_surface_status (similar
))
91 ret
= surface_compare_visual_and_format (similar
);
93 cairo_surface_destroy (similar
);
100 draw_pattern (cairo_surface_t
*surface
)
102 cairo_t
*cr
= cairo_create (surface
);
105 cairo_set_source_rgb (cr
, 1.0, 1.0, 1.0); /* white */
108 cairo_set_source_rgba (cr
, 0, 0.0, 0.0, 0.50); /* half-alpha-black */
110 for (i
= 1; i
<= 3; i
++) {
111 int inset
= SIZE
/ 8 * i
;
115 SIZE
- 2 * inset
, SIZE
- 2 * inset
);
123 erase_pattern (cairo_surface_t
*surface
)
125 cairo_t
*cr
= cairo_create (surface
);
127 cairo_set_source_rgb (cr
, 0.0, 0.0, 0.0); /* black */
133 static cairo_test_status_t
134 do_test (Display
*dpy
,
135 unsigned char *reference_data
,
136 unsigned char *test_data
,
137 unsigned char *diff_data
,
138 cairo_bool_t use_render
,
139 cairo_bool_t use_pixmap
,
140 cairo_bool_t set_size
,
141 cairo_bool_t offscreen
)
143 cairo_surface_t
*surface
;
144 cairo_surface_t
*test_surface
;
146 buffer_diff_result_t result
;
148 int screen
= DefaultScreen (dpy
);
150 if (use_pixmap
&& offscreen
)
151 return CAIRO_TEST_SUCCESS
;
154 drawable
= XCreatePixmap (dpy
, DefaultRootWindow (dpy
),
155 SIZE
, SIZE
, DefaultDepth (dpy
, screen
));
157 XSetWindowAttributes xwa
;
160 xwa
.override_redirect
= True
;
163 x
= - OFFSCREEN_OFFSET
;
164 y
= - OFFSCREEN_OFFSET
;
170 drawable
= XCreateWindow (dpy
, DefaultRootWindow (dpy
),
172 DefaultDepth (dpy
, screen
), InputOutput
,
173 DefaultVisual (dpy
, screen
),
174 CWOverrideRedirect
, &xwa
);
175 XMapWindow (dpy
, drawable
);
178 surface
= cairo_xlib_surface_create (dpy
,
180 DefaultVisual (dpy
, screen
),
183 if (! surface_compare_visual_and_format (surface
))
184 return CAIRO_TEST_FAILURE
;
187 cairo_boilerplate_xlib_surface_disable_render (surface
);
190 cairo_xlib_surface_set_size (surface
, SIZE
, SIZE
);
192 if (cairo_xlib_surface_get_width (surface
) != SIZE
||
193 cairo_xlib_surface_get_height (surface
) != SIZE
)
194 return CAIRO_TEST_FAILURE
;
197 if (! check_similar_visual_and_format (surface
))
198 return CAIRO_TEST_FAILURE
;
200 draw_pattern (surface
);
202 test_surface
= cairo_image_surface_create_for_data (test_data
,
207 test_cr
= cairo_create (test_surface
);
208 cairo_set_source_surface (test_cr
, surface
, 0, 0);
209 cairo_paint (test_cr
);
211 cairo_destroy (test_cr
);
212 cairo_surface_destroy (test_surface
);
214 /* We erase the surface to black in case we get the same
215 * memory back again for the pixmap case.
217 erase_pattern (surface
);
218 cairo_surface_destroy (surface
);
221 XFreePixmap (dpy
, drawable
);
223 XDestroyWindow (dpy
, drawable
);
226 size_t offset
= 4 * (SIZE
* OFFSCREEN_OFFSET
+ OFFSCREEN_OFFSET
);
228 buffer_diff_noalpha (reference_data
+ offset
,
231 SIZE
- OFFSCREEN_OFFSET
,
232 SIZE
- OFFSCREEN_OFFSET
,
236 buffer_diff_noalpha (reference_data
,
245 cairo_test_log ("xlib-surface: %s, %s, %s%s: %s\n",
246 use_render
? " render" : "no-render",
247 set_size
? " size" : "no-size",
248 use_pixmap
? "pixmap" : "window",
251 (offscreen
? ", offscreen" : ", onscreen"),
252 result
.pixels_changed
? "FAIL" : "PASS");
254 if (result
.pixels_changed
)
255 return CAIRO_TEST_FAILURE
;
257 return CAIRO_TEST_SUCCESS
;
261 check_visual (Display
*dpy
)
263 Visual
*visual
= DefaultVisual (dpy
, DefaultScreen (dpy
));
265 if ((visual
->red_mask
== 0xff0000 &&
266 visual
->green_mask
== 0x00ff00 &&
267 visual
->blue_mask
== 0x0000ff) ||
268 (visual
->red_mask
== 0x0000ff &&
269 visual
->green_mask
== 0x00ff00 &&
270 visual
->blue_mask
== 0xff0000))
278 xcalloc (size_t a
, size_t b
)
280 void *ptr
= calloc (a
, b
);
282 cairo_test_log ("xlib-surface: unable to allocate memory, skipping\n");
293 unsigned char *reference_data
;
294 unsigned char *test_data
;
295 unsigned char *diff_data
;
296 cairo_surface_t
*reference_surface
;
297 cairo_bool_t use_pixmap
;
298 cairo_bool_t set_size
;
299 cairo_bool_t offscreen
;
300 cairo_test_status_t status
, result
= CAIRO_TEST_SUCCESS
;
303 cairo_test_init ("xlib-surface");
305 dpy
= XOpenDisplay (NULL
);
307 cairo_test_log ("xlib-surface: Cannot open display, skipping\n");
312 if (!check_visual (dpy
)) {
313 cairo_test_log ("xlib-surface: default visual is not RGB24 or BGR24, skipping\n");
318 stride
= cairo_format_stride_for_width (CAIRO_FORMAT_RGB24
, SIZE
);
320 reference_data
= xcalloc (SIZE
, stride
);
321 test_data
= xcalloc (SIZE
, stride
);
322 diff_data
= xcalloc (SIZE
, stride
);
324 reference_surface
= cairo_image_surface_create_for_data (reference_data
,
329 draw_pattern (reference_surface
);
330 cairo_surface_destroy (reference_surface
);
332 for (set_size
= 0; set_size
<= 1; set_size
++)
333 for (use_pixmap
= 0; use_pixmap
<= 1; use_pixmap
++)
334 for (offscreen
= 0; offscreen
<= 1; offscreen
++) {
335 status
= do_test (dpy
,
336 reference_data
, test_data
, diff_data
,
337 1, use_pixmap
, set_size
, offscreen
);
342 for (set_size
= 0; set_size
<= 1; set_size
++)
343 for (use_pixmap
= 0; use_pixmap
<= 1; use_pixmap
++)
344 for (offscreen
= 0; offscreen
<= 1; offscreen
++) {
345 status
= do_test (dpy
,
346 reference_data
, test_data
, diff_data
,
347 0, use_pixmap
, set_size
, offscreen
);
352 free (reference_data
);
358 cairo_debug_reset_static_data ();