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-pixman-private.h"
64 #include "cairo-region-private.h"
65 #include "cairo-scaled-font-private.h"
66 #include "cairo-surface-snapshot-private.h"
67 #include "cairo-surface-subsurface-private.h"
69 #include <X11/Xutil.h> /* for XDestroyImage */
71 #include <X11/extensions/XShm.h>
75 #define XLIB_COORD_MAX 32767
80 #define UNSUPPORTED(reason) \
82 "cairo-xlib: hit unsupported operation %s(), line %d: %s\n", \
83 __FUNCTION__, __LINE__, reason), \
84 CAIRO_INT_STATUS_UNSUPPORTED
86 #define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
90 #include <X11/Xlibint.h>
91 static void CAIRO_PRINTF_FORMAT (2, 3)
92 _x_bread_crumb (Display
*dpy
,
98 unsigned int len
, len_dwords
;
102 len
= vsnprintf (buf
, sizeof (buf
), fmt
, ap
);
110 GetEmptyReq (NoOperation
, req
);
112 len_dwords
= len
>> 2;
113 SetReqLen (req
, len_dwords
, len_dwords
);
114 Data (dpy
, buf
, len
);
119 #define X_DEBUG(x) _x_bread_crumb x
126 * @Title: XLib Surfaces
127 * @Short_Description: X Window System rendering using XLib
128 * @See_Also: #cairo_surface_t
130 * The XLib surface is used to render cairo graphics to X Window System
131 * windows and pixmaps using the XLib library.
133 * Note that the XLib surface automatically takes advantage of X render extension
134 * if it is available.
138 * CAIRO_HAS_XLIB_SURFACE:
140 * Defined if the Xlib surface backend is available.
141 * This macro can be used to conditionally compile backend-specific code.
147 * SECTION:cairo-xlib-xrender
148 * @Title: XLib-XRender Backend
149 * @Short_Description: X Window System rendering using XLib and the X Render extension
150 * @See_Also: #cairo_surface_t
152 * The XLib surface is used to render cairo graphics to X Window System
153 * windows and pixmaps using the XLib and Xrender libraries.
155 * Note that the XLib surface automatically takes advantage of X Render extension
156 * if it is available.
160 * CAIRO_HAS_XLIB_XRENDER_SURFACE:
162 * Defined if the XLib/XRender surface functions are available.
163 * This macro can be used to conditionally compile backend-specific code.
168 /* Xlib doesn't define a typedef, so define one ourselves */
169 typedef int (*cairo_xlib_error_func_t
) (Display
*display
,
172 static cairo_surface_t
*
173 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t
*screen
,
176 XRenderPictFormat
*xrender_format
,
182 _cairo_surface_is_xlib (cairo_surface_t
*surface
);
185 * Instead of taking two round trips for each blending request,
186 * assume that if a particular drawable fails GetImage that it will
187 * fail for a "while"; use temporary pixmaps to avoid the errors
190 #define CAIRO_ASSUME_PIXMAP 20
192 static const XTransform identity
= { {
193 { 1 << 16, 0x00000, 0x00000 },
194 { 0x00000, 1 << 16, 0x00000 },
195 { 0x00000, 0x00000, 1 << 16 },
199 _visual_for_xrender_format(Screen
*screen
,
200 XRenderPictFormat
*xrender_format
)
204 /* XXX Consider searching through the list of known cairo_visual_t for
205 * the reverse mapping.
208 for (d
= 0; d
< screen
->ndepths
; d
++) {
209 Depth
*d_info
= &screen
->depths
[d
];
211 if (d_info
->depth
!= xrender_format
->depth
)
214 for (v
= 0; v
< d_info
->nvisuals
; v
++) {
215 Visual
*visual
= &d_info
->visuals
[v
];
217 switch (visual
->class) {
219 if (xrender_format
->type
!= PictTypeDirect
)
224 /* Prefer TrueColor to DirectColor.
225 * (XRenderFindVisualFormat considers both TrueColor and DirectColor
226 * Visuals to match the same PictFormat.)
234 if (xrender_format
->type
!= PictTypeIndexed
)
239 if (xrender_format
==
240 XRenderFindVisualFormat (DisplayOfScreen(screen
), visual
))
248 static cairo_content_t
249 _xrender_format_to_content (XRenderPictFormat
*xrender_format
)
251 cairo_content_t content
;
253 /* This only happens when using a non-Render server. Let's punt
254 * and say there's no alpha here. */
255 if (xrender_format
== NULL
)
256 return CAIRO_CONTENT_COLOR
;
259 if (xrender_format
->direct
.alphaMask
)
260 content
|= CAIRO_CONTENT_ALPHA
;
261 if (xrender_format
->direct
.redMask
|
262 xrender_format
->direct
.greenMask
|
263 xrender_format
->direct
.blueMask
)
264 content
|= CAIRO_CONTENT_COLOR
;
269 static cairo_surface_t
*
270 _cairo_xlib_surface_create_similar (void *abstract_src
,
271 cairo_content_t content
,
275 cairo_xlib_surface_t
*src
= abstract_src
;
276 XRenderPictFormat
*xrender_format
;
277 cairo_xlib_surface_t
*surface
;
278 cairo_xlib_display_t
*display
;
281 if (width
> XLIB_COORD_MAX
|| height
> XLIB_COORD_MAX
)
284 if (width
== 0 || height
== 0)
287 if (_cairo_xlib_display_acquire (src
->base
.device
, &display
))
290 /* If we never found an XRenderFormat or if it isn't compatible
291 * with the content being requested, then we fallback to just
292 * constructing a cairo_format_t instead, (which will fairly
293 * arbitrarily pick a visual/depth for the similar surface.
295 xrender_format
= NULL
;
296 if (src
->xrender_format
&&
297 _xrender_format_to_content (src
->xrender_format
) == content
)
299 xrender_format
= src
->xrender_format
;
301 if (xrender_format
== NULL
) {
303 _cairo_xlib_display_get_xrender_format (display
,
304 _cairo_format_from_content (content
));
306 if (xrender_format
) {
309 /* We've got a compatible XRenderFormat now, which means the
310 * similar surface will match the existing surface as closely in
311 * visual/depth etc. as possible. */
312 pix
= XCreatePixmap (display
->display
, src
->drawable
,
313 width
, height
, xrender_format
->depth
);
315 if (xrender_format
== src
->xrender_format
)
316 visual
= src
->visual
;
318 visual
= _visual_for_xrender_format(src
->screen
->screen
,
321 surface
= (cairo_xlib_surface_t
*)
322 _cairo_xlib_surface_create_internal (src
->screen
, pix
, visual
,
325 xrender_format
->depth
);
329 Screen
*screen
= src
->screen
->screen
;
332 /* No compatible XRenderFormat, see if we can make an ordinary pixmap,
333 * so that we can still accelerate blits with XCopyArea(). */
334 if (content
!= CAIRO_CONTENT_COLOR
) {
335 cairo_device_release (&display
->base
);
339 depth
= DefaultDepthOfScreen (screen
);
341 pix
= XCreatePixmap (display
->display
, RootWindowOfScreen (screen
),
342 width
<= 0 ? 1 : width
, height
<= 0 ? 1 : height
,
345 surface
= (cairo_xlib_surface_t
*)
346 _cairo_xlib_surface_create_internal (src
->screen
, pix
,
347 DefaultVisualOfScreen (screen
),
349 width
, height
, depth
);
352 if (likely (surface
->base
.status
== CAIRO_STATUS_SUCCESS
))
353 surface
->owns_pixmap
= TRUE
;
355 XFreePixmap (display
->display
, pix
);
357 cairo_device_release (&display
->base
);
359 return &surface
->base
;
363 _cairo_xlib_surface_discard_shm (cairo_xlib_surface_t
*surface
)
365 if (surface
->shm
== NULL
)
368 /* Force the flush for an external surface */
369 if (!surface
->owns_pixmap
)
370 cairo_surface_flush (surface
->shm
);
372 cairo_surface_finish (surface
->shm
);
373 cairo_surface_destroy (surface
->shm
);
376 _cairo_damage_destroy (surface
->base
.damage
);
377 surface
->base
.damage
= NULL
;
379 surface
->fallback
= 0;
382 static cairo_status_t
383 _cairo_xlib_surface_finish (void *abstract_surface
)
385 cairo_xlib_surface_t
*surface
= abstract_surface
;
386 cairo_status_t status
;
387 cairo_xlib_display_t
*display
;
389 cairo_list_del (&surface
->link
);
391 status
= _cairo_xlib_display_acquire (surface
->base
.device
, &display
);
392 if (unlikely (status
))
395 X_DEBUG ((display
->display
, "finish (drawable=%x)", (unsigned int) surface
->drawable
));
397 if (surface
->embedded_source
.picture
)
398 XRenderFreePicture (display
->display
, surface
->embedded_source
.picture
);
399 if (surface
->picture
)
400 XRenderFreePicture (display
->display
, surface
->picture
);
402 _cairo_xlib_surface_discard_shm (surface
);
404 if (surface
->owns_pixmap
)
405 XFreePixmap (display
->display
, surface
->drawable
);
407 cairo_device_release (&display
->base
);
413 _cairo_xlib_surface_get_gc (cairo_xlib_display_t
*display
,
414 cairo_xlib_surface_t
*surface
,
417 *gc
= _cairo_xlib_screen_get_gc (display
,
421 if (unlikely (*gc
== NULL
))
422 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
424 return CAIRO_STATUS_SUCCESS
;
428 _noop_error_handler (Display
*display
,
431 return False
; /* return value is ignored */
435 _swap_ximage_2bytes (XImage
*ximage
)
438 char *line
= ximage
->data
;
440 for (j
= ximage
->height
; j
; j
--) {
441 uint16_t *p
= (uint16_t *) line
;
442 for (i
= ximage
->width
; i
; i
--) {
447 line
+= ximage
->bytes_per_line
;
452 _swap_ximage_3bytes (XImage
*ximage
)
455 char *line
= ximage
->data
;
457 for (j
= ximage
->height
; j
; j
--) {
458 uint8_t *p
= (uint8_t *) line
;
459 for (i
= ximage
->width
; i
; i
--) {
467 line
+= ximage
->bytes_per_line
;
472 _swap_ximage_4bytes (XImage
*ximage
)
475 char *line
= ximage
->data
;
477 for (j
= ximage
->height
; j
; j
--) {
478 uint32_t *p
= (uint32_t *) line
;
479 for (i
= ximage
->width
; i
; i
--) {
484 line
+= ximage
->bytes_per_line
;
489 _swap_ximage_nibbles (XImage
*ximage
)
492 char *line
= ximage
->data
;
494 for (j
= ximage
->height
; j
; j
--) {
495 uint8_t *p
= (uint8_t *) line
;
496 for (i
= (ximage
->width
+ 1) / 2; i
; i
--) {
497 *p
= ((*p
>> 4) & 0xf) | ((*p
<< 4) & ~0xf);
501 line
+= ximage
->bytes_per_line
;
506 _swap_ximage_bits (XImage
*ximage
)
509 char *line
= ximage
->data
;
510 int unit
= ximage
->bitmap_unit
;
511 int line_bytes
= ((ximage
->width
+ unit
- 1) & ~(unit
- 1)) / 8;
513 for (j
= ximage
->height
; j
; j
--) {
516 for (i
= line_bytes
; i
; i
--) {
518 b
= ((b
<< 1) & 0xaa) | ((b
>> 1) & 0x55);
519 b
= ((b
<< 2) & 0xcc) | ((b
>> 2) & 0x33);
520 b
= ((b
<< 4) & 0xf0) | ((b
>> 4) & 0x0f);
526 line
+= ximage
->bytes_per_line
;
531 _swap_ximage_to_native (XImage
*ximage
)
534 int native_byte_order
= _cairo_is_little_endian () ? LSBFirst
: MSBFirst
;
536 if (ximage
->bits_per_pixel
== 1 &&
537 ximage
->bitmap_bit_order
!= native_byte_order
)
539 _swap_ximage_bits (ximage
);
540 if (ximage
->bitmap_bit_order
== ximage
->byte_order
)
544 if (ximage
->byte_order
== native_byte_order
)
547 switch (ximage
->bits_per_pixel
) {
549 unit_bytes
= ximage
->bitmap_unit
/ 8;
552 _swap_ximage_nibbles (ximage
);
561 unit_bytes
= (ximage
->bits_per_pixel
+ 7) / 8;
564 /* This could be hit on some rare but possible cases. */
568 switch (unit_bytes
) {
572 _swap_ximage_2bytes (ximage
);
575 _swap_ximage_3bytes (ximage
);
578 _swap_ximage_4bytes (ximage
);
586 /* Given a mask, (with a single sequence of contiguous 1 bits), return
587 * the number of 1 bits in 'width' and the number of 0 bits to its
588 * right in 'shift'. */
590 _characterize_field (uint32_t mask
, int *width
, int *shift
)
592 *width
= _cairo_popcount (mask
);
593 /* The final '& 31' is to force a 0 mask to result in 0 shift. */
594 *shift
= _cairo_popcount ((mask
- 1) & ~mask
) & 31;
597 /* Convert a field of 'width' bits to 'new_width' bits with correct
599 static inline uint32_t
600 _resize_field (uint32_t field
, int width
, int new_width
)
605 if (width
>= new_width
) {
606 return field
>> (width
- new_width
);
608 uint32_t result
= field
<< (new_width
- width
);
610 while (width
< new_width
) {
611 result
|= result
>> width
;
618 static inline uint32_t
619 _adjust_field (uint32_t field
, int adjustment
)
621 return MIN (255, MAX(0, (int)field
+ adjustment
));
624 /* Given a shifted field value, (described by 'width' and 'shift),
625 * resize it 8-bits and return that value.
627 * Note that the original field value must not have any non-field bits
630 static inline uint32_t
631 _field_to_8 (uint32_t field
, int width
, int shift
)
633 return _resize_field (field
>> shift
, width
, 8);
636 static inline uint32_t
637 _field_to_8_undither (uint32_t field
, int width
, int shift
,
638 int dither_adjustment
)
640 return _adjust_field (_field_to_8 (field
, width
, shift
), - dither_adjustment
>>width
);
643 /* Given an 8-bit value, convert it to a field of 'width', shift it up
644 * to 'shift, and return it. */
645 static inline uint32_t
646 _field_from_8 (uint32_t field
, int width
, int shift
)
648 return _resize_field (field
, 8, width
) << shift
;
651 static inline uint32_t
652 _field_from_8_dither (uint32_t field
, int width
, int shift
,
653 int8_t dither_adjustment
)
655 return _field_from_8 (_adjust_field (field
, dither_adjustment
>>width
), width
, shift
);
658 static inline uint32_t
659 _pseudocolor_from_rgb888_dither (cairo_xlib_visual_info_t
*visual_info
,
660 uint32_t r
, uint32_t g
, uint32_t b
,
661 int8_t dither_adjustment
)
663 if (r
== g
&& g
== b
) {
664 dither_adjustment
/= RAMP_SIZE
;
665 return visual_info
->gray8_to_pseudocolor
[_adjust_field (r
, dither_adjustment
)];
667 dither_adjustment
= visual_info
->dither8_to_cube
[dither_adjustment
+128];
668 return visual_info
->cube_to_pseudocolor
[visual_info
->field8_to_cube
[_adjust_field (r
, dither_adjustment
)]]
669 [visual_info
->field8_to_cube
[_adjust_field (g
, dither_adjustment
)]]
670 [visual_info
->field8_to_cube
[_adjust_field (b
, dither_adjustment
)]];
674 static inline uint32_t
675 _pseudocolor_to_rgb888 (cairo_xlib_visual_info_t
*visual_info
,
680 r
= visual_info
->colors
[pixel
].r
;
681 g
= visual_info
->colors
[pixel
].g
;
682 b
= visual_info
->colors
[pixel
].b
;
688 /* should range from -128 to 127 */
690 static const int8_t dither_pattern
[4][4] = {
691 {-8*X
, +0*X
, -6*X
, +2*X
},
692 {+4*X
, -4*X
, +6*X
, -2*X
},
693 {-5*X
, +4*X
, -7*X
, +1*X
},
694 {+7*X
, -1*X
, +5*X
, -3*X
}
698 static int bits_per_pixel(cairo_xlib_surface_t
*surface
)
700 if (surface
->depth
> 16)
702 else if (surface
->depth
> 8)
704 else if (surface
->depth
> 1)
711 _pixman_format_for_xlib_surface (cairo_xlib_surface_t
*surface
)
713 cairo_format_masks_t masks
;
714 pixman_format_code_t format
;
716 masks
.bpp
= bits_per_pixel (surface
);
717 masks
.alpha_mask
= surface
->a_mask
;
718 masks
.red_mask
= surface
->r_mask
;
719 masks
.green_mask
= surface
->g_mask
;
720 masks
.blue_mask
= surface
->b_mask
;
721 if (! _pixman_format_from_masks (&masks
, &format
))
727 static cairo_surface_t
*
728 _get_image_surface (cairo_xlib_surface_t
*surface
,
729 const cairo_rectangle_int_t
*extents
,
732 cairo_int_status_t status
;
733 cairo_image_surface_t
*image
= NULL
;
735 pixman_format_code_t pixman_format
;
736 cairo_xlib_display_t
*display
;
738 assert (extents
->x
>= 0);
739 assert (extents
->y
>= 0);
740 assert (extents
->x
+ extents
->width
<= surface
->width
);
741 assert (extents
->y
+ extents
->height
<= surface
->height
);
743 if (surface
->base
.is_clear
||
744 (surface
->base
.serial
== 0 && surface
->owns_pixmap
))
746 pixman_format
= _pixman_format_for_xlib_surface (surface
);
749 return _cairo_image_surface_create_with_pixman_format (NULL
,
758 cairo_image_surface_t
*src
= (cairo_image_surface_t
*) surface
->shm
;
759 cairo_surface_t
*dst
;
760 cairo_surface_pattern_t pattern
;
762 dst
= cairo_image_surface_create (src
->format
,
763 extents
->width
, extents
->height
);
764 if (unlikely (dst
->status
))
767 _cairo_pattern_init_for_surface (&pattern
, &src
->base
);
768 cairo_matrix_init_translate (&pattern
.base
.matrix
,
769 extents
->x
, extents
->y
);
770 status
= _cairo_surface_paint (dst
, CAIRO_OPERATOR_SOURCE
, &pattern
.base
, NULL
);
771 _cairo_pattern_fini (&pattern
.base
);
772 if (unlikely (status
)) {
773 cairo_surface_destroy (dst
);
774 dst
= _cairo_surface_create_in_error (status
);
780 status
= _cairo_xlib_display_acquire (surface
->base
.device
, &display
);
782 return _cairo_surface_create_in_error (status
);
784 pixman_format
= _pixman_format_for_xlib_surface (surface
);
785 if (try_shm
&& pixman_format
) {
786 image
= (cairo_image_surface_t
*)
787 _cairo_xlib_surface_create_shm__image (surface
, pixman_format
,
788 extents
->width
, extents
->height
);
789 if (image
&& image
->base
.status
== CAIRO_STATUS_SUCCESS
) {
790 cairo_xlib_error_func_t old_handler
;
794 _cairo_xlib_shm_surface_get_ximage (&image
->base
, &shm_image
);
796 old_handler
= XSetErrorHandler (_noop_error_handler
);
797 success
= XShmGetImage (display
->display
,
800 extents
->x
, extents
->y
,
802 XSetErrorHandler (old_handler
);
805 cairo_device_release (&display
->base
);
809 cairo_surface_destroy (&image
->base
);
813 if (surface
->use_pixmap
== 0) {
814 cairo_xlib_error_func_t old_handler
;
816 old_handler
= XSetErrorHandler (_noop_error_handler
);
818 ximage
= XGetImage (display
->display
,
820 extents
->x
, extents
->y
,
821 extents
->width
, extents
->height
,
824 XSetErrorHandler (old_handler
);
826 /* If we get an error, the surface must have been a window,
827 * so retry with the safe code path.
830 surface
->use_pixmap
= CAIRO_ASSUME_PIXMAP
;
832 surface
->use_pixmap
--;
836 if (ximage
== NULL
) {
837 /* XGetImage from a window is dangerous because it can
838 * produce errors if the window is unmapped or partially
839 * outside the screen. We could check for errors and
840 * retry, but to keep things simple, we just create a
846 status
= _cairo_xlib_surface_get_gc (display
, surface
, &gc
);
847 if (unlikely (status
))
850 pixmap
= XCreatePixmap (display
->display
,
852 extents
->width
, extents
->height
,
857 gcv
.subwindow_mode
= IncludeInferiors
;
858 XChangeGC (display
->display
, gc
, GCSubwindowMode
, &gcv
);
860 XCopyArea (display
->display
, surface
->drawable
, pixmap
, gc
,
861 extents
->x
, extents
->y
,
862 extents
->width
, extents
->height
,
865 gcv
.subwindow_mode
= ClipByChildren
;
866 XChangeGC (display
->display
, gc
, GCSubwindowMode
, &gcv
);
868 ximage
= XGetImage (display
->display
,
871 extents
->width
, extents
->height
,
874 XFreePixmap (display
->display
, pixmap
);
877 _cairo_xlib_surface_put_gc (display
, surface
, gc
);
879 if (ximage
== NULL
) {
880 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
885 _swap_ximage_to_native (ximage
);
887 /* We can't use pixman to simply write to image if:
888 * (a) the pixels are not appropriately aligned,
889 * (b) pixman does not the pixel format, or
890 * (c) if the image is palettized and we need to convert.
893 ximage
->bitmap_unit
== 32 && ximage
->bitmap_pad
== 32 &&
894 (surface
->visual
== NULL
|| surface
->visual
->class == TrueColor
))
896 image
= (cairo_image_surface_t
*)
897 _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage
->data
,
901 ximage
->bytes_per_line
);
902 status
= image
->base
.status
;
903 if (unlikely (status
))
906 /* Let the surface take ownership of the data */
907 _cairo_image_surface_assume_ownership_of_data (image
);
910 /* The visual we are dealing with is not supported by the
911 * standard pixman formats. So we must first convert the data
912 * to a supported format. */
914 cairo_format_t format
;
917 uint32_t in_pixel
, out_pixel
;
918 unsigned int rowstride
;
919 uint32_t a_mask
=0, r_mask
=0, g_mask
=0, b_mask
=0;
920 int a_width
=0, r_width
=0, g_width
=0, b_width
=0;
921 int a_shift
=0, r_shift
=0, g_shift
=0, b_shift
=0;
922 int x
, y
, x0
, y0
, x_off
, y_off
;
923 cairo_xlib_visual_info_t
*visual_info
= NULL
;
925 if (surface
->visual
== NULL
|| surface
->visual
->class == TrueColor
) {
926 cairo_bool_t has_alpha
;
927 cairo_bool_t has_color
;
929 has_alpha
= surface
->a_mask
;
930 has_color
= (surface
->r_mask
||
936 format
= CAIRO_FORMAT_ARGB32
;
938 format
= CAIRO_FORMAT_RGB24
;
941 /* XXX: Using CAIRO_FORMAT_A8 here would be more
942 * efficient, but would require slightly different code in
943 * the image conversion to put the alpha channel values
944 * into the right place. */
945 format
= CAIRO_FORMAT_ARGB32
;
948 a_mask
= surface
->a_mask
;
949 r_mask
= surface
->r_mask
;
950 g_mask
= surface
->g_mask
;
951 b_mask
= surface
->b_mask
;
953 _characterize_field (a_mask
, &a_width
, &a_shift
);
954 _characterize_field (r_mask
, &r_width
, &r_shift
);
955 _characterize_field (g_mask
, &g_width
, &g_shift
);
956 _characterize_field (b_mask
, &b_width
, &b_shift
);
959 format
= CAIRO_FORMAT_RGB24
;
961 status
= _cairo_xlib_screen_get_visual_info (display
,
965 if (unlikely (status
))
969 image
= (cairo_image_surface_t
*) cairo_image_surface_create
970 (format
, ximage
->width
, ximage
->height
);
971 status
= image
->base
.status
;
972 if (unlikely (status
))
975 data
= cairo_image_surface_get_data (&image
->base
);
976 rowstride
= cairo_image_surface_get_stride (&image
->base
) >> 2;
977 row
= (uint32_t *) data
;
978 x0
= extents
->x
+ surface
->base
.device_transform
.x0
;
979 y0
= extents
->y
+ surface
->base
.device_transform
.y0
;
980 for (y
= 0, y_off
= y0
% ARRAY_LENGTH (dither_pattern
);
982 y
++, y_off
= (y_off
+1) % ARRAY_LENGTH (dither_pattern
)) {
983 const int8_t *dither_row
= dither_pattern
[y_off
];
984 for (x
= 0, x_off
= x0
% ARRAY_LENGTH (dither_pattern
[0]);
986 x
++, x_off
= (x_off
+1) % ARRAY_LENGTH (dither_pattern
[0])) {
987 int dither_adjustment
= dither_row
[x_off
];
989 in_pixel
= XGetPixel (ximage
, x
, y
);
990 if (visual_info
== NULL
) {
992 _field_to_8 (in_pixel
& a_mask
, a_width
, a_shift
) << 24 |
993 _field_to_8_undither (in_pixel
& r_mask
, r_width
, r_shift
, dither_adjustment
) << 16 |
994 _field_to_8_undither (in_pixel
& g_mask
, g_width
, g_shift
, dither_adjustment
) << 8 |
995 _field_to_8_undither (in_pixel
& b_mask
, b_width
, b_shift
, dither_adjustment
));
997 /* Undithering pseudocolor does not look better */
998 out_pixel
= _pseudocolor_to_rgb888 (visual_info
, in_pixel
);
1004 cairo_surface_mark_dirty (&image
->base
);
1009 XDestroyImage (ximage
);
1011 cairo_device_release (&display
->base
);
1013 if (unlikely (status
)) {
1014 cairo_surface_destroy (&image
->base
);
1015 return _cairo_surface_create_in_error (status
);
1018 return &image
->base
;
1022 _cairo_xlib_surface_set_precision (cairo_xlib_surface_t
*surface
,
1023 cairo_antialias_t antialias
)
1025 cairo_xlib_display_t
*display
= surface
->display
;
1028 if (display
->force_precision
!= -1)
1029 precision
= display
->force_precision
;
1030 else switch (antialias
) {
1032 case CAIRO_ANTIALIAS_DEFAULT
:
1033 case CAIRO_ANTIALIAS_GRAY
:
1034 case CAIRO_ANTIALIAS_NONE
:
1035 case CAIRO_ANTIALIAS_FAST
:
1036 case CAIRO_ANTIALIAS_GOOD
:
1037 precision
= PolyModeImprecise
;
1039 case CAIRO_ANTIALIAS_BEST
:
1040 case CAIRO_ANTIALIAS_SUBPIXEL
:
1041 precision
= PolyModePrecise
;
1045 if (surface
->precision
!= precision
) {
1046 XRenderPictureAttributes pa
;
1048 pa
.poly_mode
= precision
;
1049 XRenderChangePicture (display
->display
, surface
->picture
,
1052 surface
->precision
= precision
;
1057 _cairo_xlib_surface_ensure_picture (cairo_xlib_surface_t
*surface
)
1059 cairo_xlib_display_t
*display
= surface
->display
;
1060 XRenderPictureAttributes pa
;
1063 if (surface
->picture
)
1066 if (display
->force_precision
!= -1)
1067 pa
.poly_mode
= display
->force_precision
;
1069 pa
.poly_mode
= PolyModeImprecise
;
1073 surface
->precision
= pa
.poly_mode
;
1074 surface
->picture
= XRenderCreatePicture (display
->display
,
1076 surface
->xrender_format
,
1081 _cairo_xlib_surface_draw_image (cairo_xlib_surface_t
*surface
,
1082 cairo_image_surface_t
*image
,
1090 cairo_xlib_display_t
*display
;
1092 cairo_format_masks_t image_masks
;
1093 int native_byte_order
= _cairo_is_little_endian () ? LSBFirst
: MSBFirst
;
1094 cairo_surface_t
*shm_image
= NULL
;
1095 pixman_image_t
*pixman_image
= NULL
;
1096 cairo_status_t status
;
1097 cairo_bool_t own_data
= FALSE
;
1098 cairo_bool_t is_rgb_image
;
1101 ximage
.width
= image
->width
;
1102 ximage
.height
= image
->height
;
1103 ximage
.format
= ZPixmap
;
1104 ximage
.byte_order
= native_byte_order
;
1105 ximage
.bitmap_unit
= 32; /* always for libpixman */
1106 ximage
.bitmap_bit_order
= native_byte_order
;
1107 ximage
.bitmap_pad
= 32; /* always for libpixman */
1108 ximage
.depth
= surface
->depth
;
1109 ximage
.red_mask
= surface
->r_mask
;
1110 ximage
.green_mask
= surface
->g_mask
;
1111 ximage
.blue_mask
= surface
->b_mask
;
1113 ximage
.obdata
= NULL
;
1115 status
= _cairo_xlib_display_acquire (surface
->base
.device
, &display
);
1116 if (unlikely (status
))
1119 is_rgb_image
= _pixman_format_to_masks (image
->pixman_format
, &image_masks
);
1122 (image_masks
.alpha_mask
== surface
->a_mask
|| surface
->a_mask
== 0) &&
1123 (image_masks
.red_mask
== surface
->r_mask
|| surface
->r_mask
== 0) &&
1124 (image_masks
.green_mask
== surface
->g_mask
|| surface
->g_mask
== 0) &&
1125 (image_masks
.blue_mask
== surface
->b_mask
|| surface
->b_mask
== 0))
1129 ximage
.bits_per_pixel
= image_masks
.bpp
;
1130 ximage
.bytes_per_line
= image
->stride
;
1131 ximage
.data
= (char *)image
->data
;
1132 if (image
->base
.device
!= surface
->base
.device
) {
1133 /* If PutImage will break the image up into chunks, prefer to
1134 * send it all in one pass with ShmPutImage. For larger images,
1135 * it is further advantageous to reduce the number of copies,
1136 * albeit at the expense of more SHM bookkeeping.
1138 int max_request_size
= XExtendedMaxRequestSize (display
->display
);
1139 if (max_request_size
== 0)
1140 max_request_size
= XMaxRequestSize (display
->display
);
1141 if (max_request_size
> 8192)
1142 max_request_size
= 8192;
1143 if (width
* height
* 4 > max_request_size
) {
1144 shm_image
= _cairo_xlib_surface_create_shm__image (surface
,
1145 image
->pixman_format
,
1147 if (shm_image
&& shm_image
->status
== CAIRO_STATUS_SUCCESS
) {
1148 cairo_image_surface_t
*clone
= (cairo_image_surface_t
*) shm_image
;
1149 pixman_image_composite32 (PIXMAN_OP_SRC
,
1150 image
->pixman_image
, NULL
, clone
->pixman_image
,
1155 ximage
.obdata
= _cairo_xlib_shm_surface_get_obdata (shm_image
);
1156 ximage
.data
= (char *)clone
->data
;
1157 ximage
.bytes_per_line
= clone
->stride
;
1158 ximage
.width
= width
;
1159 ximage
.height
= height
;
1164 ximage
.obdata
= _cairo_xlib_shm_surface_get_obdata (&image
->base
);
1166 ret
= XInitImage (&ximage
);
1169 else if (surface
->visual
== NULL
|| surface
->visual
->class == TrueColor
)
1171 pixman_format_code_t intermediate_format
;
1174 image_masks
.alpha_mask
= surface
->a_mask
;
1175 image_masks
.red_mask
= surface
->r_mask
;
1176 image_masks
.green_mask
= surface
->g_mask
;
1177 image_masks
.blue_mask
= surface
->b_mask
;
1178 image_masks
.bpp
= bits_per_pixel (surface
);
1179 ret
= _pixman_format_from_masks (&image_masks
, &intermediate_format
);
1182 shm_image
= _cairo_xlib_surface_create_shm__image (surface
,
1183 intermediate_format
,
1185 if (shm_image
&& shm_image
->status
== CAIRO_STATUS_SUCCESS
) {
1186 cairo_image_surface_t
*clone
= (cairo_image_surface_t
*) shm_image
;
1188 pixman_image_composite32 (PIXMAN_OP_SRC
,
1189 image
->pixman_image
,
1191 clone
->pixman_image
,
1197 ximage
.data
= (char *) clone
->data
;
1198 ximage
.obdata
= _cairo_xlib_shm_surface_get_obdata (&clone
->base
);
1199 ximage
.bytes_per_line
= clone
->stride
;
1201 pixman_image
= pixman_image_create_bits (intermediate_format
,
1202 width
, height
, NULL
, 0);
1203 if (pixman_image
== NULL
) {
1204 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1208 pixman_image_composite32 (PIXMAN_OP_SRC
,
1209 image
->pixman_image
,
1217 ximage
.data
= (char *) pixman_image_get_data (pixman_image
);
1218 ximage
.bytes_per_line
= pixman_image_get_stride (pixman_image
);
1221 ximage
.width
= width
;
1222 ximage
.height
= height
;
1223 ximage
.bits_per_pixel
= image_masks
.bpp
;
1225 ret
= XInitImage (&ximage
);
1232 unsigned int stride
, rowstride
;
1233 int x
, y
, x0
, y0
, x_off
, y_off
;
1234 uint32_t in_pixel
, out_pixel
, *row
;
1235 int i_a_width
=0, i_r_width
=0, i_g_width
=0, i_b_width
=0;
1236 int i_a_shift
=0, i_r_shift
=0, i_g_shift
=0, i_b_shift
=0;
1237 int o_a_width
=0, o_r_width
=0, o_g_width
=0, o_b_width
=0;
1238 int o_a_shift
=0, o_r_shift
=0, o_g_shift
=0, o_b_shift
=0;
1239 cairo_xlib_visual_info_t
*visual_info
= NULL
;
1240 cairo_bool_t true_color
;
1243 ximage
.bits_per_pixel
= bits_per_pixel(surface
);
1244 stride
= CAIRO_STRIDE_FOR_WIDTH_BPP (ximage
.width
,
1245 ximage
.bits_per_pixel
);
1246 ximage
.bytes_per_line
= stride
;
1247 ximage
.data
= _cairo_malloc_ab (stride
, ximage
.height
);
1248 if (unlikely (ximage
.data
== NULL
)) {
1249 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1255 ret
= XInitImage (&ximage
);
1258 _characterize_field (image_masks
.alpha_mask
, &i_a_width
, &i_a_shift
);
1259 _characterize_field (image_masks
.red_mask
, &i_r_width
, &i_r_shift
);
1260 _characterize_field (image_masks
.green_mask
, &i_g_width
, &i_g_shift
);
1261 _characterize_field (image_masks
.blue_mask
, &i_b_width
, &i_b_shift
);
1263 true_color
= surface
->visual
== NULL
||
1264 surface
->visual
->class == TrueColor
;
1266 _characterize_field (surface
->a_mask
, &o_a_width
, &o_a_shift
);
1267 _characterize_field (surface
->r_mask
, &o_r_width
, &o_r_shift
);
1268 _characterize_field (surface
->g_mask
, &o_g_width
, &o_g_shift
);
1269 _characterize_field (surface
->b_mask
, &o_b_width
, &o_b_shift
);
1271 status
= _cairo_xlib_screen_get_visual_info (display
,
1275 if (unlikely (status
))
1279 rowstride
= image
->stride
>> 2;
1280 row
= (uint32_t *) image
->data
;
1281 x0
= dst_x
+ surface
->base
.device_transform
.x0
;
1282 y0
= dst_y
+ surface
->base
.device_transform
.y0
;
1283 for (y
= 0, y_off
= y0
% ARRAY_LENGTH (dither_pattern
);
1285 y
++, y_off
= (y_off
+1) % ARRAY_LENGTH (dither_pattern
))
1287 const int8_t *dither_row
= dither_pattern
[y_off
];
1289 for (x
= 0, x_off
= x0
% ARRAY_LENGTH (dither_pattern
[0]);
1291 x
++, x_off
= (x_off
+1) % ARRAY_LENGTH (dither_pattern
[0]))
1293 int dither_adjustment
= dither_row
[x_off
];
1296 if (image_masks
.bpp
== 1)
1297 in_pixel
= !! (((uint8_t*)row
)[x
/8] & (1 << (x
& 7)));
1298 else if (image_masks
.bpp
<= 8)
1299 in_pixel
= ((uint8_t*)row
)[x
];
1300 else if (image_masks
.bpp
<= 16)
1301 in_pixel
= ((uint16_t*)row
)[x
];
1302 else if (image_masks
.bpp
<= 24)
1303 #ifdef WORDS_BIGENDIAN
1304 in_pixel
= ((uint8_t*)row
)[3 * x
] << 16 |
1305 ((uint8_t*)row
)[3 * x
+ 1] << 8 |
1306 ((uint8_t*)row
)[3 * x
+ 2];
1308 in_pixel
= ((uint8_t*)row
)[3 * x
] |
1309 ((uint8_t*)row
)[3 * x
+ 1] << 8 |
1310 ((uint8_t*)row
)[3 * x
+ 2] << 16;
1315 /* If the incoming image has no alpha channel, then the input
1316 * is opaque and the output should have the maximum alpha value.
1317 * For all other channels, their absence implies 0.
1319 if (image_masks
.alpha_mask
== 0x0)
1322 a
= _field_to_8 (in_pixel
& image_masks
.alpha_mask
, i_a_width
, i_a_shift
);
1323 r
= _field_to_8 (in_pixel
& image_masks
.red_mask
, i_r_width
, i_r_shift
);
1324 g
= _field_to_8 (in_pixel
& image_masks
.green_mask
, i_g_width
, i_g_shift
);
1325 b
= _field_to_8 (in_pixel
& image_masks
.blue_mask
, i_b_width
, i_b_shift
);
1328 out_pixel
= _field_from_8 (a
, o_a_width
, o_a_shift
) |
1329 _field_from_8_dither (r
, o_r_width
, o_r_shift
, dither_adjustment
) |
1330 _field_from_8_dither (g
, o_g_width
, o_g_shift
, dither_adjustment
) |
1331 _field_from_8_dither (b
, o_b_width
, o_b_shift
, dither_adjustment
);
1333 out_pixel
= _pseudocolor_from_rgb888_dither (visual_info
, r
, g
, b
, dither_adjustment
);
1336 XPutPixel (&ximage
, x
, y
, out_pixel
);
1343 status
= _cairo_xlib_surface_get_gc (display
, surface
, &gc
);
1344 if (unlikely (status
))
1348 XShmPutImage (display
->display
, surface
->drawable
, gc
, &ximage
,
1349 src_x
, src_y
, dst_x
, dst_y
, width
, height
, True
);
1351 XPutImage (display
->display
, surface
->drawable
, gc
, &ximage
,
1352 src_x
, src_y
, dst_x
, dst_y
, width
, height
);
1354 _cairo_xlib_surface_put_gc (display
, surface
, gc
);
1357 cairo_device_release (&display
->base
);
1362 cairo_surface_destroy (shm_image
);
1364 pixman_image_unref (pixman_image
);
1366 return CAIRO_STATUS_SUCCESS
;
1369 static cairo_surface_t
*
1370 _cairo_xlib_surface_source(void *abstract_surface
,
1371 cairo_rectangle_int_t
*extents
)
1373 cairo_xlib_surface_t
*surface
= abstract_surface
;
1376 extents
->x
= extents
->y
= 0;
1377 extents
->width
= surface
->width
;
1378 extents
->height
= surface
->height
;
1381 return &surface
->base
;
1384 static cairo_status_t
1385 _cairo_xlib_surface_acquire_source_image (void *abstract_surface
,
1386 cairo_image_surface_t
**image_out
,
1389 cairo_xlib_surface_t
*surface
= abstract_surface
;
1390 cairo_rectangle_int_t extents
;
1392 *image_extra
= NULL
;
1393 *image_out
= (cairo_image_surface_t
*)
1394 _cairo_xlib_surface_get_shm (abstract_surface
, FALSE
);
1396 return (*image_out
)->base
.status
;
1398 extents
.x
= extents
.y
= 0;
1399 extents
.width
= surface
->width
;
1400 extents
.height
= surface
->height
;
1402 *image_out
= (cairo_image_surface_t
*)
1403 _get_image_surface (surface
, &extents
, TRUE
);
1404 return (*image_out
)->base
.status
;
1407 static cairo_surface_t
*
1408 _cairo_xlib_surface_snapshot (void *abstract_surface
)
1410 cairo_xlib_surface_t
*surface
= abstract_surface
;
1411 cairo_rectangle_int_t extents
;
1413 extents
.x
= extents
.y
= 0;
1414 extents
.width
= surface
->width
;
1415 extents
.height
= surface
->height
;
1417 return _get_image_surface (surface
, &extents
, FALSE
);
1421 _cairo_xlib_surface_release_source_image (void *abstract_surface
,
1422 cairo_image_surface_t
*image
,
1425 cairo_xlib_surface_t
*surface
= abstract_surface
;
1427 if (&image
->base
== surface
->shm
)
1430 cairo_surface_destroy (&image
->base
);
1433 static cairo_image_surface_t
*
1434 _cairo_xlib_surface_map_to_image (void *abstract_surface
,
1435 const cairo_rectangle_int_t
*extents
)
1437 cairo_xlib_surface_t
*surface
= abstract_surface
;
1438 cairo_surface_t
*image
;
1440 image
= _cairo_xlib_surface_get_shm (abstract_surface
, FALSE
);
1442 assert (surface
->base
.damage
);
1443 surface
->fallback
++;
1444 return _cairo_image_surface_map_to_image (image
, extents
);
1447 image
= _get_image_surface (abstract_surface
, extents
, TRUE
);
1448 cairo_surface_set_device_offset (image
, -extents
->x
, -extents
->y
);
1450 return (cairo_image_surface_t
*) image
;
1453 static cairo_int_status_t
1454 _cairo_xlib_surface_unmap_image (void *abstract_surface
,
1455 cairo_image_surface_t
*image
)
1457 cairo_xlib_surface_t
*surface
= abstract_surface
;
1458 cairo_int_status_t status
;
1461 cairo_rectangle_int_t r
;
1463 assert (surface
->fallback
);
1464 assert (surface
->base
.damage
);
1466 r
.x
= image
->base
.device_transform_inverse
.x0
;
1467 r
.y
= image
->base
.device_transform_inverse
.y0
;
1468 r
.width
= image
->width
;
1469 r
.height
= image
->height
;
1471 TRACE ((stderr
, "%s: adding damage (%d,%d)x(%d,%d)\n",
1472 __FUNCTION__
, r
.x
, r
.y
, r
.width
, r
.height
));
1473 surface
->shm
->damage
=
1474 _cairo_damage_add_rectangle (surface
->shm
->damage
, &r
);
1476 return _cairo_image_surface_unmap_image (surface
->shm
, image
);
1479 status
= _cairo_xlib_surface_draw_image (abstract_surface
, image
,
1481 image
->width
, image
->height
,
1482 image
->base
.device_transform_inverse
.x0
,
1483 image
->base
.device_transform_inverse
.y0
);
1485 cairo_surface_finish (&image
->base
);
1486 cairo_surface_destroy (&image
->base
);
1491 static cairo_status_t
1492 _cairo_xlib_surface_flush (void *abstract_surface
,
1495 cairo_xlib_surface_t
*surface
= abstract_surface
;
1496 cairo_int_status_t status
;
1499 return CAIRO_STATUS_SUCCESS
;
1501 status
= _cairo_xlib_surface_put_shm (surface
);
1502 if (unlikely (status
))
1505 surface
->fallback
>>= 1;
1506 if (surface
->shm
&& _cairo_xlib_shm_surface_is_idle (surface
->shm
))
1507 _cairo_xlib_surface_discard_shm (surface
);
1509 return CAIRO_STATUS_SUCCESS
;
1513 _cairo_xlib_surface_get_extents (void *abstract_surface
,
1514 cairo_rectangle_int_t
*rectangle
)
1516 cairo_xlib_surface_t
*surface
= abstract_surface
;
1521 rectangle
->width
= surface
->width
;
1522 rectangle
->height
= surface
->height
;
1528 _cairo_xlib_surface_get_font_options (void *abstract_surface
,
1529 cairo_font_options_t
*options
)
1531 cairo_xlib_surface_t
*surface
= abstract_surface
;
1533 *options
= *_cairo_xlib_screen_get_font_options (surface
->screen
);
1536 static inline cairo_int_status_t
1537 get_compositor (cairo_xlib_surface_t
**surface
,
1538 const cairo_compositor_t
**compositor
)
1540 cairo_xlib_surface_t
*s
= *surface
;
1541 cairo_int_status_t status
= CAIRO_INT_STATUS_SUCCESS
;;
1544 assert (s
->base
.damage
!= NULL
);
1545 assert (s
->shm
!= NULL
);
1546 assert (s
->shm
->damage
!= NULL
);
1547 if (! _cairo_xlib_shm_surface_is_active (s
->shm
)) {
1548 *surface
= (cairo_xlib_surface_t
*) s
->shm
;
1549 *compositor
= ((cairo_image_surface_t
*) s
->shm
)->compositor
;
1552 status
= _cairo_xlib_surface_put_shm (s
);
1554 *compositor
= s
->compositor
;
1557 *compositor
= s
->compositor
;
1562 static cairo_int_status_t
1563 _cairo_xlib_surface_paint (void *_surface
,
1564 cairo_operator_t op
,
1565 const cairo_pattern_t
*source
,
1566 const cairo_clip_t
*clip
)
1568 cairo_xlib_surface_t
*surface
= _surface
;
1569 const cairo_compositor_t
*compositor
;
1570 cairo_int_status_t status
;
1572 status
= get_compositor (&surface
, &compositor
);
1573 if (unlikely (status
))
1576 return _cairo_compositor_paint (compositor
, &surface
->base
,
1581 static cairo_int_status_t
1582 _cairo_xlib_surface_mask (void *_surface
,
1583 cairo_operator_t op
,
1584 const cairo_pattern_t
*source
,
1585 const cairo_pattern_t
*mask
,
1586 const cairo_clip_t
*clip
)
1588 cairo_xlib_surface_t
*surface
= _surface
;
1589 const cairo_compositor_t
*compositor
;
1590 cairo_int_status_t status
;
1592 status
= get_compositor (&surface
, &compositor
);
1593 if (unlikely (status
))
1596 return _cairo_compositor_mask (compositor
, &surface
->base
,
1601 static cairo_int_status_t
1602 _cairo_xlib_surface_stroke (void *_surface
,
1603 cairo_operator_t op
,
1604 const cairo_pattern_t
*source
,
1605 const cairo_path_fixed_t
*path
,
1606 const cairo_stroke_style_t
*style
,
1607 const cairo_matrix_t
*ctm
,
1608 const cairo_matrix_t
*ctm_inverse
,
1610 cairo_antialias_t antialias
,
1611 const cairo_clip_t
*clip
)
1613 cairo_xlib_surface_t
*surface
= _surface
;
1614 const cairo_compositor_t
*compositor
;
1615 cairo_int_status_t status
;
1617 status
= get_compositor (&surface
, &compositor
);
1618 if (unlikely (status
))
1621 return _cairo_compositor_stroke (compositor
, &surface
->base
,
1623 path
, style
, ctm
, ctm_inverse
,
1624 tolerance
, antialias
,
1628 static cairo_int_status_t
1629 _cairo_xlib_surface_fill (void *_surface
,
1630 cairo_operator_t op
,
1631 const cairo_pattern_t
*source
,
1632 const cairo_path_fixed_t
*path
,
1633 cairo_fill_rule_t fill_rule
,
1635 cairo_antialias_t antialias
,
1636 const cairo_clip_t
*clip
)
1638 cairo_xlib_surface_t
*surface
= _surface
;
1639 const cairo_compositor_t
*compositor
;
1640 cairo_int_status_t status
;
1642 status
= get_compositor (&surface
, &compositor
);
1643 if (unlikely (status
))
1646 return _cairo_compositor_fill (compositor
, &surface
->base
,
1648 path
, fill_rule
, tolerance
, antialias
,
1652 static cairo_int_status_t
1653 _cairo_xlib_surface_glyphs (void *_surface
,
1654 cairo_operator_t op
,
1655 const cairo_pattern_t
*source
,
1656 cairo_glyph_t
*glyphs
,
1658 cairo_scaled_font_t
*scaled_font
,
1659 const cairo_clip_t
*clip
)
1661 cairo_xlib_surface_t
*surface
= _surface
;
1662 const cairo_compositor_t
*compositor
;
1663 cairo_int_status_t status
;
1665 status
= get_compositor (&surface
, &compositor
);
1666 if (unlikely (status
))
1669 return _cairo_compositor_glyphs (compositor
, &surface
->base
,
1671 glyphs
, num_glyphs
, scaled_font
,
1675 static const cairo_surface_backend_t cairo_xlib_surface_backend
= {
1676 CAIRO_SURFACE_TYPE_XLIB
,
1677 _cairo_xlib_surface_finish
,
1679 _cairo_default_context_create
,
1681 _cairo_xlib_surface_create_similar
,
1682 _cairo_xlib_surface_create_similar_shm
,
1683 _cairo_xlib_surface_map_to_image
,
1684 _cairo_xlib_surface_unmap_image
,
1686 _cairo_xlib_surface_source
,
1687 _cairo_xlib_surface_acquire_source_image
,
1688 _cairo_xlib_surface_release_source_image
,
1689 _cairo_xlib_surface_snapshot
,
1691 NULL
, /* copy_page */
1692 NULL
, /* show_page */
1694 _cairo_xlib_surface_get_extents
,
1695 _cairo_xlib_surface_get_font_options
,
1697 _cairo_xlib_surface_flush
,
1698 NULL
, /* mark_dirty_rectangle */
1700 _cairo_xlib_surface_paint
,
1701 _cairo_xlib_surface_mask
,
1702 _cairo_xlib_surface_stroke
,
1703 _cairo_xlib_surface_fill
,
1704 NULL
, /* fill-stroke */
1705 _cairo_xlib_surface_glyphs
,
1709 * _cairo_surface_is_xlib:
1710 * @surface: a #cairo_surface_t
1712 * Checks if a surface is a #cairo_xlib_surface_t
1714 * Return value: True if the surface is an xlib surface
1717 _cairo_surface_is_xlib (cairo_surface_t
*surface
)
1719 return surface
->backend
== &cairo_xlib_surface_backend
;
1722 static cairo_surface_t
*
1723 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t
*screen
,
1726 XRenderPictFormat
*xrender_format
,
1731 cairo_xlib_surface_t
*surface
;
1732 cairo_xlib_display_t
*display
;
1733 cairo_status_t status
;
1736 if (xrender_format
) {
1737 depth
= xrender_format
->depth
;
1739 /* XXX find matching visual for core/dithering fallbacks? */
1740 } else if (visual
) {
1741 Screen
*scr
= screen
->screen
;
1743 if (visual
== DefaultVisualOfScreen (scr
)) {
1744 depth
= DefaultDepthOfScreen (scr
);
1748 /* This is ugly, but we have to walk over all visuals
1749 * for the display to find the correct depth.
1752 for (j
= 0; j
< scr
->ndepths
; j
++) {
1753 Depth
*d
= &scr
->depths
[j
];
1754 for (k
= 0; k
< d
->nvisuals
; k
++) {
1755 if (&d
->visuals
[k
] == visual
) {
1765 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL
));
1771 surface
= malloc (sizeof (cairo_xlib_surface_t
));
1772 if (unlikely (surface
== NULL
))
1773 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY
));
1775 status
= _cairo_xlib_display_acquire (screen
->device
, &display
);
1776 if (unlikely (status
)) {
1778 return _cairo_surface_create_in_error (_cairo_error (status
));
1781 surface
->display
= display
;
1782 if (CAIRO_RENDER_HAS_CREATE_PICTURE (display
)) {
1783 if (!xrender_format
) {
1785 xrender_format
= XRenderFindVisualFormat (display
->display
, visual
);
1786 } else if (depth
== 1) {
1788 _cairo_xlib_display_get_xrender_format (display
,
1794 cairo_device_release (&display
->base
);
1796 _cairo_surface_init (&surface
->base
,
1797 &cairo_xlib_surface_backend
,
1799 _xrender_format_to_content (xrender_format
));
1801 surface
->screen
= screen
;
1802 surface
->compositor
= display
->compositor
;
1803 surface
->shm
= NULL
;
1804 surface
->fallback
= 0;
1806 surface
->drawable
= drawable
;
1807 surface
->owns_pixmap
= FALSE
;
1808 surface
->use_pixmap
= 0;
1809 surface
->width
= width
;
1810 surface
->height
= height
;
1812 surface
->picture
= None
;
1813 surface
->precision
= PolyModePrecise
;
1815 surface
->embedded_source
.picture
= None
;
1817 surface
->visual
= visual
;
1818 surface
->xrender_format
= xrender_format
;
1819 surface
->depth
= depth
;
1822 * Compute the pixel format masks from either a XrenderFormat or
1823 * else from a visual; failing that we assume the drawable is an
1824 * alpha-only pixmap as it could only have been created that way
1825 * through the cairo_xlib_surface_create_for_bitmap function.
1827 if (xrender_format
) {
1828 surface
->a_mask
= (unsigned long)
1829 surface
->xrender_format
->direct
.alphaMask
1830 << surface
->xrender_format
->direct
.alpha
;
1831 surface
->r_mask
= (unsigned long)
1832 surface
->xrender_format
->direct
.redMask
1833 << surface
->xrender_format
->direct
.red
;
1834 surface
->g_mask
= (unsigned long)
1835 surface
->xrender_format
->direct
.greenMask
1836 << surface
->xrender_format
->direct
.green
;
1837 surface
->b_mask
= (unsigned long)
1838 surface
->xrender_format
->direct
.blueMask
1839 << surface
->xrender_format
->direct
.blue
;
1840 } else if (visual
) {
1841 surface
->a_mask
= 0;
1842 surface
->r_mask
= visual
->red_mask
;
1843 surface
->g_mask
= visual
->green_mask
;
1844 surface
->b_mask
= visual
->blue_mask
;
1847 surface
->a_mask
= (1 << depth
) - 1;
1849 surface
->a_mask
= 0xffffffff;
1850 surface
->r_mask
= 0;
1851 surface
->g_mask
= 0;
1852 surface
->b_mask
= 0;
1855 cairo_list_add (&surface
->link
, &screen
->surfaces
);
1857 return &surface
->base
;
1861 _cairo_xlib_screen_from_visual (Display
*dpy
, Visual
*visual
)
1865 for (s
= 0; s
< ScreenCount (dpy
); s
++) {
1868 screen
= ScreenOfDisplay (dpy
, s
);
1869 if (visual
== DefaultVisualOfScreen (screen
))
1872 for (d
= 0; d
< screen
->ndepths
; d
++) {
1875 depth
= &screen
->depths
[d
];
1876 for (v
= 0; v
< depth
->nvisuals
; v
++)
1877 if (visual
== &depth
->visuals
[v
])
1885 static cairo_bool_t
valid_size (int width
, int height
)
1887 /* Note: the minimum surface size allowed in the X protocol is 1x1.
1888 * However, as we historically did not check the minimum size we
1889 * allowed applications to lie and set the correct size later (one hopes).
1890 * To preserve compatability we must allow applications to use
1893 return (width
>= 0 && width
<= XLIB_COORD_MAX
&&
1894 height
>= 0 && height
<= XLIB_COORD_MAX
);
1898 * cairo_xlib_surface_create:
1899 * @dpy: an X Display
1900 * @drawable: an X Drawable, (a Pixmap or a Window)
1901 * @visual: the visual to use for drawing to @drawable. The depth
1902 * of the visual must match the depth of the drawable.
1903 * Currently, only TrueColor visuals are fully supported.
1904 * @width: the current width of @drawable.
1905 * @height: the current height of @drawable.
1907 * Creates an Xlib surface that draws to the given drawable.
1908 * The way that colors are represented in the drawable is specified
1909 * by the provided visual.
1911 * Note: If @drawable is a Window, then the function
1912 * cairo_xlib_surface_set_size() must be called whenever the size of the
1915 * When @drawable is a Window containing child windows then drawing to
1916 * the created surface will be clipped by those child windows. When
1917 * the created surface is used as a source, the contents of the
1918 * children will be included.
1920 * Return value: the newly created surface
1925 cairo_xlib_surface_create (Display
*dpy
,
1932 cairo_xlib_screen_t
*screen
;
1933 cairo_status_t status
;
1935 if (! valid_size (width
, height
)) {
1936 /* you're lying, and you know it! */
1937 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE
));
1940 scr
= _cairo_xlib_screen_from_visual (dpy
, visual
);
1942 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL
));
1944 status
= _cairo_xlib_screen_get (dpy
, scr
, &screen
);
1945 if (unlikely (status
))
1946 return _cairo_surface_create_in_error (status
);
1948 X_DEBUG ((dpy
, "create (drawable=%x)", (unsigned int) drawable
));
1950 return _cairo_xlib_surface_create_internal (screen
, drawable
,
1956 * cairo_xlib_surface_create_for_bitmap:
1957 * @dpy: an X Display
1958 * @bitmap: an X Drawable, (a depth-1 Pixmap)
1959 * @screen: the X Screen associated with @bitmap
1960 * @width: the current width of @bitmap.
1961 * @height: the current height of @bitmap.
1963 * Creates an Xlib surface that draws to the given bitmap.
1964 * This will be drawn to as a %CAIRO_FORMAT_A1 object.
1966 * Return value: the newly created surface
1971 cairo_xlib_surface_create_for_bitmap (Display
*dpy
,
1977 cairo_xlib_screen_t
*screen
;
1978 cairo_status_t status
;
1980 if (! valid_size (width
, height
))
1981 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE
));
1983 status
= _cairo_xlib_screen_get (dpy
, scr
, &screen
);
1984 if (unlikely (status
))
1985 return _cairo_surface_create_in_error (status
);
1987 X_DEBUG ((dpy
, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap
));
1989 return _cairo_xlib_surface_create_internal (screen
, bitmap
,
1994 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
1996 * cairo_xlib_surface_create_with_xrender_format:
1997 * @dpy: an X Display
1998 * @drawable: an X Drawable, (a Pixmap or a Window)
1999 * @screen: the X Screen associated with @drawable
2000 * @format: the picture format to use for drawing to @drawable. The depth
2001 * of @format must match the depth of the drawable.
2002 * @width: the current width of @drawable.
2003 * @height: the current height of @drawable.
2005 * Creates an Xlib surface that draws to the given drawable.
2006 * The way that colors are represented in the drawable is specified
2007 * by the provided picture format.
2009 * Note: If @drawable is a Window, then the function
2010 * cairo_xlib_surface_set_size() must be called whenever the size of the
2013 * Return value: the newly created surface
2018 cairo_xlib_surface_create_with_xrender_format (Display
*dpy
,
2021 XRenderPictFormat
*format
,
2025 cairo_xlib_screen_t
*screen
;
2026 cairo_status_t status
;
2028 if (! valid_size (width
, height
))
2029 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE
));
2031 status
= _cairo_xlib_screen_get (dpy
, scr
, &screen
);
2032 if (unlikely (status
))
2033 return _cairo_surface_create_in_error (status
);
2035 X_DEBUG ((dpy
, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable
));
2037 return _cairo_xlib_surface_create_internal (screen
, drawable
,
2038 _visual_for_xrender_format (scr
, format
),
2039 format
, width
, height
, 0);
2043 * cairo_xlib_surface_get_xrender_format:
2044 * @surface: an xlib surface
2046 * Gets the X Render picture format that @surface uses for rendering with the
2047 * X Render extension. If the surface was created by
2048 * cairo_xlib_surface_create_with_xrender_format() originally, the return
2049 * value is the format passed to that constructor.
2051 * Return value: the XRenderPictFormat* associated with @surface,
2052 * or %NULL if the surface is not an xlib surface
2053 * or if the X Render extension is not available.
2058 cairo_xlib_surface_get_xrender_format (cairo_surface_t
*surface
)
2060 cairo_xlib_surface_t
*xlib_surface
= (cairo_xlib_surface_t
*) surface
;
2062 /* Throw an error for a non-xlib surface */
2063 if (! _cairo_surface_is_xlib (surface
)) {
2064 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2068 return xlib_surface
->xrender_format
;
2073 * cairo_xlib_surface_set_size:
2074 * @surface: a #cairo_surface_t for the XLib backend
2075 * @width: the new width of the surface
2076 * @height: the new height of the surface
2078 * Informs cairo of the new size of the X Drawable underlying the
2079 * surface. For a surface created for a Window (rather than a Pixmap),
2080 * this function must be called each time the size of the window
2081 * changes. (For a subwindow, you are normally resizing the window
2082 * yourself, but for a toplevel window, it is necessary to listen for
2083 * ConfigureNotify events.)
2085 * A Pixmap can never change size, so it is never necessary to call
2086 * this function on a surface created for a Pixmap.
2091 cairo_xlib_surface_set_size (cairo_surface_t
*abstract_surface
,
2095 cairo_xlib_surface_t
*surface
= (cairo_xlib_surface_t
*) abstract_surface
;
2096 cairo_status_t status
;
2098 if (unlikely (abstract_surface
->status
))
2100 if (unlikely (abstract_surface
->finished
)) {
2101 _cairo_surface_set_error (abstract_surface
,
2102 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED
));
2106 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2107 _cairo_surface_set_error (abstract_surface
,
2108 _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
));
2112 if (surface
->width
== width
&& surface
->height
== height
)
2115 if (! valid_size (width
, height
)) {
2116 _cairo_surface_set_error (abstract_surface
,
2117 _cairo_error (CAIRO_STATUS_INVALID_SIZE
));
2121 status
= _cairo_surface_flush (abstract_surface
, 0);
2122 if (unlikely (status
)) {
2123 _cairo_surface_set_error (abstract_surface
, status
);
2127 _cairo_xlib_surface_discard_shm (surface
);
2129 surface
->width
= width
;
2130 surface
->height
= height
;
2134 * cairo_xlib_surface_set_drawable:
2135 * @surface: a #cairo_surface_t for the XLib backend
2136 * @drawable: the new drawable for the surface
2137 * @width: the width of the new drawable
2138 * @height: the height of the new drawable
2140 * Informs cairo of a new X Drawable underlying the
2141 * surface. The drawable must match the display, screen
2142 * and format of the existing drawable or the application
2143 * will get X protocol errors and will probably terminate.
2144 * No checks are done by this function to ensure this
2150 cairo_xlib_surface_set_drawable (cairo_surface_t
*abstract_surface
,
2155 cairo_xlib_surface_t
*surface
= (cairo_xlib_surface_t
*)abstract_surface
;
2156 cairo_status_t status
;
2158 if (unlikely (abstract_surface
->status
))
2160 if (unlikely (abstract_surface
->finished
)) {
2161 status
= _cairo_surface_set_error (abstract_surface
,
2162 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED
));
2166 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2167 status
= _cairo_surface_set_error (abstract_surface
,
2168 _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
));
2172 if (! valid_size (width
, height
)) {
2173 status
= _cairo_surface_set_error (abstract_surface
,
2174 _cairo_error (CAIRO_STATUS_INVALID_SIZE
));
2178 /* XXX: and what about this case? */
2179 if (surface
->owns_pixmap
)
2182 status
= _cairo_surface_flush (abstract_surface
, 0);
2183 if (unlikely (status
)) {
2184 _cairo_surface_set_error (abstract_surface
, status
);
2188 if (surface
->drawable
!= drawable
) {
2189 cairo_xlib_display_t
*display
;
2191 status
= _cairo_xlib_display_acquire (surface
->base
.device
, &display
);
2192 if (unlikely (status
))
2195 X_DEBUG ((display
->display
, "set_drawable (drawable=%x)", (unsigned int) drawable
));
2197 if (surface
->picture
!= None
) {
2198 XRenderFreePicture (display
->display
, surface
->picture
);
2199 if (unlikely (status
)) {
2200 status
= _cairo_surface_set_error (&surface
->base
, status
);
2204 surface
->picture
= None
;
2207 cairo_device_release (&display
->base
);
2209 surface
->drawable
= drawable
;
2212 if (surface
->width
!= width
|| surface
->height
!= height
) {
2213 _cairo_xlib_surface_discard_shm (surface
);
2215 surface
->width
= width
;
2216 surface
->height
= height
;
2221 * cairo_xlib_surface_get_display:
2222 * @surface: a #cairo_xlib_surface_t
2224 * Get the X Display for the underlying X Drawable.
2226 * Return value: the display.
2231 cairo_xlib_surface_get_display (cairo_surface_t
*abstract_surface
)
2233 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2234 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2238 return ((cairo_xlib_display_t
*) abstract_surface
->device
)->display
;
2242 * cairo_xlib_surface_get_drawable:
2243 * @surface: a #cairo_xlib_surface_t
2245 * Get the underlying X Drawable used for the surface.
2247 * Return value: the drawable.
2252 cairo_xlib_surface_get_drawable (cairo_surface_t
*abstract_surface
)
2254 cairo_xlib_surface_t
*surface
= (cairo_xlib_surface_t
*) abstract_surface
;
2256 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2257 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2261 return surface
->drawable
;
2265 * cairo_xlib_surface_get_screen:
2266 * @surface: a #cairo_xlib_surface_t
2268 * Get the X Screen for the underlying X Drawable.
2270 * Return value: the screen.
2275 cairo_xlib_surface_get_screen (cairo_surface_t
*abstract_surface
)
2277 cairo_xlib_surface_t
*surface
= (cairo_xlib_surface_t
*) abstract_surface
;
2279 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2280 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2284 return surface
->screen
->screen
;
2288 * cairo_xlib_surface_get_visual:
2289 * @surface: a #cairo_xlib_surface_t
2291 * Gets the X Visual associated with @surface, suitable for use with the
2292 * underlying X Drawable. If @surface was created by
2293 * cairo_xlib_surface_create(), the return value is the Visual passed to that
2296 * Return value: the Visual or %NULL if there is no appropriate Visual for
2302 cairo_xlib_surface_get_visual (cairo_surface_t
*surface
)
2304 cairo_xlib_surface_t
*xlib_surface
= (cairo_xlib_surface_t
*) surface
;
2306 if (! _cairo_surface_is_xlib (surface
)) {
2307 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2311 return xlib_surface
->visual
;
2315 * cairo_xlib_surface_get_depth:
2316 * @surface: a #cairo_xlib_surface_t
2318 * Get the number of bits used to represent each pixel value.
2320 * Return value: the depth of the surface in bits.
2325 cairo_xlib_surface_get_depth (cairo_surface_t
*abstract_surface
)
2327 cairo_xlib_surface_t
*surface
= (cairo_xlib_surface_t
*) abstract_surface
;
2329 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2330 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2334 return surface
->depth
;
2338 * cairo_xlib_surface_get_width:
2339 * @surface: a #cairo_xlib_surface_t
2341 * Get the width of the X Drawable underlying the surface in pixels.
2343 * Return value: the width of the surface in pixels.
2348 cairo_xlib_surface_get_width (cairo_surface_t
*abstract_surface
)
2350 cairo_xlib_surface_t
*surface
= (cairo_xlib_surface_t
*) abstract_surface
;
2352 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2353 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2357 return surface
->width
;
2361 * cairo_xlib_surface_get_height:
2362 * @surface: a #cairo_xlib_surface_t
2364 * Get the height of the X Drawable underlying the surface in pixels.
2366 * Return value: the height of the surface in pixels.
2371 cairo_xlib_surface_get_height (cairo_surface_t
*abstract_surface
)
2373 cairo_xlib_surface_t
*surface
= (cairo_xlib_surface_t
*) abstract_surface
;
2375 if (! _cairo_surface_is_xlib (abstract_surface
)) {
2376 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
2380 return surface
->height
;
2383 #endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */