cairo_surface_t * cairo_boilerplate_convert_to_image (const char *filename, int page) { FILE *file; unsigned int flags = 0; cairo_surface_t *image; int ret; RETRY: file = cairo_boilerplate_open_any2ppm (filename, page, flags); if (file == NULL) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); image = cairo_boilerplate_image_surface_create_from_ppm_stream (file); ret = pclose (file); if (cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) { if (flags == 0) { /* Try again in a standalone process. */ cairo_surface_destroy (image); flags = CAIRO_BOILERPLATE_OPEN_NO_DAEMON; goto RETRY; } } if (cairo_surface_status (image) == CAIRO_STATUS_SUCCESS && ret != 0) { cairo_surface_destroy (image); image = cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); }; return image; }
static cairo_surface_t * _cairo_boilerplate_win32_printing_get_image_surface (cairo_surface_t *surface, int page, int width, int height) { win32_target_closure_t *ptc = cairo_surface_get_user_data (surface, &win32_closure_key); char *filename; cairo_status_t status; /* XXX test paginated interface */ if (page != 0) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); xasprintf (&filename, "%s.png", ptc->filename); status = _cairo_boilerplate_win32_printing_surface_write_to_png (surface, filename); if (status) return cairo_boilerplate_surface_create_in_error (status); surface = cairo_boilerplate_get_image_surface_from_png (filename, width, height, ptc->target == NULL); remove (filename); free (filename); return surface; }
static cairo_surface_t * _cairo_boilerplate_ps_get_image_surface (cairo_surface_t *surface, int page, int width, int height) { ps_target_closure_t *ptc = cairo_surface_get_user_data (surface, &ps_closure_key); char *filename; cairo_status_t status; if (page == 0) xasprintf (&filename, "%s.png", ptc->filename); else xasprintf (&filename, "%s-%%05d.png", ptc->filename); status = _cairo_boilerplate_ps_surface_write_to_png (surface, filename); if (status) return cairo_boilerplate_surface_create_in_error (status); if (page != 0) { free (filename); xasprintf (&filename, "%s-%05d.png", ptc->filename, page); } surface = cairo_boilerplate_get_image_surface_from_png (filename, width, height, ptc->target == NULL); remove (filename); free (filename); return surface; }
cairo_surface_t * cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file) { char format; int width, height, stride; int x, y; unsigned char *data; cairo_surface_t *image = NULL; if (fscanf (file, "P%c %d %d 255\n", &format, &width, &height) != 3) goto FAIL; switch (format) { case '7': /* XXX */ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); break; case '6': image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); break; case '5': image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); break; default: goto FAIL; } if (cairo_surface_status (image)) goto FAIL; data = cairo_image_surface_get_data (image); stride = cairo_image_surface_get_stride (image); for (y = 0; y < height; y++) { unsigned char *buf = data + y *stride; switch (format) { case '7': if (! freadn (buf, 4 * width, file)) goto FAIL; break; case '6': for (x = 0; x < width; x++) { if (! freadn (buf, 3, file)) goto FAIL; *(uint32_t *) buf = (buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0); buf += 4; } break; case '5': if (! freadn (buf, width, file)) goto FAIL; break; } } return image; FAIL: cairo_surface_destroy (image); return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); }
cairo_surface_t * _cairo_boilerplate_pdf_create_surface (const char *name, cairo_content_t content, int width, int height, int max_width, int max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { pdf_target_closure_t *ptc; cairo_surface_t *surface; cairo_status_t status; /* Sanitize back to a real cairo_content_t value. */ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) content = CAIRO_CONTENT_COLOR_ALPHA; *closure = ptc = xmalloc (sizeof (pdf_target_closure_t)); ptc->width = width; ptc->height = height; xasprintf (&ptc->filename, "%s-out.pdf", name); xunlink (ptc->filename); surface = cairo_pdf_surface_create (ptc->filename, width, height); if (cairo_surface_status (surface)) goto CLEANUP_FILENAME; cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { ptc->target = surface; surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); if (cairo_surface_status (surface)) goto CLEANUP_TARGET; } else { ptc->target = NULL; } status = cairo_surface_set_user_data (surface, &pdf_closure_key, ptc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); CLEANUP_TARGET: cairo_surface_destroy (ptc->target); CLEANUP_FILENAME: free (ptc->filename); free (ptc); return surface; }
cairo_surface_t * _cairo_boilerplate_glitz_wgl_create_surface (const char *name, cairo_content_t content, int width, int height, int max_width, int max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { glitz_surface_t *glitz_surface; cairo_surface_t *surface = NULL; glitz_wgl_target_closure_t *wglc; glitz_wgl_init (NULL); *closure = wglc = xmalloc (sizeof (glitz_wgl_target_closure_t)); switch (content) { case CAIRO_CONTENT_COLOR: glitz_surface = _cairo_boilerplate_glitz_wgl_create_surface_internal (GLITZ_STANDARD_RGB24, width, height, NULL); break; case CAIRO_CONTENT_COLOR_ALPHA: glitz_surface = _cairo_boilerplate_glitz_wgl_create_surface_internal (GLITZ_STANDARD_ARGB32, width, height, NULL); break; default: CAIRO_BOILERPLATE_LOG ("Invalid content for glitz-wgl test: %d\n", content); goto FAIL; } if (!glitz_surface) goto FAIL; surface = cairo_glitz_surface_create (glitz_surface); glitz_surface_destroy (glitz_surface); if (cairo_surface_status (surface)) goto FAIL; wglc->base.width = width; wglc->base.height = height; wglc->base.content = content; status = cairo_boilerplate_surface_set_user_data (surface, &glitz_closure_key, wglc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); FAIL: glitz_wgl_fini (); free (wglc); return surface; }
static cairo_surface_t * _cairo_boilerplate_svg_create_surface (const char *name, cairo_content_t content, cairo_svg_version_t version, int width, int height, int max_width, int max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { svg_target_closure_t *ptc; cairo_surface_t *surface; cairo_status_t status; *closure = ptc = xmalloc (sizeof (svg_target_closure_t)); ptc->width = width; ptc->height = height; xasprintf (&ptc->filename, "%s-out.svg", name); xunlink (ptc->filename); surface = cairo_svg_surface_create (ptc->filename, width, height); if (cairo_surface_status (surface)) goto CLEANUP_FILENAME; cairo_svg_surface_restrict_to_version (surface, version); cairo_surface_set_fallback_resolution (surface, 72., 72.); if (content == CAIRO_CONTENT_COLOR) { ptc->target = surface; surface = cairo_surface_create_similar (ptc->target, CAIRO_CONTENT_COLOR, width, height); if (cairo_surface_status (surface)) goto CLEANUP_TARGET; } else ptc->target = NULL; status = cairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); CLEANUP_TARGET: cairo_surface_destroy (ptc->target); CLEANUP_FILENAME: free (ptc->filename); free (ptc); return surface; }
cairo_surface_t * cairo_boilerplate_convert_to_image (const char *filename, int page) { FILE *file; unsigned int flags = 0; cairo_surface_t *image; int (*close_cb) (FILE *); int ret; RETRY: file = cairo_boilerplate_open_any2ppm (filename, page, flags, &close_cb); if (file == NULL) { switch (errno) { case ENOMEM: return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); default: return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); } } image = cairo_boilerplate_image_surface_create_from_ppm_stream (file); ret = close_cb (file); /* check for fatal errors from the interpreter */ if (ret) { /* any2pmm should never die... */ cairo_surface_destroy (image); return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_INVALID_STATUS); } if (ret == 0 && cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) { if (flags == 0) { /* Try again in a standalone process. */ cairo_surface_destroy (image); flags = CAIRO_BOILERPLATE_OPEN_NO_DAEMON; goto RETRY; } } return image; }
static cairo_surface_t * _cairo_boilerplate_test_paginated_get_image_surface (cairo_surface_t *surface, int page, int width, int height) { test_paginated_closure_t *tpc; cairo_status_t status; /* XXX separate finish as per PDF */ if (page != 0) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); /* show page first. the automatic show_page is too late for us */ cairo_surface_show_page (surface); status = cairo_surface_status (surface); if (status) return cairo_boilerplate_surface_create_in_error (status); tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key); return _cairo_boilerplate_get_image_surface (tpc->target, 0, width, height); }
cairo_surface_t * _cairo_boilerplate_get_image_surface (cairo_surface_t *src, int page, int width, int height) { cairo_surface_t *surface; cairo_t *cr; #if 0 if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_IMAGE) { int ww = cairo_image_surface_get_width (src); int hh = cairo_image_surface_get_height (src); if (width == ww && hh == height) { return cairo_surface_reference (src); } else { cairo_format_t format = cairo_image_surface_get_format (src); unsigned char *data = cairo_image_surface_get_data (src); int stride = cairo_image_surface_get_stride (src); data += stride * (hh - height) + 4 * (ww - width); return cairo_image_surface_create_for_data (data, format, width, height, stride); } } #endif if (page != 0) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); /* extract sub-surface */ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); cairo_surface_destroy (surface); cairo_set_source_surface (cr, src, 0, 0); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); surface = cairo_surface_reference (cairo_get_target (cr)); cairo_destroy (cr); return surface; }
static cairo_surface_t * _cairo_boilerplate_svg_convert_to_image (cairo_surface_t *surface) { svg_target_closure_t *ptc = cairo_surface_get_user_data (surface, &svg_closure_key); FILE *file; cairo_surface_t *image; file = cairo_boilerplate_open_any2ppm (ptc->filename, 0); if (file == NULL) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); image = cairo_boilerplate_image_surface_create_from_ppm_stream (file); fclose (file); return image; }
cairo_surface_t * _cairo_boilerplate_svg_get_image_surface (cairo_surface_t *surface, int page, int width, int height) { cairo_surface_t *image; if (page != 0) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); image = _cairo_boilerplate_svg_convert_to_image (surface); cairo_surface_set_device_offset (image, cairo_image_surface_get_width (image) - width, cairo_image_surface_get_height (image) - height); surface = _cairo_boilerplate_get_image_surface (image, 0, width, height); cairo_surface_destroy (image); return surface; }
static cairo_surface_t * _cairo_boilerplate_test_paginated_create_surface (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { test_paginated_closure_t *tpc; cairo_format_t format; cairo_surface_t *surface; cairo_status_t status; *closure = tpc = xmalloc (sizeof (test_paginated_closure_t)); format = cairo_boilerplate_format_from_content (content); tpc->target = cairo_image_surface_create (format, ceil (width), ceil (height)); surface = _cairo_test_paginated_surface_create (tpc->target); if (cairo_surface_status (surface)) goto CLEANUP; status = cairo_surface_set_user_data (surface, &test_paginated_closure_key, tpc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); cairo_surface_destroy (tpc->target); CLEANUP: free (tpc); return surface; }
static cairo_surface_t * _cairo_boilerplate_xcb_create_surface (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, void **closure) { xcb_screen_t *root; xcb_target_closure_t *xtc; xcb_connection_t *c; xcb_render_query_pict_formats_cookie_t formats_cookie; xcb_render_pictforminfo_t *render_format; xcb_render_pictforminfo_iterator_t i; struct xcb_info *info; int depth; xcb_void_cookie_t cookie; cairo_surface_t *surface; cairo_status_t status; *closure = xtc = xmalloc (sizeof (xcb_target_closure_t)); info = xcalloc (1, sizeof (struct xcb_info)); if (width == 0) width = 1; if (height == 0) height = 1; xtc->c = c = xcb_connect(NULL,NULL); if (c == NULL || xcb_connection_has_error(c)) { free (xtc); return NULL; } root = xcb_setup_roots_iterator(xcb_get_setup(c)).data; formats_cookie = xcb_render_query_pict_formats (c); xtc->surface = NULL; xtc->is_pixmap = TRUE; xtc->drawable = xcb_generate_id (c); switch (content) { case CAIRO_CONTENT_COLOR: depth = 24; break; case CAIRO_CONTENT_COLOR_ALPHA: depth = 32; break; case CAIRO_CONTENT_ALPHA: /* would be XCB_PICT_STANDARD_A_8 */ default: xcb_disconnect (c); free (xtc); return NULL; } cookie = xcb_create_pixmap_checked (c, depth, xtc->drawable, root->root, width, height); /* slow, but sure */ if (xcb_request_check (c, cookie) != NULL) { xcb_disconnect (c); free (xtc); return NULL; } info->formats = xcb_render_query_pict_formats_reply (c, formats_cookie, 0); if (info->formats == NULL) return NULL; for (i = xcb_render_query_pict_formats_formats_iterator (info->formats); i.rem; xcb_render_pictforminfo_next (&i)) { if (XCB_RENDER_PICT_TYPE_DIRECT != i.data->type) continue; if (i.data->depth == 32) { if (info->render_format[0] == 0) info->render_format[0] = i.data; } else if (i.data->depth == 24) { if (info->render_format[1] == 0) info->render_format[1] = i.data; } else if (i.data->depth == 8) { if (info->render_format[2] == 0) info->render_format[2] = i.data; } } assert (info->render_format[0]); assert (info->render_format[1]); assert (info->render_format[2]); switch (content) { default: case CAIRO_CONTENT_COLOR_ALPHA: render_format = info->render_format[0]; break; case CAIRO_CONTENT_COLOR: render_format = info->render_format[1]; break; case CAIRO_CONTENT_ALPHA: /* would be XCB_PICT_STANDARD_A_8 */ render_format = info->render_format[2]; break; } surface = cairo_xcb_surface_create_with_xrender_format (c, root, xtc->drawable, render_format, width, height); cairo_device_set_user_data (cairo_surface_get_device (surface), &key, info, free); if (mode != CAIRO_BOILERPLATE_MODE_PERF) _cairo_boilerplate_xcb_setup_test_surface(surface); xtc->device = cairo_device_reference (cairo_surface_get_device (surface)); status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); _cairo_boilerplate_xcb_cleanup (xtc); return cairo_boilerplate_surface_create_in_error (status); }
static cairo_surface_t * _cairo_boilerplate_gl_create_window_db (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, void **closure) { int rgba_attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 1, GLX_DOUBLEBUFFER, None }; int msaa_attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 1, GLX_STENCIL_SIZE, 1, GLX_SAMPLES, 4, GLX_SAMPLE_BUFFERS, 1, GLX_DOUBLEBUFFER, None }; XVisualInfo *vi; GLXContext ctx; gl_target_closure_t *gltc; cairo_surface_t *surface; Display *dpy; XSetWindowAttributes attr; cairo_status_t status; gltc = calloc (1, sizeof (gl_target_closure_t)); *closure = gltc; if (width == 0) width = 1; if (height == 0) height = 1; dpy = XOpenDisplay (NULL); gltc->dpy = dpy; if (!gltc->dpy) { fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0)); free (gltc); return NULL; } if (mode == CAIRO_BOILERPLATE_MODE_TEST) XSynchronize (gltc->dpy, 1); vi = glXChooseVisual (dpy, DefaultScreen (dpy), msaa_attribs); if (vi == NULL) vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs); if (vi == NULL) { fprintf (stderr, "Failed to create RGBA, double-buffered visual\n"); XCloseDisplay (dpy); free (gltc); return NULL; } attr.colormap = XCreateColormap (dpy, RootWindow (dpy, vi->screen), vi->visual, AllocNone); attr.border_pixel = 0; attr.override_redirect = True; gltc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWOverrideRedirect | CWBorderPixel | CWColormap, &attr); XMapWindow (dpy, gltc->drawable); ctx = glXCreateContext (dpy, vi, NULL, True); XFree (vi); gltc->ctx = ctx; gltc->device = cairo_glx_device_create (dpy, ctx); gltc->surface = cairo_gl_surface_create_for_window (gltc->device, gltc->drawable, ceil (width), ceil (height)); surface = cairo_surface_create_similar (gltc->surface, content, width, height); status = cairo_surface_set_user_data (surface, &gl_closure_key, gltc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); _cairo_boilerplate_gl_cleanup (gltc); return cairo_boilerplate_surface_create_in_error (status); }
cairo_surface_t * _cairo_boilerplate_get_image_surface (cairo_surface_t *src, int page, int width, int height) { cairo_surface_t *surface, *image; cairo_t *cr; cairo_status_t status; cairo_format_t format; if (cairo_surface_status (src)) return cairo_surface_reference (src); if (page != 0) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); /* extract sub-surface */ switch (cairo_surface_get_content (src)) { case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break; case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break; default: case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break; } surface = cairo_image_surface_create (format, width, height); assert (cairo_surface_get_content (surface) == cairo_surface_get_content (src)); image = cairo_surface_reference (surface); /* open a logging channel (only interesting for recording surfaces) */ #if CAIRO_HAS_SCRIPT_SURFACE && CAIRO_HAS_RECORDING_SURFACE if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_RECORDING) { const char *test_name; test_name = cairo_surface_get_user_data (src, &cairo_boilerplate_output_basename_key); if (test_name != NULL) { cairo_device_t *ctx; char *filename; cairo_surface_destroy (surface); xasprintf (&filename, "%s.out.trace", test_name); ctx = cairo_script_create (filename); surface = cairo_script_surface_create_for_target (ctx, image); cairo_device_destroy (ctx); free (filename); } } #endif cr = cairo_create (surface); cairo_surface_destroy (surface); cairo_set_source_surface (cr, src, 0, 0); cairo_paint (cr); status = cairo_status (cr); if (status) { cairo_surface_destroy (image); image = cairo_surface_reference (cairo_get_target (cr)); } cairo_destroy (cr); return image; }
cairo_surface_t * _cairo_boilerplate_glitz_glx_create_surface (const char *name, cairo_content_t content, int width, int height, int max_width, int max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { glitz_glx_target_closure_t *gxtc; glitz_surface_t * glitz_surface; cairo_surface_t * surface = NULL; cairo_status_t status; *closure = gxtc = xmalloc (sizeof (glitz_glx_target_closure_t)); if (width == 0) width = 1; if (height == 0) height = 1; gxtc->dpy = XOpenDisplay (getenv("CAIRO_TEST_GLITZ_DISPLAY")); if (!gxtc->dpy) { CAIRO_BOILERPLATE_LOG ("Failed to open display: %s\n", XDisplayName(0)); goto FAIL; } XSynchronize (gxtc->dpy, 1); gxtc->scr = DefaultScreen(gxtc->dpy); switch (content) { case CAIRO_CONTENT_COLOR: glitz_surface = _cairo_boilerplate_glitz_glx_create_surface_internal (GLITZ_STANDARD_RGB24, width, height, gxtc); break; case CAIRO_CONTENT_COLOR_ALPHA: glitz_surface = _cairo_boilerplate_glitz_glx_create_surface_internal (GLITZ_STANDARD_ARGB32, width, height, gxtc); break; case CAIRO_CONTENT_ALPHA: default: CAIRO_BOILERPLATE_LOG ("Invalid content for glitz-glx test: %d\n", content); goto FAIL_CLOSE_DISPLAY; } if (!glitz_surface) { CAIRO_BOILERPLATE_LOG ("Failed to create glitz-glx surface\n"); goto FAIL_CLOSE_DISPLAY; } surface = cairo_glitz_surface_create (glitz_surface); glitz_surface_destroy (glitz_surface); if (cairo_surface_status (surface)) goto FAIL_CLOSE_DISPLAY; gxtc->base.width = width; gxtc->base.height = height; gxtc->base.content = content; status = cairo_boilerplate_surface_set_user_data (surface, &glitz_closure_key, gxtc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); FAIL_CLOSE_DISPLAY: glitz_glx_fini (); XCloseDisplay (gxtc->dpy); FAIL: free (gxtc); return surface; }
static cairo_surface_t * _cairo_boilerplate_xcb_create_surface (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { xcb_screen_t *root; xcb_target_closure_t *xtc; xcb_connection_t *c; xcb_render_pictforminfo_t *render_format; xcb_pict_standard_t format; xcb_void_cookie_t cookie; cairo_surface_t *surface; cairo_status_t status; *closure = xtc = xmalloc (sizeof (xcb_target_closure_t)); if (width == 0) width = 1; if (height == 0) height = 1; xtc->c = c = xcb_connect(NULL,NULL); if (xcb_connection_has_error(c)) { fprintf (stderr, "Failed to connect to X server through XCB\n"); return NULL; } root = xcb_setup_roots_iterator(xcb_get_setup(c)).data; xtc->pixmap = xcb_generate_id (c); switch (content) { case CAIRO_CONTENT_COLOR: cookie = xcb_create_pixmap_checked (c, 24, xtc->pixmap, root->root, width, height); format = XCB_PICT_STANDARD_RGB_24; break; case CAIRO_CONTENT_COLOR_ALPHA: cookie = xcb_create_pixmap_checked (c, 32, xtc->pixmap, root->root, width, height); format = XCB_PICT_STANDARD_ARGB_32; break; case CAIRO_CONTENT_ALPHA: /* would be XCB_PICT_STANDARD_A_8 */ default: fprintf (stderr, "Invalid content for XCB test: %d\n", content); return NULL; } /* slow, but sure */ if (xcb_request_check (c, cookie) != NULL) { xcb_disconnect (c); free (xtc); return NULL; } render_format = xcb_render_util_find_standard_format (xcb_render_util_query_formats (c), format); if (render_format->id == 0) return NULL; surface = cairo_xcb_surface_create_with_xrender_format (c, xtc->pixmap, root, render_format, width, height); status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); _cairo_boilerplate_xcb_cleanup (xtc); return surface; }
static cairo_surface_t * _cairo_boilerplate_xcb_create_fallback (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { xcb_target_closure_t *xtc; xcb_connection_t *c; xcb_screen_t *s; xcb_void_cookie_t cookie; cairo_surface_t *tmp, *surface; cairo_status_t status; uint32_t values[] = { 1 }; *closure = xtc = xmalloc (sizeof (xcb_target_closure_t)); if (width == 0) width = 1; if (height == 0) height = 1; xtc->c = c = xcb_connect (NULL,NULL); if (xcb_connection_has_error(c)) { free (xtc); return NULL; } s = xcb_setup_roots_iterator (xcb_get_setup (c)).data; if (width > s->width_in_pixels || height > s->height_in_pixels) { xcb_disconnect (c); free (xtc); return NULL; } xtc->surface = NULL; xtc->is_pixmap = FALSE; xtc->drawable = xcb_generate_id (c); cookie = xcb_create_window_checked (c, s->root_depth, xtc->drawable, s->root, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual, XCB_CW_OVERRIDE_REDIRECT, values); xcb_map_window (c, xtc->drawable); /* slow, but sure */ if (xcb_request_check (c, cookie) != NULL) { xcb_disconnect (c); free (xtc); return NULL; } tmp = cairo_xcb_surface_create (c, xtc->drawable, lookup_visual (s, s->root_visual), width, height); if (cairo_surface_status (tmp)) { xcb_disconnect (c); free (xtc); return tmp; } cairo_xcb_device_debug_cap_xrender_version (cairo_surface_get_device (tmp), -1, -1); /* recreate with impaired connection */ surface = cairo_xcb_surface_create (c, xtc->drawable, lookup_visual (s, s->root_visual), width, height); cairo_surface_destroy (tmp); xtc->device = cairo_device_reference (cairo_surface_get_device (surface)); status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); _cairo_boilerplate_xcb_cleanup (xtc); return cairo_boilerplate_surface_create_in_error (status); }
static cairo_surface_t * _cairo_boilerplate_xcb_create_render_0_0 (const char *name, cairo_content_t content, double width, double height, double max_width, double max_height, cairo_boilerplate_mode_t mode, int id, void **closure) { xcb_screen_t *root; xcb_target_closure_t *xtc; xcb_connection_t *c; xcb_render_pictforminfo_t *render_format; int depth; xcb_void_cookie_t cookie; cairo_surface_t *surface, *tmp; cairo_status_t status; void *formats; *closure = xtc = xmalloc (sizeof (xcb_target_closure_t)); if (width == 0) width = 1; if (height == 0) height = 1; xtc->c = c = xcb_connect(NULL,NULL); if (xcb_connection_has_error(c)) { free (xtc); return NULL; } root = xcb_setup_roots_iterator(xcb_get_setup(c)).data; xtc->surface = NULL; xtc->is_pixmap = TRUE; xtc->drawable = xcb_generate_id (c); switch (content) { case CAIRO_CONTENT_COLOR: depth = 24; cookie = xcb_create_pixmap_checked (c, depth, xtc->drawable, root->root, width, height); break; case CAIRO_CONTENT_COLOR_ALPHA: depth = 32; cookie = xcb_create_pixmap_checked (c, depth, xtc->drawable, root->root, width, height); break; case CAIRO_CONTENT_ALPHA: /* would be XCB_PICT_STANDARD_A_8 */ default: xcb_disconnect (c); free (xtc); return NULL; } /* slow, but sure */ if (xcb_request_check (c, cookie) != NULL) { xcb_disconnect (c); free (xtc); return NULL; } render_format = find_depth (c, depth, &formats); if (render_format == NULL) { xcb_disconnect (c); free (xtc); return NULL; } tmp = cairo_xcb_surface_create_with_xrender_format (c, root, xtc->drawable, render_format, width, height); if (cairo_surface_status (tmp)) { free (formats); xcb_disconnect (c); free (xtc); return tmp; } xtc->device = cairo_device_reference (cairo_surface_get_device (tmp)); cairo_xcb_device_debug_cap_xrender_version (xtc->device, 0, 0); /* recreate with impaired connection */ surface = cairo_xcb_surface_create_with_xrender_format (c, root, xtc->drawable, render_format, width, height); free (formats); cairo_surface_destroy (tmp); assert (cairo_surface_get_device (surface) == xtc->device); status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL); if (status == CAIRO_STATUS_SUCCESS) return surface; cairo_surface_destroy (surface); _cairo_boilerplate_xcb_cleanup (xtc); return cairo_boilerplate_surface_create_in_error (status); }