1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2002 University of Southern California
5 * Copyright © 2005 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
30 * The Original Code is the cairo graphics library.
32 * The Initial Developer of the Original Code is University of Southern
36 * Carl D. Worth <cworth@cworth.org>
37 * Behdad Esfahbod <behdad@behdad.org>
38 * Chris Wilson <chris@chris-wilson.co.uk>
39 * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
42 /* Heed well the words of Owen Taylor:
43 * "Any patch that works around a render bug, or claims to, without a
44 * specific reference to the bug filed in bugzilla.freedesktop.org will
45 * never pass approval."
50 #if !CAIRO_HAS_XLIB_XCB_FUNCTIONS
52 #include "cairo-xlib-private.h"
53 #include "cairo-xlib-surface-private.h"
55 #include "cairo-compositor-private.h"
56 #include "cairo-clip-private.h"
57 #include "cairo-default-context-private.h"
58 #include "cairo-error-private.h"
59 #include "cairo-image-surface-private.h"
60 #include "cairo-list-inline.h"
61 #include "cairo-pattern-private.h"
62 #include "cairo-region-private.h"
63 #include "cairo-scaled-font-private.h"
64 #include "cairo-surface-snapshot-private.h"
65 #include "cairo-surface-subsurface-private.h"
67 #include <X11/Xutil.h> /* for XDestroyImage */
69 #define XLIB_COORD_MAX 32767
74 #define UNSUPPORTED(reason) \
76 "cairo-xlib: hit unsupported operation %s(), line %d: %s\n", \
77 __FUNCTION__, __LINE__, reason), \
78 CAIRO_INT_STATUS_UNSUPPORTED
80 #define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
84 #include <X11/Xlibint.h>
85 static void CAIRO_PRINTF_FORMAT (2, 3)
86 _x_bread_crumb (Display *dpy,
92 unsigned int len, len_dwords;
96 len = vsnprintf (buf, sizeof (buf), fmt, ap);
104 GetEmptyReq (NoOperation, req);
106 len_dwords = len >> 2;
107 SetReqLen (req, len_dwords, len_dwords);
108 Data (dpy, buf, len);
113 #define X_DEBUG(x) _x_bread_crumb x
120 * @Title: XLib Surfaces
121 * @Short_Description: X Window System rendering using XLib
122 * @See_Also: #cairo_surface_t
124 * The XLib surface is used to render cairo graphics to X Window System
125 * windows and pixmaps using the XLib library.
127 * Note that the XLib surface automatically takes advantage of X render extension
128 * if it is available.
132 * CAIRO_HAS_XLIB_SURFACE:
134 * Defined if the Xlib surface backend is available.
135 * This macro can be used to conditionally compile backend-specific code.
141 * SECTION:cairo-xlib-xrender
142 * @Title: XLib-XRender Backend
143 * @Short_Description: X Window System rendering using XLib and the X Render extension
144 * @See_Also: #cairo_surface_t
146 * The XLib surface is used to render cairo graphics to X Window System
147 * windows and pixmaps using the XLib and Xrender libraries.
149 * Note that the XLib surface automatically takes advantage of X Render extension
150 * if it is available.
154 * CAIRO_HAS_XLIB_XRENDER_SURFACE:
156 * Defined if the XLib/XRender surface functions are available.
157 * This macro can be used to conditionally compile backend-specific code.
162 /* Xlib doesn't define a typedef, so define one ourselves */
163 typedef int (*cairo_xlib_error_func_t) (Display *display,
166 static cairo_surface_t *
167 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
170 XRenderPictFormat *xrender_format,
176 _cairo_surface_is_xlib (cairo_surface_t *surface);
179 * Instead of taking two round trips for each blending request,
180 * assume that if a particular drawable fails GetImage that it will
181 * fail for a "while"; use temporary pixmaps to avoid the errors
184 #define CAIRO_ASSUME_PIXMAP 20
186 static const XTransform identity = { {
187 { 1 << 16, 0x00000, 0x00000 },
188 { 0x00000, 1 << 16, 0x00000 },
189 { 0x00000, 0x00000, 1 << 16 },
193 _visual_for_xrender_format(Screen *screen,
194 XRenderPictFormat *xrender_format)
198 /* XXX Consider searching through the list of known cairo_visual_t for
199 * the reverse mapping.
202 for (d = 0; d < screen->ndepths; d++) {
203 Depth *d_info = &screen->depths[d];
205 if (d_info->depth != xrender_format->depth)
208 for (v = 0; v < d_info->nvisuals; v++) {
209 Visual *visual = &d_info->visuals[v];
211 switch (visual->class) {
213 if (xrender_format->type != PictTypeDirect)
218 /* Prefer TrueColor to DirectColor.
219 * (XRenderFindVisualFormat considers both TrueColor and DirectColor
220 * Visuals to match the same PictFormat.)
228 if (xrender_format->type != PictTypeIndexed)
233 if (xrender_format ==
234 XRenderFindVisualFormat (DisplayOfScreen(screen), visual))
242 static cairo_content_t
243 _xrender_format_to_content (XRenderPictFormat *xrender_format)
245 cairo_content_t content;
247 /* This only happens when using a non-Render server. Let's punt
248 * and say there's no alpha here. */
249 if (xrender_format == NULL)
250 return CAIRO_CONTENT_COLOR;
253 if (xrender_format->direct.alphaMask)
254 content |= CAIRO_CONTENT_ALPHA;
255 if (xrender_format->direct.redMask |
256 xrender_format->direct.greenMask |
257 xrender_format->direct.blueMask)
258 content |= CAIRO_CONTENT_COLOR;
263 static cairo_surface_t *
264 _cairo_xlib_surface_create_similar (void *abstract_src,
265 cairo_content_t content,
269 cairo_xlib_surface_t *src = abstract_src;
270 XRenderPictFormat *xrender_format;
271 cairo_xlib_surface_t *surface;
272 cairo_xlib_display_t *display;
275 if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
278 if (width == 0 || height == 0)
281 if (_cairo_xlib_display_acquire (src->base.device, &display))
284 /* If we never found an XRenderFormat or if it isn't compatible
285 * with the content being requested, then we fallback to just
286 * constructing a cairo_format_t instead, (which will fairly
287 * arbitrarily pick a visual/depth for the similar surface.
289 xrender_format = NULL;
290 if (src->xrender_format &&
291 _xrender_format_to_content (src->xrender_format) == content)
293 xrender_format = src->xrender_format;
295 if (xrender_format == NULL) {
297 _cairo_xlib_display_get_xrender_format (display,
298 _cairo_format_from_content (content));
300 if (xrender_format) {
303 /* We've got a compatible XRenderFormat now, which means the
304 * similar surface will match the existing surface as closely in
305 * visual/depth etc. as possible. */
306 pix = XCreatePixmap (display->display, src->drawable,
307 width, height, xrender_format->depth);
309 if (xrender_format == src->xrender_format)
310 visual = src->visual;
312 visual = _visual_for_xrender_format(src->screen->screen,
315 surface = (cairo_xlib_surface_t *)
316 _cairo_xlib_surface_create_internal (src->screen, pix, visual,
319 xrender_format->depth);
323 Screen *screen = src->screen->screen;
326 /* No compatible XRenderFormat, see if we can make an ordinary pixmap,
327 * so that we can still accelerate blits with XCopyArea(). */
328 if (content != CAIRO_CONTENT_COLOR) {
329 cairo_device_release (&display->base);
333 depth = DefaultDepthOfScreen (screen);
335 pix = XCreatePixmap (display->display, RootWindowOfScreen (screen),
336 width <= 0 ? 1 : width, height <= 0 ? 1 : height,
339 surface = (cairo_xlib_surface_t *)
340 _cairo_xlib_surface_create_internal (src->screen, pix,
341 DefaultVisualOfScreen (screen),
343 width, height, depth);
346 if (likely (surface->base.status == CAIRO_STATUS_SUCCESS))
347 surface->owns_pixmap = TRUE;
349 XFreePixmap (display->display, pix);
351 cairo_device_release (&display->base);
353 return &surface->base;
356 static cairo_status_t
357 _cairo_xlib_surface_finish (void *abstract_surface)
359 cairo_xlib_surface_t *surface = abstract_surface;
360 cairo_status_t status;
361 cairo_xlib_display_t *display;
363 X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable));
365 cairo_list_del (&surface->link);
367 status = _cairo_xlib_display_acquire (surface->base.device, &display);
368 if (unlikely (status))
371 if (surface->embedded_source.picture)
372 XRenderFreePicture (display->display, surface->embedded_source.picture);
373 if (surface->picture)
374 XRenderFreePicture (display->display, surface->picture);
375 if (surface->owns_pixmap)
376 XFreePixmap (display->display, surface->drawable);
378 cairo_device_release (&display->base);
384 _cairo_xlib_surface_get_gc (cairo_xlib_display_t *display,
385 cairo_xlib_surface_t *surface,
388 *gc = _cairo_xlib_screen_get_gc (display,
392 if (unlikely (*gc == NULL))
393 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
395 return CAIRO_STATUS_SUCCESS;
399 _noop_error_handler (Display *display,
402 return False; /* return value is ignored */
406 _swap_ximage_2bytes (XImage *ximage)
409 char *line = ximage->data;
411 for (j = ximage->height; j; j--) {
412 uint16_t *p = (uint16_t *) line;
413 for (i = ximage->width; i; i--) {
418 line += ximage->bytes_per_line;
423 _swap_ximage_3bytes (XImage *ximage)
426 char *line = ximage->data;
428 for (j = ximage->height; j; j--) {
429 uint8_t *p = (uint8_t *) line;
430 for (i = ximage->width; i; i--) {
438 line += ximage->bytes_per_line;
443 _swap_ximage_4bytes (XImage *ximage)
446 char *line = ximage->data;
448 for (j = ximage->height; j; j--) {
449 uint32_t *p = (uint32_t *) line;
450 for (i = ximage->width; i; i--) {
455 line += ximage->bytes_per_line;
460 _swap_ximage_nibbles (XImage *ximage)
463 char *line = ximage->data;
465 for (j = ximage->height; j; j--) {
466 uint8_t *p = (uint8_t *) line;
467 for (i = (ximage->width + 1) / 2; i; i--) {
468 *p = ((*p >> 4) & 0xf) | ((*p << 4) & ~0xf);
472 line += ximage->bytes_per_line;
477 _swap_ximage_bits (XImage *ximage)
480 char *line = ximage->data;
481 int unit = ximage->bitmap_unit;
482 int line_bytes = ((ximage->width + unit - 1) & ~(unit - 1)) / 8;
484 for (j = ximage->height; j; j--) {
487 for (i = line_bytes; i; i--) {
489 b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55);
490 b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33);
491 b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f);
497 line += ximage->bytes_per_line;
502 _swap_ximage_to_native (XImage *ximage)
505 int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst;
507 if (ximage->bits_per_pixel == 1 &&
508 ximage->bitmap_bit_order != native_byte_order)
510 _swap_ximage_bits (ximage);
511 if (ximage->bitmap_bit_order == ximage->byte_order)
515 if (ximage->byte_order == native_byte_order)
518 switch (ximage->bits_per_pixel) {
520 unit_bytes = ximage->bitmap_unit / 8;
523 _swap_ximage_nibbles (ximage);
532 unit_bytes = (ximage->bits_per_pixel + 7) / 8;
535 /* This could be hit on some rare but possible cases. */
539 switch (unit_bytes) {
543 _swap_ximage_2bytes (ximage);
546 _swap_ximage_3bytes (ximage);
549 _swap_ximage_4bytes (ximage);
557 /* Given a mask, (with a single sequence of contiguous 1 bits), return
558 * the number of 1 bits in 'width' and the number of 0 bits to its
559 * right in 'shift'. */
561 _characterize_field (uint32_t mask, int *width, int *shift)
563 *width = _cairo_popcount (mask);
564 /* The final '& 31' is to force a 0 mask to result in 0 shift. */
565 *shift = _cairo_popcount ((mask - 1) & ~mask) & 31;
568 /* Convert a field of 'width' bits to 'new_width' bits with correct
570 static inline uint32_t
571 _resize_field (uint32_t field, int width, int new_width)
576 if (width >= new_width) {
577 return field >> (width - new_width);
579 uint32_t result = field << (new_width - width);
581 while (width < new_width) {
582 result |= result >> width;
589 static inline uint32_t
590 _adjust_field (uint32_t field, int adjustment)
592 return MIN (255, MAX(0, (int)field + adjustment));
595 /* Given a shifted field value, (described by 'width' and 'shift),
596 * resize it 8-bits and return that value.
598 * Note that the original field value must not have any non-field bits
601 static inline uint32_t
602 _field_to_8 (uint32_t field, int width, int shift)
604 return _resize_field (field >> shift, width, 8);
607 static inline uint32_t
608 _field_to_8_undither (uint32_t field, int width, int shift,
609 int dither_adjustment)
611 return _adjust_field (_field_to_8 (field, width, shift), - dither_adjustment>>width);
614 /* Given an 8-bit value, convert it to a field of 'width', shift it up
615 * to 'shift, and return it. */
616 static inline uint32_t
617 _field_from_8 (uint32_t field, int width, int shift)
619 return _resize_field (field, 8, width) << shift;
622 static inline uint32_t
623 _field_from_8_dither (uint32_t field, int width, int shift,
624 int8_t dither_adjustment)
626 return _field_from_8 (_adjust_field (field, dither_adjustment>>width), width, shift);
629 static inline uint32_t
630 _pseudocolor_from_rgb888_dither (cairo_xlib_visual_info_t *visual_info,
631 uint32_t r, uint32_t g, uint32_t b,
632 int8_t dither_adjustment)
634 if (r == g && g == b) {
635 dither_adjustment /= RAMP_SIZE;
636 return visual_info->gray8_to_pseudocolor[_adjust_field (r, dither_adjustment)];
638 dither_adjustment = visual_info->dither8_to_cube[dither_adjustment+128];
639 return visual_info->cube_to_pseudocolor[visual_info->field8_to_cube[_adjust_field (r, dither_adjustment)]]
640 [visual_info->field8_to_cube[_adjust_field (g, dither_adjustment)]]
641 [visual_info->field8_to_cube[_adjust_field (b, dither_adjustment)]];
645 static inline uint32_t
646 _pseudocolor_to_rgb888 (cairo_xlib_visual_info_t *visual_info,
651 r = visual_info->colors[pixel].r;
652 g = visual_info->colors[pixel].g;
653 b = visual_info->colors[pixel].b;
659 /* should range from -128 to 127 */
661 static const int8_t dither_pattern[4][4] = {
662 {-8*X, +0*X, -6*X, +2*X},
663 {+4*X, -4*X, +6*X, -2*X},
664 {-5*X, +4*X, -7*X, +1*X},
665 {+7*X, -1*X, +5*X, -3*X}
669 static int bits_per_pixel(cairo_xlib_surface_t *surface)
671 if (surface->depth > 16)
673 else if (surface->depth > 8)
675 else if (surface->depth > 1)
681 static cairo_surface_t *
682 _get_image_surface (cairo_xlib_surface_t *surface,
683 const cairo_rectangle_int_t *extents)
685 cairo_int_status_t status;
686 cairo_image_surface_t *image = NULL;
688 pixman_format_code_t pixman_format;
689 cairo_format_masks_t xlib_masks;
690 cairo_xlib_display_t *display;
692 assert (extents->x >= 0);
693 assert (extents->y >= 0);
694 assert (extents->x + extents->width <= surface->width);
695 assert (extents->y + extents->height <= surface->height);
697 if (surface->base.is_clear ||
698 (surface->base.serial == 0 && surface->owns_pixmap))
700 xlib_masks.bpp = bits_per_pixel (surface);
701 xlib_masks.alpha_mask = surface->a_mask;
702 xlib_masks.red_mask = surface->r_mask;
703 xlib_masks.green_mask = surface->g_mask;
704 xlib_masks.blue_mask = surface->b_mask;
705 if (_pixman_format_from_masks (&xlib_masks, &pixman_format) &&
706 _cairo_format_from_pixman_format (pixman_format) != CAIRO_FORMAT_INVALID)
708 return _cairo_image_surface_create_with_pixman_format (NULL,
716 status = _cairo_xlib_display_acquire (surface->base.device, &display);
718 return _cairo_surface_create_in_error (status);
720 /* XXX: This should try to use the XShm extension if available */
722 if (surface->use_pixmap == 0) {
723 cairo_xlib_error_func_t old_handler;
725 old_handler = XSetErrorHandler (_noop_error_handler);
727 ximage = XGetImage (display->display,
729 extents->x, extents->y,
730 extents->width, extents->height,
733 XSetErrorHandler (old_handler);
735 /* If we get an error, the surface must have been a window,
736 * so retry with the safe code path.
739 surface->use_pixmap = CAIRO_ASSUME_PIXMAP;
741 surface->use_pixmap--;
745 if (ximage == NULL) {
746 /* XGetImage from a window is dangerous because it can
747 * produce errors if the window is unmapped or partially
748 * outside the screen. We could check for errors and
749 * retry, but to keep things simple, we just create a
755 status = _cairo_xlib_surface_get_gc (display, surface, &gc);
756 if (unlikely (status))
759 pixmap = XCreatePixmap (display->display,
761 extents->width, extents->height,
766 gcv.subwindow_mode = IncludeInferiors;
767 XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
769 XCopyArea (display->display, surface->drawable, pixmap, gc,
770 extents->x, extents->y,
771 extents->width, extents->height,
774 gcv.subwindow_mode = ClipByChildren;
775 XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
777 ximage = XGetImage (display->display,
780 extents->width, extents->height,
783 XFreePixmap (display->display, pixmap);
786 _cairo_xlib_surface_put_gc (display, surface, gc);
788 if (ximage == NULL) {
789 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
794 _swap_ximage_to_native (ximage);
796 xlib_masks.bpp = ximage->bits_per_pixel;
797 xlib_masks.alpha_mask = surface->a_mask;
798 xlib_masks.red_mask = surface->r_mask;
799 xlib_masks.green_mask = surface->g_mask;
800 xlib_masks.blue_mask = surface->b_mask;
802 /* We can't use pixman to simply write to image if:
803 * (a) the pixels are not appropriately aligned,
804 * (b) pixman does not the pixel format, or
805 * (c) if the image is palettized and we need to convert.
807 if (ximage->bitmap_unit == 32 && ximage->bitmap_pad == 32 &&
808 _pixman_format_from_masks (&xlib_masks, &pixman_format) &&
809 (surface->visual == NULL || surface->visual->class == TrueColor))
811 image = (cairo_image_surface_t*)
812 _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
816 ximage->bytes_per_line);
817 status = image->base.status;
818 if (unlikely (status))
821 /* Let the surface take ownership of the data */
822 _cairo_image_surface_assume_ownership_of_data (image);
825 /* The visual we are dealing with is not supported by the
826 * standard pixman formats. So we must first convert the data
827 * to a supported format. */
829 cairo_format_t format;
832 uint32_t in_pixel, out_pixel;
833 unsigned int rowstride;
834 uint32_t a_mask=0, r_mask=0, g_mask=0, b_mask=0;
835 int a_width=0, r_width=0, g_width=0, b_width=0;
836 int a_shift=0, r_shift=0, g_shift=0, b_shift=0;
837 int x, y, x0, y0, x_off, y_off;
838 cairo_xlib_visual_info_t *visual_info = NULL;
840 if (surface->visual == NULL || surface->visual->class == TrueColor) {
841 cairo_bool_t has_alpha;
842 cairo_bool_t has_color;
844 has_alpha = surface->a_mask;
845 has_color = (surface->r_mask ||
851 format = CAIRO_FORMAT_ARGB32;
853 format = CAIRO_FORMAT_RGB24;
856 /* XXX: Using CAIRO_FORMAT_A8 here would be more
857 * efficient, but would require slightly different code in
858 * the image conversion to put the alpha channel values
859 * into the right place. */
860 format = CAIRO_FORMAT_ARGB32;
863 a_mask = surface->a_mask;
864 r_mask = surface->r_mask;
865 g_mask = surface->g_mask;
866 b_mask = surface->b_mask;
868 _characterize_field (a_mask, &a_width, &a_shift);
869 _characterize_field (r_mask, &r_width, &r_shift);
870 _characterize_field (g_mask, &g_width, &g_shift);
871 _characterize_field (b_mask, &b_width, &b_shift);
874 format = CAIRO_FORMAT_RGB24;
876 status = _cairo_xlib_screen_get_visual_info (display,
880 if (unlikely (status))
884 image = (cairo_image_surface_t *) cairo_image_surface_create
885 (format, ximage->width, ximage->height);
886 status = image->base.status;
887 if (unlikely (status))
890 data = cairo_image_surface_get_data (&image->base);
891 rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
892 row = (uint32_t *) data;
893 x0 = extents->x + surface->base.device_transform.x0;
894 y0 = extents->y + surface->base.device_transform.y0;
895 for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
897 y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern)) {
898 const int8_t *dither_row = dither_pattern[y_off];
899 for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]);
901 x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0])) {
902 int dither_adjustment = dither_row[x_off];
904 in_pixel = XGetPixel (ximage, x, y);
905 if (visual_info == NULL) {
907 _field_to_8 (in_pixel & a_mask, a_width, a_shift) << 24 |
908 _field_to_8_undither (in_pixel & r_mask, r_width, r_shift, dither_adjustment) << 16 |
909 _field_to_8_undither (in_pixel & g_mask, g_width, g_shift, dither_adjustment) << 8 |
910 _field_to_8_undither (in_pixel & b_mask, b_width, b_shift, dither_adjustment));
912 /* Undithering pseudocolor does not look better */
913 out_pixel = _pseudocolor_to_rgb888 (visual_info, in_pixel);
919 cairo_surface_mark_dirty (&image->base);
924 XDestroyImage (ximage);
926 cairo_device_release (&display->base);
928 if (unlikely (status)) {
929 cairo_surface_destroy (&image->base);
930 return _cairo_surface_create_in_error (status);
937 _cairo_xlib_surface_set_precision (cairo_xlib_surface_t *surface,
938 cairo_antialias_t antialias)
940 cairo_xlib_display_t *display = surface->display;
943 if (display->force_precision != -1)
944 precision = display->force_precision;
945 else switch (antialias) {
947 case CAIRO_ANTIALIAS_DEFAULT:
948 case CAIRO_ANTIALIAS_GRAY:
949 case CAIRO_ANTIALIAS_NONE:
950 case CAIRO_ANTIALIAS_FAST:
951 case CAIRO_ANTIALIAS_GOOD:
952 precision = PolyModeImprecise;
954 case CAIRO_ANTIALIAS_BEST:
955 case CAIRO_ANTIALIAS_SUBPIXEL:
956 precision = PolyModePrecise;
960 if (surface->precision != precision) {
961 XRenderPictureAttributes pa;
963 pa.poly_mode = precision;
964 XRenderChangePicture (display->display, surface->picture,
967 surface->precision = precision;
972 _cairo_xlib_surface_ensure_picture (cairo_xlib_surface_t *surface)
974 cairo_xlib_display_t *display = surface->display;
975 XRenderPictureAttributes pa;
978 if (surface->picture)
981 if (display->force_precision != -1)
982 pa.poly_mode = display->force_precision;
984 pa.poly_mode = PolyModeImprecise;
988 surface->precision = pa.poly_mode;
989 surface->picture = XRenderCreatePicture (display->display,
991 surface->xrender_format,
996 _cairo_xlib_surface_draw_image (cairo_xlib_surface_t *surface,
997 cairo_image_surface_t *image,
1005 cairo_xlib_display_t *display;
1007 cairo_format_masks_t image_masks;
1008 int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst;
1009 pixman_image_t *pixman_image = NULL;
1010 cairo_status_t status;
1011 cairo_bool_t own_data;
1012 cairo_bool_t is_rgb_image;
1015 ximage.width = image->width;
1016 ximage.height = image->height;
1017 ximage.format = ZPixmap;
1018 ximage.byte_order = native_byte_order;
1019 ximage.bitmap_unit = 32; /* always for libpixman */
1020 ximage.bitmap_bit_order = native_byte_order;
1021 ximage.bitmap_pad = 32; /* always for libpixman */
1022 ximage.depth = surface->depth;
1023 ximage.red_mask = surface->r_mask;
1024 ximage.green_mask = surface->g_mask;
1025 ximage.blue_mask = surface->b_mask;
1028 status = _cairo_xlib_display_acquire (surface->base.device, &display);
1029 if (unlikely (status))
1032 is_rgb_image = _pixman_format_to_masks (image->pixman_format, &image_masks);
1035 (image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) &&
1036 (image_masks.red_mask == surface->r_mask || surface->r_mask == 0) &&
1037 (image_masks.green_mask == surface->g_mask || surface->g_mask == 0) &&
1038 (image_masks.blue_mask == surface->b_mask || surface->b_mask == 0))
1042 ximage.bits_per_pixel = image_masks.bpp;
1043 ximage.bytes_per_line = image->stride;
1044 ximage.data = (char *)image->data;
1047 ret = XInitImage (&ximage);
1050 else if (surface->visual == NULL || surface->visual->class == TrueColor)
1052 pixman_format_code_t intermediate_format;
1055 image_masks.alpha_mask = surface->a_mask;
1056 image_masks.red_mask = surface->r_mask;
1057 image_masks.green_mask = surface->g_mask;
1058 image_masks.blue_mask = surface->b_mask;
1059 image_masks.bpp = bits_per_pixel (surface);
1060 ret = _pixman_format_from_masks (&image_masks, &intermediate_format);
1065 pixman_image = pixman_image_create_bits (intermediate_format,
1066 width, height, NULL, 0);
1067 if (pixman_image == NULL) {
1068 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1072 pixman_image_composite32 (PIXMAN_OP_SRC,
1073 image->pixman_image,
1081 ximage.width = width;
1082 ximage.height = height;
1083 ximage.bits_per_pixel = image_masks.bpp;
1084 ximage.data = (char *) pixman_image_get_data (pixman_image);
1085 ximage.bytes_per_line = pixman_image_get_stride (pixman_image);
1087 ret = XInitImage (&ximage);
1094 unsigned int stride, rowstride;
1095 int x, y, x0, y0, x_off, y_off;
1096 uint32_t in_pixel, out_pixel, *row;
1097 int i_a_width=0, i_r_width=0, i_g_width=0, i_b_width=0;
1098 int i_a_shift=0, i_r_shift=0, i_g_shift=0, i_b_shift=0;
1099 int o_a_width=0, o_r_width=0, o_g_width=0, o_b_width=0;
1100 int o_a_shift=0, o_r_shift=0, o_g_shift=0, o_b_shift=0;
1101 cairo_xlib_visual_info_t *visual_info = NULL;
1102 cairo_bool_t true_color;
1105 ximage.bits_per_pixel = bits_per_pixel(surface);
1106 stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
1107 ximage.bits_per_pixel);
1108 ximage.bytes_per_line = stride;
1109 ximage.data = _cairo_malloc_ab (stride, ximage.height);
1110 if (unlikely (ximage.data == NULL)) {
1112 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1118 ret = XInitImage (&ximage);
1121 _characterize_field (image_masks.alpha_mask, &i_a_width, &i_a_shift);
1122 _characterize_field (image_masks.red_mask , &i_r_width, &i_r_shift);
1123 _characterize_field (image_masks.green_mask, &i_g_width, &i_g_shift);
1124 _characterize_field (image_masks.blue_mask , &i_b_width, &i_b_shift);
1126 true_color = surface->visual == NULL ||
1127 surface->visual->class == TrueColor;
1129 _characterize_field (surface->a_mask, &o_a_width, &o_a_shift);
1130 _characterize_field (surface->r_mask, &o_r_width, &o_r_shift);
1131 _characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
1132 _characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
1134 status = _cairo_xlib_screen_get_visual_info (display,
1138 if (unlikely (status))
1142 rowstride = image->stride >> 2;
1143 row = (uint32_t *) image->data;
1144 x0 = dst_x + surface->base.device_transform.x0;
1145 y0 = dst_y + surface->base.device_transform.y0;
1146 for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
1148 y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern))
1150 const int8_t *dither_row = dither_pattern[y_off];
1152 for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]);
1154 x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0]))
1156 int dither_adjustment = dither_row[x_off];
1159 if (image_masks.bpp == 1)
1160 in_pixel = !! (((uint8_t*)row)[x/8] & (1 << (x & 7)));
1161 else if (image_masks.bpp <= 8)
1162 in_pixel = ((uint8_t*)row)[x];
1163 else if (image_masks.bpp <= 16)
1164 in_pixel = ((uint16_t*)row)[x];
1165 else if (image_masks.bpp <= 24)
1166 #ifdef WORDS_BIGENDIAN
1167 in_pixel = ((uint8_t*)row)[3 * x] << 16 |
1168 ((uint8_t*)row)[3 * x + 1] << 8 |
1169 ((uint8_t*)row)[3 * x + 2];
1171 in_pixel = ((uint8_t*)row)[3 * x] |
1172 ((uint8_t*)row)[3 * x + 1] << 8 |
1173 ((uint8_t*)row)[3 * x + 2] << 16;
1178 /* If the incoming image has no alpha channel, then the input
1179 * is opaque and the output should have the maximum alpha value.
1180 * For all other channels, their absence implies 0.
1182 if (image_masks.alpha_mask == 0x0)
1185 a = _field_to_8 (in_pixel & image_masks.alpha_mask, i_a_width, i_a_shift);
1186 r = _field_to_8 (in_pixel & image_masks.red_mask , i_r_width, i_r_shift);
1187 g = _field_to_8 (in_pixel & image_masks.green_mask, i_g_width, i_g_shift);
1188 b = _field_to_8 (in_pixel & image_masks.blue_mask , i_b_width, i_b_shift);
1191 out_pixel = _field_from_8 (a, o_a_width, o_a_shift) |
1192 _field_from_8_dither (r, o_r_width, o_r_shift, dither_adjustment) |
1193 _field_from_8_dither (g, o_g_width, o_g_shift, dither_adjustment) |
1194 _field_from_8_dither (b, o_b_width, o_b_shift, dither_adjustment);
1196 out_pixel = _pseudocolor_from_rgb888_dither (visual_info, r, g, b, dither_adjustment);
1199 XPutPixel (&ximage, x, y, out_pixel);
1206 status = _cairo_xlib_surface_get_gc (display, surface, &gc);
1207 if (unlikely (status))
1210 XPutImage (display->display, surface->drawable, gc, &ximage,
1211 src_x, src_y, dst_x, dst_y, width, height);
1213 _cairo_xlib_surface_put_gc (display, surface, gc);
1217 cairo_device_release (&display->base);
1222 pixman_image_unref (pixman_image);
1224 return CAIRO_STATUS_SUCCESS;
1227 static cairo_surface_t *
1228 _cairo_xlib_surface_source(void *abstract_surface,
1229 cairo_rectangle_int_t *extents)
1231 cairo_xlib_surface_t *surface = abstract_surface;
1234 extents->x = extents->y = 0;
1235 extents->width = surface->width;
1236 extents->height = surface->height;
1239 return &surface->base;
1242 static cairo_status_t
1243 _cairo_xlib_surface_acquire_source_image (void *abstract_surface,
1244 cairo_image_surface_t **image_out,
1247 cairo_xlib_surface_t *surface = abstract_surface;
1248 cairo_rectangle_int_t extents;
1250 extents.x = extents.y = 0;
1251 extents.width = surface->width;
1252 extents.height = surface->height;
1254 *image_extra = NULL;
1255 *image_out = (cairo_image_surface_t*)_get_image_surface (surface, &extents);
1256 return (*image_out)->base.status;
1259 static cairo_surface_t *
1260 _cairo_xlib_surface_snapshot (void *abstract_surface)
1262 cairo_xlib_surface_t *surface = abstract_surface;
1263 cairo_rectangle_int_t extents;
1265 extents.x = extents.y = 0;
1266 extents.width = surface->width;
1267 extents.height = surface->height;
1269 /* XXX notice the duplication with acquire source */
1270 return _get_image_surface (surface, &extents);
1274 _cairo_xlib_surface_release_source_image (void *abstract_surface,
1275 cairo_image_surface_t *image,
1278 cairo_surface_destroy (&image->base);
1281 static cairo_surface_t *
1282 _cairo_xlib_surface_map_to_image (void *abstract_surface,
1283 const cairo_rectangle_int_t *extents)
1285 cairo_surface_t *image;
1287 image = _get_image_surface (abstract_surface, extents);
1288 cairo_surface_set_device_offset (image, -extents->x, -extents->y);
1293 static cairo_int_status_t
1294 _cairo_xlib_surface_unmap_image (void *abstract_surface,
1295 cairo_image_surface_t *image)
1297 return _cairo_xlib_surface_draw_image (abstract_surface, image,
1299 image->width, image->height,
1300 image->base.device_transform_inverse.x0,
1301 image->base.device_transform_inverse.y0);
1305 _cairo_xlib_surface_get_extents (void *abstract_surface,
1306 cairo_rectangle_int_t *rectangle)
1308 cairo_xlib_surface_t *surface = abstract_surface;
1313 rectangle->width = surface->width;
1314 rectangle->height = surface->height;
1320 _cairo_xlib_surface_get_font_options (void *abstract_surface,
1321 cairo_font_options_t *options)
1323 cairo_xlib_surface_t *surface = abstract_surface;
1325 *options = *_cairo_xlib_screen_get_font_options (surface->screen);
1329 static cairo_int_status_t
1330 _cairo_xlib_surface_paint (void *_surface,
1331 cairo_operator_t op,
1332 const cairo_pattern_t *source,
1333 const cairo_clip_t *clip)
1335 cairo_xlib_surface_t *surface = _surface;
1336 return _cairo_compositor_paint (surface->compositor,
1337 &surface->base, op, source,
1341 static cairo_int_status_t
1342 _cairo_xlib_surface_mask (void *_surface,
1343 cairo_operator_t op,
1344 const cairo_pattern_t *source,
1345 const cairo_pattern_t *mask,
1346 const cairo_clip_t *clip)
1348 cairo_xlib_surface_t *surface = _surface;
1349 return _cairo_compositor_mask (surface->compositor,
1350 &surface->base, op, source, mask,
1354 static cairo_int_status_t
1355 _cairo_xlib_surface_stroke (void *_surface,
1356 cairo_operator_t op,
1357 const cairo_pattern_t *source,
1358 const cairo_path_fixed_t *path,
1359 const cairo_stroke_style_t *style,
1360 const cairo_matrix_t *ctm,
1361 const cairo_matrix_t *ctm_inverse,
1363 cairo_antialias_t antialias,
1364 const cairo_clip_t *clip)
1366 cairo_xlib_surface_t *surface = _surface;
1367 return _cairo_compositor_stroke (surface->compositor,
1368 &surface->base, op, source,
1369 path, style, ctm, ctm_inverse,
1370 tolerance, antialias,
1374 static cairo_int_status_t
1375 _cairo_xlib_surface_fill (void *_surface,
1376 cairo_operator_t op,
1377 const cairo_pattern_t *source,
1378 const cairo_path_fixed_t *path,
1379 cairo_fill_rule_t fill_rule,
1381 cairo_antialias_t antialias,
1382 const cairo_clip_t *clip)
1384 cairo_xlib_surface_t *surface = _surface;
1385 return _cairo_compositor_fill (surface->compositor,
1386 &surface->base, op, source,
1387 path, fill_rule, tolerance, antialias,
1391 static cairo_int_status_t
1392 _cairo_xlib_surface_glyphs (void *_surface,
1393 cairo_operator_t op,
1394 const cairo_pattern_t *source,
1395 cairo_glyph_t *glyphs,
1397 cairo_scaled_font_t *scaled_font,
1398 const cairo_clip_t *clip)
1400 cairo_xlib_surface_t *surface = _surface;
1401 return _cairo_compositor_glyphs (surface->compositor,
1402 &surface->base, op, source,
1403 glyphs, num_glyphs, scaled_font,
1407 static const cairo_surface_backend_t cairo_xlib_surface_backend = {
1408 CAIRO_SURFACE_TYPE_XLIB,
1409 _cairo_xlib_surface_finish,
1411 _cairo_default_context_create,
1413 _cairo_xlib_surface_create_similar,
1414 NULL, //_cairo_xlib_surface_create_similar_image, /* XXX shm */
1415 _cairo_xlib_surface_map_to_image,
1416 _cairo_xlib_surface_unmap_image,
1418 _cairo_xlib_surface_source,
1419 _cairo_xlib_surface_acquire_source_image,
1420 _cairo_xlib_surface_release_source_image,
1421 _cairo_xlib_surface_snapshot,
1423 NULL, /* copy_page */
1424 NULL, /* show_page */
1426 _cairo_xlib_surface_get_extents,
1427 _cairo_xlib_surface_get_font_options,
1430 NULL, /* mark_dirty_rectangle */
1432 _cairo_xlib_surface_paint,
1433 _cairo_xlib_surface_mask,
1434 _cairo_xlib_surface_stroke,
1435 _cairo_xlib_surface_fill,
1436 NULL, /* fill-stroke */
1437 _cairo_xlib_surface_glyphs,
1441 * _cairo_surface_is_xlib:
1442 * @surface: a #cairo_surface_t
1444 * Checks if a surface is a #cairo_xlib_surface_t
1446 * Return value: True if the surface is an xlib surface
1449 _cairo_surface_is_xlib (cairo_surface_t *surface)
1451 return surface->backend == &cairo_xlib_surface_backend;
1454 static cairo_surface_t *
1455 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
1458 XRenderPictFormat *xrender_format,
1463 cairo_xlib_surface_t *surface;
1464 cairo_xlib_display_t *display;
1465 cairo_status_t status;
1468 if (xrender_format) {
1469 depth = xrender_format->depth;
1471 /* XXX find matching visual for core/dithering fallbacks? */
1472 } else if (visual) {
1473 Screen *scr = screen->screen;
1475 if (visual == DefaultVisualOfScreen (scr)) {
1476 depth = DefaultDepthOfScreen (scr);
1480 /* This is ugly, but we have to walk over all visuals
1481 * for the display to find the correct depth.
1484 for (j = 0; j < scr->ndepths; j++) {
1485 Depth *d = &scr->depths[j];
1486 for (k = 0; k < d->nvisuals; k++) {
1487 if (&d->visuals[k] == visual) {
1497 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1503 surface = malloc (sizeof (cairo_xlib_surface_t));
1504 if (unlikely (surface == NULL))
1505 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1507 status = _cairo_xlib_display_acquire (screen->device, &display);
1508 if (unlikely (status)) {
1510 return _cairo_surface_create_in_error (_cairo_error (status));
1513 surface->display = display;
1514 if (CAIRO_RENDER_HAS_CREATE_PICTURE (display)) {
1515 if (!xrender_format) {
1517 xrender_format = XRenderFindVisualFormat (display->display, visual);
1518 } else if (depth == 1) {
1520 _cairo_xlib_display_get_xrender_format (display,
1526 cairo_device_release (&display->base);
1528 _cairo_surface_init (&surface->base,
1529 &cairo_xlib_surface_backend,
1531 _xrender_format_to_content (xrender_format));
1533 surface->screen = screen;
1534 surface->compositor = display->compositor;
1536 surface->drawable = drawable;
1537 surface->owns_pixmap = FALSE;
1538 surface->use_pixmap = 0;
1539 surface->width = width;
1540 surface->height = height;
1542 surface->picture = None;
1543 surface->precision = PolyModePrecise;
1545 surface->embedded_source.picture = None;
1547 surface->visual = visual;
1548 surface->xrender_format = xrender_format;
1549 surface->depth = depth;
1552 * Compute the pixel format masks from either a XrenderFormat or
1553 * else from a visual; failing that we assume the drawable is an
1554 * alpha-only pixmap as it could only have been created that way
1555 * through the cairo_xlib_surface_create_for_bitmap function.
1557 if (xrender_format) {
1558 surface->a_mask = (unsigned long)
1559 surface->xrender_format->direct.alphaMask
1560 << surface->xrender_format->direct.alpha;
1561 surface->r_mask = (unsigned long)
1562 surface->xrender_format->direct.redMask
1563 << surface->xrender_format->direct.red;
1564 surface->g_mask = (unsigned long)
1565 surface->xrender_format->direct.greenMask
1566 << surface->xrender_format->direct.green;
1567 surface->b_mask = (unsigned long)
1568 surface->xrender_format->direct.blueMask
1569 << surface->xrender_format->direct.blue;
1570 } else if (visual) {
1571 surface->a_mask = 0;
1572 surface->r_mask = visual->red_mask;
1573 surface->g_mask = visual->green_mask;
1574 surface->b_mask = visual->blue_mask;
1577 surface->a_mask = (1 << depth) - 1;
1579 surface->a_mask = 0xffffffff;
1580 surface->r_mask = 0;
1581 surface->g_mask = 0;
1582 surface->b_mask = 0;
1585 cairo_list_add (&surface->link, &screen->surfaces);
1587 return &surface->base;
1591 _cairo_xlib_screen_from_visual (Display *dpy, Visual *visual)
1595 for (s = 0; s < ScreenCount (dpy); s++) {
1598 screen = ScreenOfDisplay (dpy, s);
1599 if (visual == DefaultVisualOfScreen (screen))
1602 for (d = 0; d < screen->ndepths; d++) {
1605 depth = &screen->depths[d];
1606 for (v = 0; v < depth->nvisuals; v++)
1607 if (visual == &depth->visuals[v])
1615 static cairo_bool_t valid_size (int width, int height)
1617 /* Note: the minimum surface size allowed in the X protocol is 1x1.
1618 * However, as we historically did not check the minimum size we
1619 * allowed applications to lie and set the correct size later (one hopes).
1620 * To preserve compatability we must allow applications to use
1623 return (width >= 0 && width <= XLIB_COORD_MAX &&
1624 height >= 0 && height <= XLIB_COORD_MAX);
1628 * cairo_xlib_surface_create:
1629 * @dpy: an X Display
1630 * @drawable: an X Drawable, (a Pixmap or a Window)
1631 * @visual: the visual to use for drawing to @drawable. The depth
1632 * of the visual must match the depth of the drawable.
1633 * Currently, only TrueColor visuals are fully supported.
1634 * @width: the current width of @drawable.
1635 * @height: the current height of @drawable.
1637 * Creates an Xlib surface that draws to the given drawable.
1638 * The way that colors are represented in the drawable is specified
1639 * by the provided visual.
1641 * Note: If @drawable is a Window, then the function
1642 * cairo_xlib_surface_set_size() must be called whenever the size of the
1645 * When @drawable is a Window containing child windows then drawing to
1646 * the created surface will be clipped by those child windows. When
1647 * the created surface is used as a source, the contents of the
1648 * children will be included.
1650 * Return value: the newly created surface
1655 cairo_xlib_surface_create (Display *dpy,
1662 cairo_xlib_screen_t *screen;
1663 cairo_status_t status;
1665 if (! valid_size (width, height)) {
1666 /* you're lying, and you know it! */
1667 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1670 scr = _cairo_xlib_screen_from_visual (dpy, visual);
1672 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1674 status = _cairo_xlib_screen_get (dpy, scr, &screen);
1675 if (unlikely (status))
1676 return _cairo_surface_create_in_error (status);
1678 X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable));
1680 return _cairo_xlib_surface_create_internal (screen, drawable,
1686 * cairo_xlib_surface_create_for_bitmap:
1687 * @dpy: an X Display
1688 * @bitmap: an X Drawable, (a depth-1 Pixmap)
1689 * @screen: the X Screen associated with @bitmap
1690 * @width: the current width of @bitmap.
1691 * @height: the current height of @bitmap.
1693 * Creates an Xlib surface that draws to the given bitmap.
1694 * This will be drawn to as a %CAIRO_FORMAT_A1 object.
1696 * Return value: the newly created surface
1701 cairo_xlib_surface_create_for_bitmap (Display *dpy,
1707 cairo_xlib_screen_t *screen;
1708 cairo_status_t status;
1710 if (! valid_size (width, height))
1711 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1713 status = _cairo_xlib_screen_get (dpy, scr, &screen);
1714 if (unlikely (status))
1715 return _cairo_surface_create_in_error (status);
1717 X_DEBUG ((dpy, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap));
1719 return _cairo_xlib_surface_create_internal (screen, bitmap,
1724 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
1726 * cairo_xlib_surface_create_with_xrender_format:
1727 * @dpy: an X Display
1728 * @drawable: an X Drawable, (a Pixmap or a Window)
1729 * @screen: the X Screen associated with @drawable
1730 * @format: the picture format to use for drawing to @drawable. The depth
1731 * of @format must match the depth of the drawable.
1732 * @width: the current width of @drawable.
1733 * @height: the current height of @drawable.
1735 * Creates an Xlib surface that draws to the given drawable.
1736 * The way that colors are represented in the drawable is specified
1737 * by the provided picture format.
1739 * Note: If @drawable is a Window, then the function
1740 * cairo_xlib_surface_set_size() must be called whenever the size of the
1743 * Return value: the newly created surface
1748 cairo_xlib_surface_create_with_xrender_format (Display *dpy,
1751 XRenderPictFormat *format,
1755 cairo_xlib_screen_t *screen;
1756 cairo_status_t status;
1758 if (! valid_size (width, height))
1759 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1761 status = _cairo_xlib_screen_get (dpy, scr, &screen);
1762 if (unlikely (status))
1763 return _cairo_surface_create_in_error (status);
1765 X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable));
1767 return _cairo_xlib_surface_create_internal (screen, drawable,
1768 _visual_for_xrender_format (scr, format),
1769 format, width, height, 0);
1773 * cairo_xlib_surface_get_xrender_format:
1774 * @surface: an xlib surface
1776 * Gets the X Render picture format that @surface uses for rendering with the
1777 * X Render extension. If the surface was created by
1778 * cairo_xlib_surface_create_with_xrender_format() originally, the return
1779 * value is the format passed to that constructor.
1781 * Return value: the XRenderPictFormat* associated with @surface,
1782 * or %NULL if the surface is not an xlib surface
1783 * or if the X Render extension is not available.
1788 cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface)
1790 cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
1792 /* Throw an error for a non-xlib surface */
1793 if (! _cairo_surface_is_xlib (surface)) {
1794 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
1798 return xlib_surface->xrender_format;
1803 * cairo_xlib_surface_set_size:
1804 * @surface: a #cairo_surface_t for the XLib backend
1805 * @width: the new width of the surface
1806 * @height: the new height of the surface
1808 * Informs cairo of the new size of the X Drawable underlying the
1809 * surface. For a surface created for a Window (rather than a Pixmap),
1810 * this function must be called each time the size of the window
1811 * changes. (For a subwindow, you are normally resizing the window
1812 * yourself, but for a toplevel window, it is necessary to listen for
1813 * ConfigureNotify events.)
1815 * A Pixmap can never change size, so it is never necessary to call
1816 * this function on a surface created for a Pixmap.
1821 cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface,
1825 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
1827 if (unlikely (abstract_surface->status))
1829 if (unlikely (abstract_surface->finished)) {
1830 _cairo_surface_set_error (abstract_surface,
1831 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1835 if (! _cairo_surface_is_xlib (abstract_surface)) {
1836 _cairo_surface_set_error (abstract_surface,
1837 _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
1841 if (! valid_size (width, height)) {
1842 _cairo_surface_set_error (abstract_surface,
1843 _cairo_error (CAIRO_STATUS_INVALID_SIZE));
1847 surface->width = width;
1848 surface->height = height;
1851 * cairo_xlib_surface_set_drawable:
1852 * @surface: a #cairo_surface_t for the XLib backend
1853 * @drawable: the new drawable for the surface
1854 * @width: the width of the new drawable
1855 * @height: the height of the new drawable
1857 * Informs cairo of a new X Drawable underlying the
1858 * surface. The drawable must match the display, screen
1859 * and format of the existing drawable or the application
1860 * will get X protocol errors and will probably terminate.
1861 * No checks are done by this function to ensure this
1867 cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
1872 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
1873 cairo_status_t status;
1875 if (unlikely (abstract_surface->status))
1877 if (unlikely (abstract_surface->finished)) {
1878 status = _cairo_surface_set_error (abstract_surface,
1879 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1883 if (! _cairo_surface_is_xlib (abstract_surface)) {
1884 status = _cairo_surface_set_error (abstract_surface,
1885 _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
1889 if (! valid_size (width, height)) {
1890 status = _cairo_surface_set_error (abstract_surface,
1891 _cairo_error (CAIRO_STATUS_INVALID_SIZE));
1895 /* XXX: and what about this case? */
1896 if (surface->owns_pixmap)
1899 if (surface->drawable != drawable) {
1900 cairo_xlib_display_t *display;
1902 status = _cairo_xlib_display_acquire (surface->base.device, &display);
1903 if (unlikely (status))
1906 X_DEBUG ((display->display, "set_drawable (drawable=%x)", (unsigned int) drawable));
1908 if (surface->picture != None) {
1909 XRenderFreePicture (display->display, surface->picture);
1910 if (unlikely (status)) {
1911 status = _cairo_surface_set_error (&surface->base, status);
1915 surface->picture = None;
1918 cairo_device_release (&display->base);
1920 surface->drawable = drawable;
1922 surface->width = width;
1923 surface->height = height;
1927 * cairo_xlib_surface_get_display:
1928 * @surface: a #cairo_xlib_surface_t
1930 * Get the X Display for the underlying X Drawable.
1932 * Return value: the display.
1937 cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
1939 if (! _cairo_surface_is_xlib (abstract_surface)) {
1940 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
1944 return ((cairo_xlib_display_t *) abstract_surface->device)->display;
1948 * cairo_xlib_surface_get_drawable:
1949 * @surface: a #cairo_xlib_surface_t
1951 * Get the underlying X Drawable used for the surface.
1953 * Return value: the drawable.
1958 cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface)
1960 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
1962 if (! _cairo_surface_is_xlib (abstract_surface)) {
1963 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
1967 return surface->drawable;
1971 * cairo_xlib_surface_get_screen:
1972 * @surface: a #cairo_xlib_surface_t
1974 * Get the X Screen for the underlying X Drawable.
1976 * Return value: the screen.
1981 cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
1983 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
1985 if (! _cairo_surface_is_xlib (abstract_surface)) {
1986 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
1990 return surface->screen->screen;
1994 * cairo_xlib_surface_get_visual:
1995 * @surface: a #cairo_xlib_surface_t
1997 * Gets the X Visual associated with @surface, suitable for use with the
1998 * underlying X Drawable. If @surface was created by
1999 * cairo_xlib_surface_create(), the return value is the Visual passed to that
2002 * Return value: the Visual or %NULL if there is no appropriate Visual for
2008 cairo_xlib_surface_get_visual (cairo_surface_t *surface)
2010 cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
2012 if (! _cairo_surface_is_xlib (surface)) {
2013 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2017 return xlib_surface->visual;
2021 * cairo_xlib_surface_get_depth:
2022 * @surface: a #cairo_xlib_surface_t
2024 * Get the number of bits used to represent each pixel value.
2026 * Return value: the depth of the surface in bits.
2031 cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
2033 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2035 if (! _cairo_surface_is_xlib (abstract_surface)) {
2036 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2040 return surface->depth;
2044 * cairo_xlib_surface_get_width:
2045 * @surface: a #cairo_xlib_surface_t
2047 * Get the width of the X Drawable underlying the surface in pixels.
2049 * Return value: the width of the surface in pixels.
2054 cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface)
2056 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2058 if (! _cairo_surface_is_xlib (abstract_surface)) {
2059 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2063 return surface->width;
2067 * cairo_xlib_surface_get_height:
2068 * @surface: a #cairo_xlib_surface_t
2070 * Get the height of the X Drawable underlying the surface in pixels.
2072 * Return value: the height of the surface in pixels.
2077 cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface)
2079 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2081 if (! _cairo_surface_is_xlib (abstract_surface)) {
2082 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2086 return surface->height;
2089 #endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */