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-damage-private.h"
58 #include "cairo-default-context-private.h"
59 #include "cairo-error-private.h"
60 #include "cairo-image-surface-private.h"
61 #include "cairo-list-inline.h"
62 #include "cairo-pattern-private.h"
63 #include "cairo-region-private.h"
64 #include "cairo-scaled-font-private.h"
65 #include "cairo-surface-snapshot-private.h"
66 #include "cairo-surface-subsurface-private.h"
68 #include <X11/Xutil.h> /* for XDestroyImage */
70 #include <X11/extensions/XShm.h>
74 #define XLIB_COORD_MAX 32767
79 #define UNSUPPORTED(reason) \
81 "cairo-xlib: hit unsupported operation %s(), line %d: %s\n", \
82 __FUNCTION__, __LINE__, reason), \
83 CAIRO_INT_STATUS_UNSUPPORTED
85 #define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
89 #include <X11/Xlibint.h>
90 static void CAIRO_PRINTF_FORMAT (2, 3)
91 _x_bread_crumb (Display *dpy,
97 unsigned int len, len_dwords;
101 len = vsnprintf (buf, sizeof (buf), fmt, ap);
109 GetEmptyReq (NoOperation, req);
111 len_dwords = len >> 2;
112 SetReqLen (req, len_dwords, len_dwords);
113 Data (dpy, buf, len);
118 #define X_DEBUG(x) _x_bread_crumb x
125 * @Title: XLib Surfaces
126 * @Short_Description: X Window System rendering using XLib
127 * @See_Also: #cairo_surface_t
129 * The XLib surface is used to render cairo graphics to X Window System
130 * windows and pixmaps using the XLib library.
132 * Note that the XLib surface automatically takes advantage of X render extension
133 * if it is available.
137 * CAIRO_HAS_XLIB_SURFACE:
139 * Defined if the Xlib surface backend is available.
140 * This macro can be used to conditionally compile backend-specific code.
146 * SECTION:cairo-xlib-xrender
147 * @Title: XLib-XRender Backend
148 * @Short_Description: X Window System rendering using XLib and the X Render extension
149 * @See_Also: #cairo_surface_t
151 * The XLib surface is used to render cairo graphics to X Window System
152 * windows and pixmaps using the XLib and Xrender libraries.
154 * Note that the XLib surface automatically takes advantage of X Render extension
155 * if it is available.
159 * CAIRO_HAS_XLIB_XRENDER_SURFACE:
161 * Defined if the XLib/XRender surface functions are available.
162 * This macro can be used to conditionally compile backend-specific code.
167 /* Xlib doesn't define a typedef, so define one ourselves */
168 typedef int (*cairo_xlib_error_func_t) (Display *display,
171 static cairo_surface_t *
172 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
175 XRenderPictFormat *xrender_format,
181 _cairo_surface_is_xlib (cairo_surface_t *surface);
184 * Instead of taking two round trips for each blending request,
185 * assume that if a particular drawable fails GetImage that it will
186 * fail for a "while"; use temporary pixmaps to avoid the errors
189 #define CAIRO_ASSUME_PIXMAP 20
191 static const XTransform identity = { {
192 { 1 << 16, 0x00000, 0x00000 },
193 { 0x00000, 1 << 16, 0x00000 },
194 { 0x00000, 0x00000, 1 << 16 },
198 _visual_for_xrender_format(Screen *screen,
199 XRenderPictFormat *xrender_format)
203 /* XXX Consider searching through the list of known cairo_visual_t for
204 * the reverse mapping.
207 for (d = 0; d < screen->ndepths; d++) {
208 Depth *d_info = &screen->depths[d];
210 if (d_info->depth != xrender_format->depth)
213 for (v = 0; v < d_info->nvisuals; v++) {
214 Visual *visual = &d_info->visuals[v];
216 switch (visual->class) {
218 if (xrender_format->type != PictTypeDirect)
223 /* Prefer TrueColor to DirectColor.
224 * (XRenderFindVisualFormat considers both TrueColor and DirectColor
225 * Visuals to match the same PictFormat.)
233 if (xrender_format->type != PictTypeIndexed)
238 if (xrender_format ==
239 XRenderFindVisualFormat (DisplayOfScreen(screen), visual))
247 static cairo_content_t
248 _xrender_format_to_content (XRenderPictFormat *xrender_format)
250 cairo_content_t content;
252 /* This only happens when using a non-Render server. Let's punt
253 * and say there's no alpha here. */
254 if (xrender_format == NULL)
255 return CAIRO_CONTENT_COLOR;
258 if (xrender_format->direct.alphaMask)
259 content |= CAIRO_CONTENT_ALPHA;
260 if (xrender_format->direct.redMask |
261 xrender_format->direct.greenMask |
262 xrender_format->direct.blueMask)
263 content |= CAIRO_CONTENT_COLOR;
268 static cairo_surface_t *
269 _cairo_xlib_surface_create_similar (void *abstract_src,
270 cairo_content_t content,
274 cairo_xlib_surface_t *src = abstract_src;
275 XRenderPictFormat *xrender_format;
276 cairo_xlib_surface_t *surface;
277 cairo_xlib_display_t *display;
280 if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
283 if (width == 0 || height == 0)
286 if (_cairo_xlib_display_acquire (src->base.device, &display))
289 /* If we never found an XRenderFormat or if it isn't compatible
290 * with the content being requested, then we fallback to just
291 * constructing a cairo_format_t instead, (which will fairly
292 * arbitrarily pick a visual/depth for the similar surface.
294 xrender_format = NULL;
295 if (src->xrender_format &&
296 _xrender_format_to_content (src->xrender_format) == content)
298 xrender_format = src->xrender_format;
300 if (xrender_format == NULL) {
302 _cairo_xlib_display_get_xrender_format (display,
303 _cairo_format_from_content (content));
305 if (xrender_format) {
308 /* We've got a compatible XRenderFormat now, which means the
309 * similar surface will match the existing surface as closely in
310 * visual/depth etc. as possible. */
311 pix = XCreatePixmap (display->display, src->drawable,
312 width, height, xrender_format->depth);
314 if (xrender_format == src->xrender_format)
315 visual = src->visual;
317 visual = _visual_for_xrender_format(src->screen->screen,
320 surface = (cairo_xlib_surface_t *)
321 _cairo_xlib_surface_create_internal (src->screen, pix, visual,
324 xrender_format->depth);
328 Screen *screen = src->screen->screen;
331 /* No compatible XRenderFormat, see if we can make an ordinary pixmap,
332 * so that we can still accelerate blits with XCopyArea(). */
333 if (content != CAIRO_CONTENT_COLOR) {
334 cairo_device_release (&display->base);
338 depth = DefaultDepthOfScreen (screen);
340 pix = XCreatePixmap (display->display, RootWindowOfScreen (screen),
341 width <= 0 ? 1 : width, height <= 0 ? 1 : height,
344 surface = (cairo_xlib_surface_t *)
345 _cairo_xlib_surface_create_internal (src->screen, pix,
346 DefaultVisualOfScreen (screen),
348 width, height, depth);
351 if (likely (surface->base.status == CAIRO_STATUS_SUCCESS))
352 surface->owns_pixmap = TRUE;
354 XFreePixmap (display->display, pix);
356 cairo_device_release (&display->base);
358 return &surface->base;
362 _cairo_xlib_surface_discard_shm (cairo_xlib_surface_t *surface)
364 if (surface->shm == NULL)
367 /* Force the flush for an external surface */
368 if (!surface->owns_pixmap)
369 cairo_surface_flush (surface->shm);
371 cairo_surface_finish (surface->shm);
372 cairo_surface_destroy (surface->shm);
375 _cairo_damage_destroy (surface->base.damage);
376 surface->base.damage = NULL;
378 surface->fallback = 0;
381 static cairo_status_t
382 _cairo_xlib_surface_finish (void *abstract_surface)
384 cairo_xlib_surface_t *surface = abstract_surface;
385 cairo_status_t status;
386 cairo_xlib_display_t *display;
388 X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable));
390 cairo_list_del (&surface->link);
392 status = _cairo_xlib_display_acquire (surface->base.device, &display);
393 if (unlikely (status))
396 if (surface->embedded_source.picture)
397 XRenderFreePicture (display->display, surface->embedded_source.picture);
398 if (surface->picture)
399 XRenderFreePicture (display->display, surface->picture);
401 _cairo_xlib_surface_discard_shm (surface);
403 if (surface->owns_pixmap)
404 XFreePixmap (display->display, surface->drawable);
406 cairo_device_release (&display->base);
412 _cairo_xlib_surface_get_gc (cairo_xlib_display_t *display,
413 cairo_xlib_surface_t *surface,
416 *gc = _cairo_xlib_screen_get_gc (display,
420 if (unlikely (*gc == NULL))
421 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
423 return CAIRO_STATUS_SUCCESS;
427 _noop_error_handler (Display *display,
430 return False; /* return value is ignored */
434 _swap_ximage_2bytes (XImage *ximage)
437 char *line = ximage->data;
439 for (j = ximage->height; j; j--) {
440 uint16_t *p = (uint16_t *) line;
441 for (i = ximage->width; i; i--) {
446 line += ximage->bytes_per_line;
451 _swap_ximage_3bytes (XImage *ximage)
454 char *line = ximage->data;
456 for (j = ximage->height; j; j--) {
457 uint8_t *p = (uint8_t *) line;
458 for (i = ximage->width; i; i--) {
466 line += ximage->bytes_per_line;
471 _swap_ximage_4bytes (XImage *ximage)
474 char *line = ximage->data;
476 for (j = ximage->height; j; j--) {
477 uint32_t *p = (uint32_t *) line;
478 for (i = ximage->width; i; i--) {
483 line += ximage->bytes_per_line;
488 _swap_ximage_nibbles (XImage *ximage)
491 char *line = ximage->data;
493 for (j = ximage->height; j; j--) {
494 uint8_t *p = (uint8_t *) line;
495 for (i = (ximage->width + 1) / 2; i; i--) {
496 *p = ((*p >> 4) & 0xf) | ((*p << 4) & ~0xf);
500 line += ximage->bytes_per_line;
505 _swap_ximage_bits (XImage *ximage)
508 char *line = ximage->data;
509 int unit = ximage->bitmap_unit;
510 int line_bytes = ((ximage->width + unit - 1) & ~(unit - 1)) / 8;
512 for (j = ximage->height; j; j--) {
515 for (i = line_bytes; i; i--) {
517 b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55);
518 b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33);
519 b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f);
525 line += ximage->bytes_per_line;
530 _swap_ximage_to_native (XImage *ximage)
533 int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst;
535 if (ximage->bits_per_pixel == 1 &&
536 ximage->bitmap_bit_order != native_byte_order)
538 _swap_ximage_bits (ximage);
539 if (ximage->bitmap_bit_order == ximage->byte_order)
543 if (ximage->byte_order == native_byte_order)
546 switch (ximage->bits_per_pixel) {
548 unit_bytes = ximage->bitmap_unit / 8;
551 _swap_ximage_nibbles (ximage);
560 unit_bytes = (ximage->bits_per_pixel + 7) / 8;
563 /* This could be hit on some rare but possible cases. */
567 switch (unit_bytes) {
571 _swap_ximage_2bytes (ximage);
574 _swap_ximage_3bytes (ximage);
577 _swap_ximage_4bytes (ximage);
585 /* Given a mask, (with a single sequence of contiguous 1 bits), return
586 * the number of 1 bits in 'width' and the number of 0 bits to its
587 * right in 'shift'. */
589 _characterize_field (uint32_t mask, int *width, int *shift)
591 *width = _cairo_popcount (mask);
592 /* The final '& 31' is to force a 0 mask to result in 0 shift. */
593 *shift = _cairo_popcount ((mask - 1) & ~mask) & 31;
596 /* Convert a field of 'width' bits to 'new_width' bits with correct
598 static inline uint32_t
599 _resize_field (uint32_t field, int width, int new_width)
604 if (width >= new_width) {
605 return field >> (width - new_width);
607 uint32_t result = field << (new_width - width);
609 while (width < new_width) {
610 result |= result >> width;
617 static inline uint32_t
618 _adjust_field (uint32_t field, int adjustment)
620 return MIN (255, MAX(0, (int)field + adjustment));
623 /* Given a shifted field value, (described by 'width' and 'shift),
624 * resize it 8-bits and return that value.
626 * Note that the original field value must not have any non-field bits
629 static inline uint32_t
630 _field_to_8 (uint32_t field, int width, int shift)
632 return _resize_field (field >> shift, width, 8);
635 static inline uint32_t
636 _field_to_8_undither (uint32_t field, int width, int shift,
637 int dither_adjustment)
639 return _adjust_field (_field_to_8 (field, width, shift), - dither_adjustment>>width);
642 /* Given an 8-bit value, convert it to a field of 'width', shift it up
643 * to 'shift, and return it. */
644 static inline uint32_t
645 _field_from_8 (uint32_t field, int width, int shift)
647 return _resize_field (field, 8, width) << shift;
650 static inline uint32_t
651 _field_from_8_dither (uint32_t field, int width, int shift,
652 int8_t dither_adjustment)
654 return _field_from_8 (_adjust_field (field, dither_adjustment>>width), width, shift);
657 static inline uint32_t
658 _pseudocolor_from_rgb888_dither (cairo_xlib_visual_info_t *visual_info,
659 uint32_t r, uint32_t g, uint32_t b,
660 int8_t dither_adjustment)
662 if (r == g && g == b) {
663 dither_adjustment /= RAMP_SIZE;
664 return visual_info->gray8_to_pseudocolor[_adjust_field (r, dither_adjustment)];
666 dither_adjustment = visual_info->dither8_to_cube[dither_adjustment+128];
667 return visual_info->cube_to_pseudocolor[visual_info->field8_to_cube[_adjust_field (r, dither_adjustment)]]
668 [visual_info->field8_to_cube[_adjust_field (g, dither_adjustment)]]
669 [visual_info->field8_to_cube[_adjust_field (b, dither_adjustment)]];
673 static inline uint32_t
674 _pseudocolor_to_rgb888 (cairo_xlib_visual_info_t *visual_info,
679 r = visual_info->colors[pixel].r;
680 g = visual_info->colors[pixel].g;
681 b = visual_info->colors[pixel].b;
687 /* should range from -128 to 127 */
689 static const int8_t dither_pattern[4][4] = {
690 {-8*X, +0*X, -6*X, +2*X},
691 {+4*X, -4*X, +6*X, -2*X},
692 {-5*X, +4*X, -7*X, +1*X},
693 {+7*X, -1*X, +5*X, -3*X}
697 static int bits_per_pixel(cairo_xlib_surface_t *surface)
699 if (surface->depth > 16)
701 else if (surface->depth > 8)
703 else if (surface->depth > 1)
710 _pixman_format_for_xlib_surface (cairo_xlib_surface_t *surface)
712 cairo_format_masks_t masks;
713 pixman_format_code_t format;
715 masks.bpp = bits_per_pixel (surface);
716 masks.alpha_mask = surface->a_mask;
717 masks.red_mask = surface->r_mask;
718 masks.green_mask = surface->g_mask;
719 masks.blue_mask = surface->b_mask;
720 if (! _pixman_format_from_masks (&masks, &format))
726 static cairo_surface_t *
727 _get_image_surface (cairo_xlib_surface_t *surface,
728 const cairo_rectangle_int_t *extents,
731 cairo_int_status_t status;
732 cairo_image_surface_t *image = NULL;
734 pixman_format_code_t pixman_format;
735 cairo_xlib_display_t *display;
737 assert (extents->x >= 0);
738 assert (extents->y >= 0);
739 assert (extents->x + extents->width <= surface->width);
740 assert (extents->y + extents->height <= surface->height);
742 if (surface->base.is_clear ||
743 (surface->base.serial == 0 && surface->owns_pixmap))
745 pixman_format = _pixman_format_for_xlib_surface (surface);
748 return _cairo_image_surface_create_with_pixman_format (NULL,
757 cairo_image_surface_t *src = (cairo_image_surface_t *) surface->shm;
758 cairo_surface_t *dst;
759 cairo_surface_pattern_t pattern;
761 dst = cairo_image_surface_create (src->format,
762 extents->width, extents->height);
763 if (unlikely (dst->status))
766 _cairo_pattern_init_for_surface (&pattern, &src->base);
767 cairo_matrix_init_translate (&pattern.base.matrix,
768 extents->x, extents->y);
769 status = _cairo_surface_paint (dst, CAIRO_OPERATOR_SOURCE, &pattern.base, NULL);
770 _cairo_pattern_fini (&pattern.base);
771 if (unlikely (status)) {
772 cairo_surface_destroy (dst);
773 dst = _cairo_surface_create_in_error (status);
779 status = _cairo_xlib_display_acquire (surface->base.device, &display);
781 return _cairo_surface_create_in_error (status);
783 pixman_format = _pixman_format_for_xlib_surface (surface);
784 if (try_shm && pixman_format) {
785 image = (cairo_image_surface_t *)
786 _cairo_xlib_surface_create_shm__image (surface, pixman_format,
787 extents->width, extents->height);
788 if (image && image->base.status == CAIRO_STATUS_SUCCESS) {
789 cairo_xlib_error_func_t old_handler;
793 _cairo_xlib_shm_surface_get_ximage (&image->base, &shm_image);
795 old_handler = XSetErrorHandler (_noop_error_handler);
796 success = XShmGetImage (display->display,
799 extents->x, extents->y,
801 XSetErrorHandler (old_handler);
804 cairo_device_release (&display->base);
808 cairo_surface_destroy (&image->base);
812 if (surface->use_pixmap == 0) {
813 cairo_xlib_error_func_t old_handler;
815 old_handler = XSetErrorHandler (_noop_error_handler);
817 ximage = XGetImage (display->display,
819 extents->x, extents->y,
820 extents->width, extents->height,
823 XSetErrorHandler (old_handler);
825 /* If we get an error, the surface must have been a window,
826 * so retry with the safe code path.
829 surface->use_pixmap = CAIRO_ASSUME_PIXMAP;
831 surface->use_pixmap--;
835 if (ximage == NULL) {
836 /* XGetImage from a window is dangerous because it can
837 * produce errors if the window is unmapped or partially
838 * outside the screen. We could check for errors and
839 * retry, but to keep things simple, we just create a
845 status = _cairo_xlib_surface_get_gc (display, surface, &gc);
846 if (unlikely (status))
849 pixmap = XCreatePixmap (display->display,
851 extents->width, extents->height,
856 gcv.subwindow_mode = IncludeInferiors;
857 XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
859 XCopyArea (display->display, surface->drawable, pixmap, gc,
860 extents->x, extents->y,
861 extents->width, extents->height,
864 gcv.subwindow_mode = ClipByChildren;
865 XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
867 ximage = XGetImage (display->display,
870 extents->width, extents->height,
873 XFreePixmap (display->display, pixmap);
876 _cairo_xlib_surface_put_gc (display, surface, gc);
878 if (ximage == NULL) {
879 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
884 _swap_ximage_to_native (ximage);
886 /* We can't use pixman to simply write to image if:
887 * (a) the pixels are not appropriately aligned,
888 * (b) pixman does not the pixel format, or
889 * (c) if the image is palettized and we need to convert.
892 ximage->bitmap_unit == 32 && ximage->bitmap_pad == 32 &&
893 (surface->visual == NULL || surface->visual->class == TrueColor))
895 image = (cairo_image_surface_t*)
896 _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
900 ximage->bytes_per_line);
901 status = image->base.status;
902 if (unlikely (status))
905 /* Let the surface take ownership of the data */
906 _cairo_image_surface_assume_ownership_of_data (image);
909 /* The visual we are dealing with is not supported by the
910 * standard pixman formats. So we must first convert the data
911 * to a supported format. */
913 cairo_format_t format;
916 uint32_t in_pixel, out_pixel;
917 unsigned int rowstride;
918 uint32_t a_mask=0, r_mask=0, g_mask=0, b_mask=0;
919 int a_width=0, r_width=0, g_width=0, b_width=0;
920 int a_shift=0, r_shift=0, g_shift=0, b_shift=0;
921 int x, y, x0, y0, x_off, y_off;
922 cairo_xlib_visual_info_t *visual_info = NULL;
924 if (surface->visual == NULL || surface->visual->class == TrueColor) {
925 cairo_bool_t has_alpha;
926 cairo_bool_t has_color;
928 has_alpha = surface->a_mask;
929 has_color = (surface->r_mask ||
935 format = CAIRO_FORMAT_ARGB32;
937 format = CAIRO_FORMAT_RGB24;
940 /* XXX: Using CAIRO_FORMAT_A8 here would be more
941 * efficient, but would require slightly different code in
942 * the image conversion to put the alpha channel values
943 * into the right place. */
944 format = CAIRO_FORMAT_ARGB32;
947 a_mask = surface->a_mask;
948 r_mask = surface->r_mask;
949 g_mask = surface->g_mask;
950 b_mask = surface->b_mask;
952 _characterize_field (a_mask, &a_width, &a_shift);
953 _characterize_field (r_mask, &r_width, &r_shift);
954 _characterize_field (g_mask, &g_width, &g_shift);
955 _characterize_field (b_mask, &b_width, &b_shift);
958 format = CAIRO_FORMAT_RGB24;
960 status = _cairo_xlib_screen_get_visual_info (display,
964 if (unlikely (status))
968 image = (cairo_image_surface_t *) cairo_image_surface_create
969 (format, ximage->width, ximage->height);
970 status = image->base.status;
971 if (unlikely (status))
974 data = cairo_image_surface_get_data (&image->base);
975 rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
976 row = (uint32_t *) data;
977 x0 = extents->x + surface->base.device_transform.x0;
978 y0 = extents->y + surface->base.device_transform.y0;
979 for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
981 y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern)) {
982 const int8_t *dither_row = dither_pattern[y_off];
983 for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]);
985 x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0])) {
986 int dither_adjustment = dither_row[x_off];
988 in_pixel = XGetPixel (ximage, x, y);
989 if (visual_info == NULL) {
991 _field_to_8 (in_pixel & a_mask, a_width, a_shift) << 24 |
992 _field_to_8_undither (in_pixel & r_mask, r_width, r_shift, dither_adjustment) << 16 |
993 _field_to_8_undither (in_pixel & g_mask, g_width, g_shift, dither_adjustment) << 8 |
994 _field_to_8_undither (in_pixel & b_mask, b_width, b_shift, dither_adjustment));
996 /* Undithering pseudocolor does not look better */
997 out_pixel = _pseudocolor_to_rgb888 (visual_info, in_pixel);
1003 cairo_surface_mark_dirty (&image->base);
1008 XDestroyImage (ximage);
1010 cairo_device_release (&display->base);
1012 if (unlikely (status)) {
1013 cairo_surface_destroy (&image->base);
1014 return _cairo_surface_create_in_error (status);
1017 return &image->base;
1021 _cairo_xlib_surface_set_precision (cairo_xlib_surface_t *surface,
1022 cairo_antialias_t antialias)
1024 cairo_xlib_display_t *display = surface->display;
1027 if (display->force_precision != -1)
1028 precision = display->force_precision;
1029 else switch (antialias) {
1031 case CAIRO_ANTIALIAS_DEFAULT:
1032 case CAIRO_ANTIALIAS_GRAY:
1033 case CAIRO_ANTIALIAS_NONE:
1034 case CAIRO_ANTIALIAS_FAST:
1035 case CAIRO_ANTIALIAS_GOOD:
1036 precision = PolyModeImprecise;
1038 case CAIRO_ANTIALIAS_BEST:
1039 case CAIRO_ANTIALIAS_SUBPIXEL:
1040 precision = PolyModePrecise;
1044 if (surface->precision != precision) {
1045 XRenderPictureAttributes pa;
1047 pa.poly_mode = precision;
1048 XRenderChangePicture (display->display, surface->picture,
1051 surface->precision = precision;
1056 _cairo_xlib_surface_ensure_picture (cairo_xlib_surface_t *surface)
1058 cairo_xlib_display_t *display = surface->display;
1059 XRenderPictureAttributes pa;
1062 if (surface->picture)
1065 if (display->force_precision != -1)
1066 pa.poly_mode = display->force_precision;
1068 pa.poly_mode = PolyModeImprecise;
1072 surface->precision = pa.poly_mode;
1073 surface->picture = XRenderCreatePicture (display->display,
1075 surface->xrender_format,
1080 _cairo_xlib_surface_draw_image (cairo_xlib_surface_t *surface,
1081 cairo_image_surface_t *image,
1089 cairo_xlib_display_t *display;
1091 cairo_format_masks_t image_masks;
1092 int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst;
1093 pixman_image_t *pixman_image = NULL;
1094 cairo_status_t status;
1095 cairo_bool_t own_data;
1096 cairo_bool_t is_rgb_image;
1099 ximage.width = image->width;
1100 ximage.height = image->height;
1101 ximage.format = ZPixmap;
1102 ximage.byte_order = native_byte_order;
1103 ximage.bitmap_unit = 32; /* always for libpixman */
1104 ximage.bitmap_bit_order = native_byte_order;
1105 ximage.bitmap_pad = 32; /* always for libpixman */
1106 ximage.depth = surface->depth;
1107 ximage.red_mask = surface->r_mask;
1108 ximage.green_mask = surface->g_mask;
1109 ximage.blue_mask = surface->b_mask;
1111 ximage.obdata = NULL;
1113 status = _cairo_xlib_display_acquire (surface->base.device, &display);
1114 if (unlikely (status))
1117 is_rgb_image = _pixman_format_to_masks (image->pixman_format, &image_masks);
1120 (image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) &&
1121 (image_masks.red_mask == surface->r_mask || surface->r_mask == 0) &&
1122 (image_masks.green_mask == surface->g_mask || surface->g_mask == 0) &&
1123 (image_masks.blue_mask == surface->b_mask || surface->b_mask == 0))
1127 ximage.bits_per_pixel = image_masks.bpp;
1128 ximage.bytes_per_line = image->stride;
1129 ximage.data = (char *)image->data;
1130 if (image->base.device == surface->base.device)
1131 ximage.obdata = _cairo_xlib_shm_surface_get_obdata (&image->base);
1134 ret = XInitImage (&ximage);
1137 else if (surface->visual == NULL || surface->visual->class == TrueColor)
1139 pixman_format_code_t intermediate_format;
1142 image_masks.alpha_mask = surface->a_mask;
1143 image_masks.red_mask = surface->r_mask;
1144 image_masks.green_mask = surface->g_mask;
1145 image_masks.blue_mask = surface->b_mask;
1146 image_masks.bpp = bits_per_pixel (surface);
1147 ret = _pixman_format_from_masks (&image_masks, &intermediate_format);
1152 pixman_image = pixman_image_create_bits (intermediate_format,
1153 width, height, NULL, 0);
1154 if (pixman_image == NULL) {
1155 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1159 pixman_image_composite32 (PIXMAN_OP_SRC,
1160 image->pixman_image,
1168 ximage.width = width;
1169 ximage.height = height;
1170 ximage.bits_per_pixel = image_masks.bpp;
1171 ximage.data = (char *) pixman_image_get_data (pixman_image);
1172 ximage.bytes_per_line = pixman_image_get_stride (pixman_image);
1174 ret = XInitImage (&ximage);
1181 unsigned int stride, rowstride;
1182 int x, y, x0, y0, x_off, y_off;
1183 uint32_t in_pixel, out_pixel, *row;
1184 int i_a_width=0, i_r_width=0, i_g_width=0, i_b_width=0;
1185 int i_a_shift=0, i_r_shift=0, i_g_shift=0, i_b_shift=0;
1186 int o_a_width=0, o_r_width=0, o_g_width=0, o_b_width=0;
1187 int o_a_shift=0, o_r_shift=0, o_g_shift=0, o_b_shift=0;
1188 cairo_xlib_visual_info_t *visual_info = NULL;
1189 cairo_bool_t true_color;
1192 ximage.bits_per_pixel = bits_per_pixel(surface);
1193 stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
1194 ximage.bits_per_pixel);
1195 ximage.bytes_per_line = stride;
1196 ximage.data = _cairo_malloc_ab (stride, ximage.height);
1197 if (unlikely (ximage.data == NULL)) {
1199 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1205 ret = XInitImage (&ximage);
1208 _characterize_field (image_masks.alpha_mask, &i_a_width, &i_a_shift);
1209 _characterize_field (image_masks.red_mask , &i_r_width, &i_r_shift);
1210 _characterize_field (image_masks.green_mask, &i_g_width, &i_g_shift);
1211 _characterize_field (image_masks.blue_mask , &i_b_width, &i_b_shift);
1213 true_color = surface->visual == NULL ||
1214 surface->visual->class == TrueColor;
1216 _characterize_field (surface->a_mask, &o_a_width, &o_a_shift);
1217 _characterize_field (surface->r_mask, &o_r_width, &o_r_shift);
1218 _characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
1219 _characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
1221 status = _cairo_xlib_screen_get_visual_info (display,
1225 if (unlikely (status))
1229 rowstride = image->stride >> 2;
1230 row = (uint32_t *) image->data;
1231 x0 = dst_x + surface->base.device_transform.x0;
1232 y0 = dst_y + surface->base.device_transform.y0;
1233 for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
1235 y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern))
1237 const int8_t *dither_row = dither_pattern[y_off];
1239 for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]);
1241 x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0]))
1243 int dither_adjustment = dither_row[x_off];
1246 if (image_masks.bpp == 1)
1247 in_pixel = !! (((uint8_t*)row)[x/8] & (1 << (x & 7)));
1248 else if (image_masks.bpp <= 8)
1249 in_pixel = ((uint8_t*)row)[x];
1250 else if (image_masks.bpp <= 16)
1251 in_pixel = ((uint16_t*)row)[x];
1252 else if (image_masks.bpp <= 24)
1253 #ifdef WORDS_BIGENDIAN
1254 in_pixel = ((uint8_t*)row)[3 * x] << 16 |
1255 ((uint8_t*)row)[3 * x + 1] << 8 |
1256 ((uint8_t*)row)[3 * x + 2];
1258 in_pixel = ((uint8_t*)row)[3 * x] |
1259 ((uint8_t*)row)[3 * x + 1] << 8 |
1260 ((uint8_t*)row)[3 * x + 2] << 16;
1265 /* If the incoming image has no alpha channel, then the input
1266 * is opaque and the output should have the maximum alpha value.
1267 * For all other channels, their absence implies 0.
1269 if (image_masks.alpha_mask == 0x0)
1272 a = _field_to_8 (in_pixel & image_masks.alpha_mask, i_a_width, i_a_shift);
1273 r = _field_to_8 (in_pixel & image_masks.red_mask , i_r_width, i_r_shift);
1274 g = _field_to_8 (in_pixel & image_masks.green_mask, i_g_width, i_g_shift);
1275 b = _field_to_8 (in_pixel & image_masks.blue_mask , i_b_width, i_b_shift);
1278 out_pixel = _field_from_8 (a, o_a_width, o_a_shift) |
1279 _field_from_8_dither (r, o_r_width, o_r_shift, dither_adjustment) |
1280 _field_from_8_dither (g, o_g_width, o_g_shift, dither_adjustment) |
1281 _field_from_8_dither (b, o_b_width, o_b_shift, dither_adjustment);
1283 out_pixel = _pseudocolor_from_rgb888_dither (visual_info, r, g, b, dither_adjustment);
1286 XPutPixel (&ximage, x, y, out_pixel);
1293 status = _cairo_xlib_surface_get_gc (display, surface, &gc);
1294 if (unlikely (status))
1298 XShmPutImage (display->display, surface->drawable, gc, &ximage,
1299 src_x, src_y, dst_x, dst_y, width, height, TRUE);
1301 XPutImage (display->display, surface->drawable, gc, &ximage,
1302 src_x, src_y, dst_x, dst_y, width, height);
1304 _cairo_xlib_surface_put_gc (display, surface, gc);
1307 cairo_device_release (&display->base);
1312 pixman_image_unref (pixman_image);
1314 return CAIRO_STATUS_SUCCESS;
1317 static cairo_surface_t *
1318 _cairo_xlib_surface_source(void *abstract_surface,
1319 cairo_rectangle_int_t *extents)
1321 cairo_xlib_surface_t *surface = abstract_surface;
1324 extents->x = extents->y = 0;
1325 extents->width = surface->width;
1326 extents->height = surface->height;
1329 return &surface->base;
1332 static cairo_status_t
1333 _cairo_xlib_surface_acquire_source_image (void *abstract_surface,
1334 cairo_image_surface_t **image_out,
1337 cairo_xlib_surface_t *surface = abstract_surface;
1338 cairo_rectangle_int_t extents;
1340 *image_extra = NULL;
1341 *image_out = (cairo_image_surface_t *)
1342 _cairo_xlib_surface_get_shm (abstract_surface, FALSE);
1344 return (*image_out)->base.status;
1346 extents.x = extents.y = 0;
1347 extents.width = surface->width;
1348 extents.height = surface->height;
1350 *image_out = (cairo_image_surface_t*)
1351 _get_image_surface (surface, &extents, TRUE);
1352 return (*image_out)->base.status;
1355 static cairo_surface_t *
1356 _cairo_xlib_surface_snapshot (void *abstract_surface)
1358 cairo_xlib_surface_t *surface = abstract_surface;
1359 cairo_rectangle_int_t extents;
1361 extents.x = extents.y = 0;
1362 extents.width = surface->width;
1363 extents.height = surface->height;
1365 return _get_image_surface (surface, &extents, FALSE);
1369 _cairo_xlib_surface_release_source_image (void *abstract_surface,
1370 cairo_image_surface_t *image,
1373 cairo_xlib_surface_t *surface = abstract_surface;
1375 if (&image->base == surface->shm)
1378 cairo_surface_destroy (&image->base);
1381 static cairo_image_surface_t *
1382 _cairo_xlib_surface_map_to_image (void *abstract_surface,
1383 const cairo_rectangle_int_t *extents)
1385 cairo_xlib_surface_t *surface = abstract_surface;
1386 cairo_surface_t *image;
1388 image = _cairo_xlib_surface_get_shm (abstract_surface, FALSE);
1390 assert (surface->base.damage);
1391 surface->fallback++;
1392 return _cairo_image_surface_map_to_image (image, extents);
1395 image = _get_image_surface (abstract_surface, extents, TRUE);
1396 cairo_surface_set_device_offset (image, -extents->x, -extents->y);
1398 return (cairo_image_surface_t *) image;
1401 static cairo_int_status_t
1402 _cairo_xlib_surface_unmap_image (void *abstract_surface,
1403 cairo_image_surface_t *image)
1405 cairo_xlib_surface_t *surface = abstract_surface;
1406 cairo_int_status_t status;
1409 cairo_rectangle_int_t r;
1411 assert (surface->fallback);
1412 assert (surface->base.damage);
1414 r.x = image->base.device_transform_inverse.x0;
1415 r.y = image->base.device_transform_inverse.y0;
1416 r.width = image->width;
1417 r.height = image->height;
1419 TRACE ((stderr, "%s: adding damage (%d,%d)x(%d,%d)\n",
1420 __FUNCTION__, r.x, r.y, r.width, r.height));
1421 surface->shm->damage =
1422 _cairo_damage_add_rectangle (surface->shm->damage, &r);
1424 return _cairo_image_surface_unmap_image (surface->shm, image);
1427 status = _cairo_xlib_surface_draw_image (abstract_surface, image,
1429 image->width, image->height,
1430 image->base.device_transform_inverse.x0,
1431 image->base.device_transform_inverse.y0);
1433 cairo_surface_finish (&image->base);
1434 cairo_surface_destroy (&image->base);
1439 static cairo_status_t
1440 _cairo_xlib_surface_flush (void *abstract_surface,
1443 cairo_xlib_surface_t *surface = abstract_surface;
1444 cairo_int_status_t status;
1447 return CAIRO_STATUS_SUCCESS;
1449 status = _cairo_xlib_surface_put_shm (surface);
1450 if (unlikely (status))
1453 surface->fallback >>= 1;
1454 if (surface->shm && _cairo_xlib_shm_surface_is_idle (surface->shm))
1455 _cairo_xlib_surface_discard_shm (surface);
1457 return CAIRO_STATUS_SUCCESS;
1461 _cairo_xlib_surface_get_extents (void *abstract_surface,
1462 cairo_rectangle_int_t *rectangle)
1464 cairo_xlib_surface_t *surface = abstract_surface;
1469 rectangle->width = surface->width;
1470 rectangle->height = surface->height;
1476 _cairo_xlib_surface_get_font_options (void *abstract_surface,
1477 cairo_font_options_t *options)
1479 cairo_xlib_surface_t *surface = abstract_surface;
1481 *options = *_cairo_xlib_screen_get_font_options (surface->screen);
1484 static inline cairo_int_status_t
1485 get_compositor (cairo_xlib_surface_t **surface,
1486 const cairo_compositor_t **compositor)
1488 cairo_xlib_surface_t *s = *surface;
1489 cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;;
1492 assert (s->base.damage != NULL);
1493 assert (s->shm != NULL);
1494 assert (s->shm->damage != NULL);
1495 if (! _cairo_xlib_shm_surface_is_active (s->shm)) {
1496 *surface = (cairo_xlib_surface_t *) s->shm;
1497 *compositor = ((cairo_image_surface_t *) s->shm)->compositor;
1500 status = _cairo_xlib_surface_put_shm (s);
1502 *compositor = s->compositor;
1505 *compositor = s->compositor;
1510 static cairo_int_status_t
1511 _cairo_xlib_surface_paint (void *_surface,
1512 cairo_operator_t op,
1513 const cairo_pattern_t *source,
1514 const cairo_clip_t *clip)
1516 cairo_xlib_surface_t *surface = _surface;
1517 const cairo_compositor_t *compositor;
1518 cairo_int_status_t status;
1520 status = get_compositor (&surface, &compositor);
1521 if (unlikely (status))
1524 return _cairo_compositor_paint (compositor, &surface->base,
1529 static cairo_int_status_t
1530 _cairo_xlib_surface_mask (void *_surface,
1531 cairo_operator_t op,
1532 const cairo_pattern_t *source,
1533 const cairo_pattern_t *mask,
1534 const cairo_clip_t *clip)
1536 cairo_xlib_surface_t *surface = _surface;
1537 const cairo_compositor_t *compositor;
1538 cairo_int_status_t status;
1540 status = get_compositor (&surface, &compositor);
1541 if (unlikely (status))
1544 return _cairo_compositor_mask (compositor, &surface->base,
1549 static cairo_int_status_t
1550 _cairo_xlib_surface_stroke (void *_surface,
1551 cairo_operator_t op,
1552 const cairo_pattern_t *source,
1553 const cairo_path_fixed_t *path,
1554 const cairo_stroke_style_t *style,
1555 const cairo_matrix_t *ctm,
1556 const cairo_matrix_t *ctm_inverse,
1558 cairo_antialias_t antialias,
1559 const cairo_clip_t *clip)
1561 cairo_xlib_surface_t *surface = _surface;
1562 const cairo_compositor_t *compositor;
1563 cairo_int_status_t status;
1565 status = get_compositor (&surface, &compositor);
1566 if (unlikely (status))
1569 return _cairo_compositor_stroke (compositor, &surface->base,
1571 path, style, ctm, ctm_inverse,
1572 tolerance, antialias,
1576 static cairo_int_status_t
1577 _cairo_xlib_surface_fill (void *_surface,
1578 cairo_operator_t op,
1579 const cairo_pattern_t *source,
1580 const cairo_path_fixed_t *path,
1581 cairo_fill_rule_t fill_rule,
1583 cairo_antialias_t antialias,
1584 const cairo_clip_t *clip)
1586 cairo_xlib_surface_t *surface = _surface;
1587 const cairo_compositor_t *compositor;
1588 cairo_int_status_t status;
1590 status = get_compositor (&surface, &compositor);
1591 if (unlikely (status))
1594 return _cairo_compositor_fill (compositor, &surface->base,
1596 path, fill_rule, tolerance, antialias,
1600 static cairo_int_status_t
1601 _cairo_xlib_surface_glyphs (void *_surface,
1602 cairo_operator_t op,
1603 const cairo_pattern_t *source,
1604 cairo_glyph_t *glyphs,
1606 cairo_scaled_font_t *scaled_font,
1607 const cairo_clip_t *clip)
1609 cairo_xlib_surface_t *surface = _surface;
1610 const cairo_compositor_t *compositor;
1611 cairo_int_status_t status;
1613 status = get_compositor (&surface, &compositor);
1614 if (unlikely (status))
1617 return _cairo_compositor_glyphs (compositor, &surface->base,
1619 glyphs, num_glyphs, scaled_font,
1623 static const cairo_surface_backend_t cairo_xlib_surface_backend = {
1624 CAIRO_SURFACE_TYPE_XLIB,
1625 _cairo_xlib_surface_finish,
1627 _cairo_default_context_create,
1629 _cairo_xlib_surface_create_similar,
1630 _cairo_xlib_surface_create_similar_shm,
1631 _cairo_xlib_surface_map_to_image,
1632 _cairo_xlib_surface_unmap_image,
1634 _cairo_xlib_surface_source,
1635 _cairo_xlib_surface_acquire_source_image,
1636 _cairo_xlib_surface_release_source_image,
1637 _cairo_xlib_surface_snapshot,
1639 NULL, /* copy_page */
1640 NULL, /* show_page */
1642 _cairo_xlib_surface_get_extents,
1643 _cairo_xlib_surface_get_font_options,
1645 _cairo_xlib_surface_flush,
1646 NULL, /* mark_dirty_rectangle */
1648 _cairo_xlib_surface_paint,
1649 _cairo_xlib_surface_mask,
1650 _cairo_xlib_surface_stroke,
1651 _cairo_xlib_surface_fill,
1652 NULL, /* fill-stroke */
1653 _cairo_xlib_surface_glyphs,
1657 * _cairo_surface_is_xlib:
1658 * @surface: a #cairo_surface_t
1660 * Checks if a surface is a #cairo_xlib_surface_t
1662 * Return value: True if the surface is an xlib surface
1665 _cairo_surface_is_xlib (cairo_surface_t *surface)
1667 return surface->backend == &cairo_xlib_surface_backend;
1670 static cairo_surface_t *
1671 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
1674 XRenderPictFormat *xrender_format,
1679 cairo_xlib_surface_t *surface;
1680 cairo_xlib_display_t *display;
1681 cairo_status_t status;
1684 if (xrender_format) {
1685 depth = xrender_format->depth;
1687 /* XXX find matching visual for core/dithering fallbacks? */
1688 } else if (visual) {
1689 Screen *scr = screen->screen;
1691 if (visual == DefaultVisualOfScreen (scr)) {
1692 depth = DefaultDepthOfScreen (scr);
1696 /* This is ugly, but we have to walk over all visuals
1697 * for the display to find the correct depth.
1700 for (j = 0; j < scr->ndepths; j++) {
1701 Depth *d = &scr->depths[j];
1702 for (k = 0; k < d->nvisuals; k++) {
1703 if (&d->visuals[k] == visual) {
1713 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1719 surface = malloc (sizeof (cairo_xlib_surface_t));
1720 if (unlikely (surface == NULL))
1721 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1723 status = _cairo_xlib_display_acquire (screen->device, &display);
1724 if (unlikely (status)) {
1726 return _cairo_surface_create_in_error (_cairo_error (status));
1729 surface->display = display;
1730 if (CAIRO_RENDER_HAS_CREATE_PICTURE (display)) {
1731 if (!xrender_format) {
1733 xrender_format = XRenderFindVisualFormat (display->display, visual);
1734 } else if (depth == 1) {
1736 _cairo_xlib_display_get_xrender_format (display,
1742 cairo_device_release (&display->base);
1744 _cairo_surface_init (&surface->base,
1745 &cairo_xlib_surface_backend,
1747 _xrender_format_to_content (xrender_format));
1749 surface->screen = screen;
1750 surface->compositor = display->compositor;
1751 surface->shm = NULL;
1752 surface->fallback = 0;
1754 surface->drawable = drawable;
1755 surface->owns_pixmap = FALSE;
1756 surface->use_pixmap = 0;
1757 surface->width = width;
1758 surface->height = height;
1760 surface->picture = None;
1761 surface->precision = PolyModePrecise;
1763 surface->embedded_source.picture = None;
1765 surface->visual = visual;
1766 surface->xrender_format = xrender_format;
1767 surface->depth = depth;
1770 * Compute the pixel format masks from either a XrenderFormat or
1771 * else from a visual; failing that we assume the drawable is an
1772 * alpha-only pixmap as it could only have been created that way
1773 * through the cairo_xlib_surface_create_for_bitmap function.
1775 if (xrender_format) {
1776 surface->a_mask = (unsigned long)
1777 surface->xrender_format->direct.alphaMask
1778 << surface->xrender_format->direct.alpha;
1779 surface->r_mask = (unsigned long)
1780 surface->xrender_format->direct.redMask
1781 << surface->xrender_format->direct.red;
1782 surface->g_mask = (unsigned long)
1783 surface->xrender_format->direct.greenMask
1784 << surface->xrender_format->direct.green;
1785 surface->b_mask = (unsigned long)
1786 surface->xrender_format->direct.blueMask
1787 << surface->xrender_format->direct.blue;
1788 } else if (visual) {
1789 surface->a_mask = 0;
1790 surface->r_mask = visual->red_mask;
1791 surface->g_mask = visual->green_mask;
1792 surface->b_mask = visual->blue_mask;
1795 surface->a_mask = (1 << depth) - 1;
1797 surface->a_mask = 0xffffffff;
1798 surface->r_mask = 0;
1799 surface->g_mask = 0;
1800 surface->b_mask = 0;
1803 cairo_list_add (&surface->link, &screen->surfaces);
1805 return &surface->base;
1809 _cairo_xlib_screen_from_visual (Display *dpy, Visual *visual)
1813 for (s = 0; s < ScreenCount (dpy); s++) {
1816 screen = ScreenOfDisplay (dpy, s);
1817 if (visual == DefaultVisualOfScreen (screen))
1820 for (d = 0; d < screen->ndepths; d++) {
1823 depth = &screen->depths[d];
1824 for (v = 0; v < depth->nvisuals; v++)
1825 if (visual == &depth->visuals[v])
1833 static cairo_bool_t valid_size (int width, int height)
1835 /* Note: the minimum surface size allowed in the X protocol is 1x1.
1836 * However, as we historically did not check the minimum size we
1837 * allowed applications to lie and set the correct size later (one hopes).
1838 * To preserve compatability we must allow applications to use
1841 return (width >= 0 && width <= XLIB_COORD_MAX &&
1842 height >= 0 && height <= XLIB_COORD_MAX);
1846 * cairo_xlib_surface_create:
1847 * @dpy: an X Display
1848 * @drawable: an X Drawable, (a Pixmap or a Window)
1849 * @visual: the visual to use for drawing to @drawable. The depth
1850 * of the visual must match the depth of the drawable.
1851 * Currently, only TrueColor visuals are fully supported.
1852 * @width: the current width of @drawable.
1853 * @height: the current height of @drawable.
1855 * Creates an Xlib surface that draws to the given drawable.
1856 * The way that colors are represented in the drawable is specified
1857 * by the provided visual.
1859 * Note: If @drawable is a Window, then the function
1860 * cairo_xlib_surface_set_size() must be called whenever the size of the
1863 * When @drawable is a Window containing child windows then drawing to
1864 * the created surface will be clipped by those child windows. When
1865 * the created surface is used as a source, the contents of the
1866 * children will be included.
1868 * Return value: the newly created surface
1873 cairo_xlib_surface_create (Display *dpy,
1880 cairo_xlib_screen_t *screen;
1881 cairo_status_t status;
1883 if (! valid_size (width, height)) {
1884 /* you're lying, and you know it! */
1885 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1888 scr = _cairo_xlib_screen_from_visual (dpy, visual);
1890 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1892 status = _cairo_xlib_screen_get (dpy, scr, &screen);
1893 if (unlikely (status))
1894 return _cairo_surface_create_in_error (status);
1896 X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable));
1898 return _cairo_xlib_surface_create_internal (screen, drawable,
1904 * cairo_xlib_surface_create_for_bitmap:
1905 * @dpy: an X Display
1906 * @bitmap: an X Drawable, (a depth-1 Pixmap)
1907 * @screen: the X Screen associated with @bitmap
1908 * @width: the current width of @bitmap.
1909 * @height: the current height of @bitmap.
1911 * Creates an Xlib surface that draws to the given bitmap.
1912 * This will be drawn to as a %CAIRO_FORMAT_A1 object.
1914 * Return value: the newly created surface
1919 cairo_xlib_surface_create_for_bitmap (Display *dpy,
1925 cairo_xlib_screen_t *screen;
1926 cairo_status_t status;
1928 if (! valid_size (width, height))
1929 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1931 status = _cairo_xlib_screen_get (dpy, scr, &screen);
1932 if (unlikely (status))
1933 return _cairo_surface_create_in_error (status);
1935 X_DEBUG ((dpy, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap));
1937 return _cairo_xlib_surface_create_internal (screen, bitmap,
1942 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
1944 * cairo_xlib_surface_create_with_xrender_format:
1945 * @dpy: an X Display
1946 * @drawable: an X Drawable, (a Pixmap or a Window)
1947 * @screen: the X Screen associated with @drawable
1948 * @format: the picture format to use for drawing to @drawable. The depth
1949 * of @format must match the depth of the drawable.
1950 * @width: the current width of @drawable.
1951 * @height: the current height of @drawable.
1953 * Creates an Xlib surface that draws to the given drawable.
1954 * The way that colors are represented in the drawable is specified
1955 * by the provided picture format.
1957 * Note: If @drawable is a Window, then the function
1958 * cairo_xlib_surface_set_size() must be called whenever the size of the
1961 * Return value: the newly created surface
1966 cairo_xlib_surface_create_with_xrender_format (Display *dpy,
1969 XRenderPictFormat *format,
1973 cairo_xlib_screen_t *screen;
1974 cairo_status_t status;
1976 if (! valid_size (width, height))
1977 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1979 status = _cairo_xlib_screen_get (dpy, scr, &screen);
1980 if (unlikely (status))
1981 return _cairo_surface_create_in_error (status);
1983 X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable));
1985 return _cairo_xlib_surface_create_internal (screen, drawable,
1986 _visual_for_xrender_format (scr, format),
1987 format, width, height, 0);
1991 * cairo_xlib_surface_get_xrender_format:
1992 * @surface: an xlib surface
1994 * Gets the X Render picture format that @surface uses for rendering with the
1995 * X Render extension. If the surface was created by
1996 * cairo_xlib_surface_create_with_xrender_format() originally, the return
1997 * value is the format passed to that constructor.
1999 * Return value: the XRenderPictFormat* associated with @surface,
2000 * or %NULL if the surface is not an xlib surface
2001 * or if the X Render extension is not available.
2006 cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface)
2008 cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
2010 /* Throw an error for a non-xlib surface */
2011 if (! _cairo_surface_is_xlib (surface)) {
2012 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2016 return xlib_surface->xrender_format;
2021 * cairo_xlib_surface_set_size:
2022 * @surface: a #cairo_surface_t for the XLib backend
2023 * @width: the new width of the surface
2024 * @height: the new height of the surface
2026 * Informs cairo of the new size of the X Drawable underlying the
2027 * surface. For a surface created for a Window (rather than a Pixmap),
2028 * this function must be called each time the size of the window
2029 * changes. (For a subwindow, you are normally resizing the window
2030 * yourself, but for a toplevel window, it is necessary to listen for
2031 * ConfigureNotify events.)
2033 * A Pixmap can never change size, so it is never necessary to call
2034 * this function on a surface created for a Pixmap.
2039 cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface,
2043 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2044 cairo_status_t status;
2046 if (unlikely (abstract_surface->status))
2048 if (unlikely (abstract_surface->finished)) {
2049 _cairo_surface_set_error (abstract_surface,
2050 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2054 if (! _cairo_surface_is_xlib (abstract_surface)) {
2055 _cairo_surface_set_error (abstract_surface,
2056 _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
2060 if (surface->width == width && surface->height == height)
2063 if (! valid_size (width, height)) {
2064 _cairo_surface_set_error (abstract_surface,
2065 _cairo_error (CAIRO_STATUS_INVALID_SIZE));
2069 status = _cairo_surface_flush (abstract_surface, 0);
2070 if (unlikely (status)) {
2071 _cairo_surface_set_error (abstract_surface, status);
2075 _cairo_xlib_surface_discard_shm (surface);
2077 surface->width = width;
2078 surface->height = height;
2082 * cairo_xlib_surface_set_drawable:
2083 * @surface: a #cairo_surface_t for the XLib backend
2084 * @drawable: the new drawable for the surface
2085 * @width: the width of the new drawable
2086 * @height: the height of the new drawable
2088 * Informs cairo of a new X Drawable underlying the
2089 * surface. The drawable must match the display, screen
2090 * and format of the existing drawable or the application
2091 * will get X protocol errors and will probably terminate.
2092 * No checks are done by this function to ensure this
2098 cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
2103 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
2104 cairo_status_t status;
2106 if (unlikely (abstract_surface->status))
2108 if (unlikely (abstract_surface->finished)) {
2109 status = _cairo_surface_set_error (abstract_surface,
2110 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2114 if (! _cairo_surface_is_xlib (abstract_surface)) {
2115 status = _cairo_surface_set_error (abstract_surface,
2116 _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
2120 if (! valid_size (width, height)) {
2121 status = _cairo_surface_set_error (abstract_surface,
2122 _cairo_error (CAIRO_STATUS_INVALID_SIZE));
2126 /* XXX: and what about this case? */
2127 if (surface->owns_pixmap)
2130 status = _cairo_surface_flush (abstract_surface, 0);
2131 if (unlikely (status)) {
2132 _cairo_surface_set_error (abstract_surface, status);
2136 if (surface->drawable != drawable) {
2137 cairo_xlib_display_t *display;
2139 status = _cairo_xlib_display_acquire (surface->base.device, &display);
2140 if (unlikely (status))
2143 X_DEBUG ((display->display, "set_drawable (drawable=%x)", (unsigned int) drawable));
2145 if (surface->picture != None) {
2146 XRenderFreePicture (display->display, surface->picture);
2147 if (unlikely (status)) {
2148 status = _cairo_surface_set_error (&surface->base, status);
2152 surface->picture = None;
2155 cairo_device_release (&display->base);
2157 surface->drawable = drawable;
2160 if (surface->width != width || surface->height != height) {
2161 _cairo_xlib_surface_discard_shm (surface);
2163 surface->width = width;
2164 surface->height = height;
2169 * cairo_xlib_surface_get_display:
2170 * @surface: a #cairo_xlib_surface_t
2172 * Get the X Display for the underlying X Drawable.
2174 * Return value: the display.
2179 cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
2181 if (! _cairo_surface_is_xlib (abstract_surface)) {
2182 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2186 return ((cairo_xlib_display_t *) abstract_surface->device)->display;
2190 * cairo_xlib_surface_get_drawable:
2191 * @surface: a #cairo_xlib_surface_t
2193 * Get the underlying X Drawable used for the surface.
2195 * Return value: the drawable.
2200 cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface)
2202 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2204 if (! _cairo_surface_is_xlib (abstract_surface)) {
2205 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2209 return surface->drawable;
2213 * cairo_xlib_surface_get_screen:
2214 * @surface: a #cairo_xlib_surface_t
2216 * Get the X Screen for the underlying X Drawable.
2218 * Return value: the screen.
2223 cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
2225 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2227 if (! _cairo_surface_is_xlib (abstract_surface)) {
2228 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2232 return surface->screen->screen;
2236 * cairo_xlib_surface_get_visual:
2237 * @surface: a #cairo_xlib_surface_t
2239 * Gets the X Visual associated with @surface, suitable for use with the
2240 * underlying X Drawable. If @surface was created by
2241 * cairo_xlib_surface_create(), the return value is the Visual passed to that
2244 * Return value: the Visual or %NULL if there is no appropriate Visual for
2250 cairo_xlib_surface_get_visual (cairo_surface_t *surface)
2252 cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
2254 if (! _cairo_surface_is_xlib (surface)) {
2255 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2259 return xlib_surface->visual;
2263 * cairo_xlib_surface_get_depth:
2264 * @surface: a #cairo_xlib_surface_t
2266 * Get the number of bits used to represent each pixel value.
2268 * Return value: the depth of the surface in bits.
2273 cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
2275 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2277 if (! _cairo_surface_is_xlib (abstract_surface)) {
2278 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2282 return surface->depth;
2286 * cairo_xlib_surface_get_width:
2287 * @surface: a #cairo_xlib_surface_t
2289 * Get the width of the X Drawable underlying the surface in pixels.
2291 * Return value: the width of the surface in pixels.
2296 cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface)
2298 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2300 if (! _cairo_surface_is_xlib (abstract_surface)) {
2301 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2305 return surface->width;
2309 * cairo_xlib_surface_get_height:
2310 * @surface: a #cairo_xlib_surface_t
2312 * Get the height of the X Drawable underlying the surface in pixels.
2314 * Return value: the height of the surface in pixels.
2319 cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface)
2321 cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2323 if (! _cairo_surface_is_xlib (abstract_surface)) {
2324 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2328 return surface->height;
2331 #endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */