diff options
Diffstat (limited to 'test/xlib-surface.c')
-rw-r--r-- | test/xlib-surface.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/test/xlib-surface.c b/test/xlib-surface.c new file mode 100644 index 0000000..d8c241c --- /dev/null +++ b/test/xlib-surface.c @@ -0,0 +1,269 @@ +/* + * Copyright © 2005 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Carl D. Worth <cworth@cworth.org> + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "cairo.h" +#include "cairo-xlib.h" +#include "cairo-xlib-xrender.h" +#include "cairo-test.h" +#include "cairo-xlib-test.h" + +#include "buffer-diff.h" + +#define SIZE 100 +#define OFFSCREEN_OFFSET 50 + +cairo_bool_t result = 0; +FILE *log_file = NULL; + +static void +draw_pattern (cairo_surface_t *surface) +{ + cairo_t *cr = cairo_create (surface); + int i; + + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ + cairo_paint (cr); + + cairo_set_source_rgba (cr, 0, 0.0, 0.0, 0.50); /* half-alpha-black */ + + for (i = 1; i <= 3; i++) { + int inset = SIZE / 8 * i; + + cairo_rectangle (cr, + inset, inset, + SIZE - 2 * inset, SIZE - 2 * inset); + cairo_fill (cr); + } + + cairo_destroy (cr); +} + +static void +erase_pattern (cairo_surface_t *surface) +{ + cairo_t *cr = cairo_create (surface); + + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_paint (cr); + + cairo_destroy (cr); +} + +static cairo_bool_t +do_test (Display *dpy, + unsigned char *reference_data, + unsigned char *test_data, + unsigned char *diff_data, + cairo_bool_t use_render, + cairo_bool_t use_pixmap, + cairo_bool_t set_size, + cairo_bool_t offscreen) +{ + cairo_surface_t *surface; + cairo_surface_t *test_surface; + cairo_t *test_cr; + cairo_bool_t result; + Drawable drawable; + int screen = DefaultScreen (dpy); + + if (use_pixmap && offscreen) + return 1; + + if (use_pixmap) { + drawable = XCreatePixmap (dpy, DefaultRootWindow (dpy), + SIZE, SIZE, DefaultDepth (dpy, screen)); + } else { + XSetWindowAttributes xwa; + int x, y; + + xwa.override_redirect = True; + + if (offscreen) { + x = - OFFSCREEN_OFFSET; + y = - OFFSCREEN_OFFSET; + } else { + x = 0; + y = 0; + } + + drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), + x, y, SIZE, SIZE, 0, + DefaultDepth (dpy, screen), InputOutput, + DefaultVisual (dpy, screen), + CWOverrideRedirect, &xwa); + XMapWindow (dpy, drawable); + } + + surface = cairo_xlib_surface_create (dpy, + drawable, + DefaultVisual (dpy, screen), + SIZE, SIZE); + + if (set_size) + cairo_xlib_surface_set_size (surface, SIZE, SIZE); + + draw_pattern (surface); + + test_surface = cairo_image_surface_create_for_data (test_data, + CAIRO_FORMAT_RGB24, + SIZE, SIZE, + SIZE * 4); + + test_cr = cairo_create (test_surface); + cairo_set_source_surface (test_cr, surface, 0, 0); + cairo_paint (test_cr); + + cairo_destroy (test_cr); + cairo_surface_destroy (test_surface); + + /* We erase the surface to black in case we get the same + * memory back again for the pixmap case. + */ + erase_pattern (surface); + cairo_surface_destroy (surface); + + if (use_pixmap) + XFreePixmap (dpy, drawable); + else + XDestroyWindow (dpy, drawable); + + if (offscreen) { + size_t offset = 4 * (SIZE * OFFSCREEN_OFFSET + OFFSCREEN_OFFSET); + + result = !buffer_diff (reference_data + offset, + test_data + offset, + diff_data + offset, + SIZE - OFFSCREEN_OFFSET, + SIZE - OFFSCREEN_OFFSET, + 4 * SIZE); + } else { + result = !buffer_diff (reference_data, + test_data, + diff_data, + SIZE, + SIZE, + 4 * SIZE); + } + + fprintf (log_file, "xlib-surface: %s, %s, %s%s: %s\n", + use_render ? " render" : "no-render", + set_size ? " size" : "no-size", + use_pixmap ? "pixmap" : "window", + use_pixmap ? + " " : + (offscreen ? ", offscreen" : ", onscreen"), + result ? "PASS" : "FAIL"); + + return result; +} + +static cairo_bool_t +check_visual (Display *dpy) +{ + Visual *visual = DefaultVisual (dpy, DefaultScreen (dpy)); + + if ((visual->red_mask == 0xff0000 && + visual->green_mask == 0x00ff00 && + visual->blue_mask == 0x0000ff) || + (visual->red_mask == 0x0000ff && + visual->green_mask == 0x00ff00 && + visual->blue_mask == 0xff0000)) + return 1; + else + return 0; +} + +int +main (void) +{ + Display *dpy; + unsigned char *reference_data; + unsigned char *test_data; + unsigned char *diff_data; + cairo_surface_t *reference_surface; + cairo_bool_t use_pixmap; + cairo_bool_t set_size; + cairo_bool_t offscreen; + result = 0; + + printf("\n"); + log_file = fopen ("xlib-surface.log", "w"); + if (log_file == NULL) { + fprintf (stderr, "Error opening log file: %s\n", "xlib-surface.log"); + log_file = stderr; + } + + dpy = XOpenDisplay (NULL); + if (!dpy) { + fprintf (log_file, "xlib-surface: Cannot open display, skipping\n"); + return 0; + } + + if (!check_visual (dpy)) { + fprintf (log_file, "xlib-surface: default visual is not RGB24 or BGR24, skipping\n"); + return 0; + } + + reference_data = malloc (SIZE * SIZE * 4); + test_data = malloc (SIZE * SIZE * 4); + diff_data = malloc (SIZE * SIZE * 4); + + reference_surface = cairo_image_surface_create_for_data (reference_data, + CAIRO_FORMAT_RGB24, + SIZE, SIZE, + SIZE * 4); + + draw_pattern (reference_surface); + cairo_surface_destroy (reference_surface); + + for (set_size = 0; set_size <= 1; set_size++) + for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++) + for (offscreen = 0; offscreen <= 1; offscreen++) + if (!do_test (dpy, + reference_data, test_data, diff_data, + 1, use_pixmap, set_size, offscreen)) + result = 1; + + cairo_test_xlib_disable_render (); + + for (set_size = 0; set_size <= 1; set_size++) + for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++) + for (offscreen = 0; offscreen <= 1; offscreen++) + if (!do_test (dpy, + reference_data, test_data, diff_data, + 0, use_pixmap, set_size, offscreen)) + result = 1; + + free (reference_data); + free (test_data); + free (diff_data); + + XCloseDisplay (dpy); + + return result; +} |