[check] Filter programlistings for check-doc-syntax.sh
[cairo/haiku.git] / test / xlib-surface.c
blobeda085f501b2bf81e9a4e7209f9dbbabb4e84018
1 /*
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>
26 #include <stdio.h>
27 #include <stdlib.h>
29 #include "cairo.h"
30 #include "cairo-xlib.h"
31 #include "cairo-test.h"
33 #include "cairo-boilerplate-xlib.h"
35 #include "buffer-diff.h"
37 #define SIZE 100
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.
49 static cairo_bool_t
50 surface_compare_visual_and_format (cairo_surface_t *surface)
52 Display *dpy;
53 Visual *visual;
54 XRenderPictFormat *format;
56 dpy = cairo_xlib_surface_get_display (surface);
58 visual = cairo_xlib_surface_get_visual (surface);
59 if (visual == NULL)
60 return TRUE;
62 format = cairo_xlib_surface_get_xrender_format (surface);
63 if (format == NULL)
64 return TRUE;
66 return format == XRenderFindVisualFormat (dpy, visual);
69 #else
71 static cairo_bool_t
72 surface_compare_visual_and_format (cairo_surface_t *surface)
74 return TRUE;
77 #endif
79 static cairo_bool_t
80 check_similar_visual_and_format (cairo_surface_t *surface)
82 cairo_surface_t *similar;
83 cairo_bool_t ret;
85 similar = cairo_surface_create_similar (surface,
86 CAIRO_CONTENT_COLOR_ALPHA,
87 1, 1);
88 if (cairo_surface_status (similar))
89 return FALSE;
91 ret = surface_compare_visual_and_format (similar);
93 cairo_surface_destroy (similar);
95 return ret;
99 static void
100 draw_pattern (cairo_surface_t *surface)
102 cairo_t *cr = cairo_create (surface);
103 int i;
105 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
106 cairo_paint (cr);
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;
113 cairo_rectangle (cr,
114 inset, inset,
115 SIZE - 2 * inset, SIZE - 2 * inset);
116 cairo_fill (cr);
119 cairo_destroy (cr);
122 static void
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 */
128 cairo_paint (cr);
130 cairo_destroy (cr);
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;
145 cairo_t *test_cr;
146 buffer_diff_result_t result;
147 Drawable drawable;
148 int screen = DefaultScreen (dpy);
150 if (use_pixmap && offscreen)
151 return CAIRO_TEST_SUCCESS;
153 if (use_pixmap) {
154 drawable = XCreatePixmap (dpy, DefaultRootWindow (dpy),
155 SIZE, SIZE, DefaultDepth (dpy, screen));
156 } else {
157 XSetWindowAttributes xwa;
158 int x, y;
160 xwa.override_redirect = True;
162 if (offscreen) {
163 x = - OFFSCREEN_OFFSET;
164 y = - OFFSCREEN_OFFSET;
165 } else {
166 x = 0;
167 y = 0;
170 drawable = XCreateWindow (dpy, DefaultRootWindow (dpy),
171 x, y, SIZE, SIZE, 0,
172 DefaultDepth (dpy, screen), InputOutput,
173 DefaultVisual (dpy, screen),
174 CWOverrideRedirect, &xwa);
175 XMapWindow (dpy, drawable);
178 surface = cairo_xlib_surface_create (dpy,
179 drawable,
180 DefaultVisual (dpy, screen),
181 SIZE, SIZE);
183 if (! surface_compare_visual_and_format (surface))
184 return CAIRO_TEST_FAILURE;
186 if (!use_render)
187 cairo_boilerplate_xlib_surface_disable_render (surface);
189 if (set_size) {
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,
203 CAIRO_FORMAT_RGB24,
204 SIZE, SIZE,
205 SIZE * 4);
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);
220 if (use_pixmap)
221 XFreePixmap (dpy, drawable);
222 else
223 XDestroyWindow (dpy, drawable);
225 if (offscreen) {
226 size_t offset = 4 * (SIZE * OFFSCREEN_OFFSET + OFFSCREEN_OFFSET);
228 buffer_diff_noalpha (reference_data + offset,
229 test_data + offset,
230 diff_data + offset,
231 SIZE - OFFSCREEN_OFFSET,
232 SIZE - OFFSCREEN_OFFSET,
233 4 * SIZE,
234 &result);
235 } else {
236 buffer_diff_noalpha (reference_data,
237 test_data,
238 diff_data,
239 SIZE,
240 SIZE,
241 4 * SIZE,
242 &result);
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",
249 use_pixmap ?
250 " " :
251 (offscreen ? ", offscreen" : ", onscreen"),
252 result.pixels_changed ? "FAIL" : "PASS");
254 if (result.pixels_changed)
255 return CAIRO_TEST_FAILURE;
256 else
257 return CAIRO_TEST_SUCCESS;
260 static cairo_bool_t
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))
271 return 1;
272 else
273 return 0;
276 #undef xcalloc
277 static void *
278 xcalloc (size_t a, size_t b)
280 void *ptr = calloc (a, b);
281 if (ptr == NULL) {
282 cairo_test_log ("xlib-surface: unable to allocate memory, skipping\n");
283 cairo_test_fini ();
284 exit (0);
286 return ptr;
290 main (void)
292 Display *dpy;
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;
301 int stride;
303 cairo_test_init ("xlib-surface");
305 dpy = XOpenDisplay (NULL);
306 if (!dpy) {
307 cairo_test_log ("xlib-surface: Cannot open display, skipping\n");
308 cairo_test_fini ();
309 return 0;
312 if (!check_visual (dpy)) {
313 cairo_test_log ("xlib-surface: default visual is not RGB24 or BGR24, skipping\n");
314 cairo_test_fini ();
315 return 0;
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,
325 CAIRO_FORMAT_RGB24,
326 SIZE, SIZE,
327 stride);
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);
338 if (status)
339 result = status;
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);
348 if (status)
349 result = status;
352 free (reference_data);
353 free (test_data);
354 free (diff_data);
356 XCloseDisplay (dpy);
358 cairo_debug_reset_static_data ();
360 cairo_test_fini ();
362 return result;