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
cairo_surface_t *shm_image = NULL;
1094
pixman_image_t *pixman_image = NULL;
1095
cairo_status_t status;
1096
cairo_bool_t own_data = FALSE;
1097
cairo_bool_t is_rgb_image;
1100
ximage.width = image->width;
1101
ximage.height = image->height;
1102
ximage.format = ZPixmap;
1103
ximage.byte_order = native_byte_order;
1104
ximage.bitmap_unit = 32; /* always for libpixman */
1105
ximage.bitmap_bit_order = native_byte_order;
1106
ximage.bitmap_pad = 32; /* always for libpixman */
1107
ximage.depth = surface->depth;
1108
ximage.red_mask = surface->r_mask;
1109
ximage.green_mask = surface->g_mask;
1110
ximage.blue_mask = surface->b_mask;
1112
ximage.obdata = NULL;
1114
status = _cairo_xlib_display_acquire (surface->base.device, &display);
1115
if (unlikely (status))
1118
is_rgb_image = _pixman_format_to_masks (image->pixman_format, &image_masks);
1121
(image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) &&
1122
(image_masks.red_mask == surface->r_mask || surface->r_mask == 0) &&
1123
(image_masks.green_mask == surface->g_mask || surface->g_mask == 0) &&
1124
(image_masks.blue_mask == surface->b_mask || surface->b_mask == 0))
1128
ximage.bits_per_pixel = image_masks.bpp;
1129
ximage.bytes_per_line = image->stride;
1130
ximage.data = (char *)image->data;
1131
if (image->base.device != surface->base.device) {
1132
/* If PutImage will break the image up into chunks, prefer to
1133
* send it all in one pass with ShmPutImage. For larger images,
1134
* it is further advantageous to reduce the number of copies,
1135
* albeit at the expense of more SHM bookkeeping.
1137
int max_request_size = XExtendedMaxRequestSize (display->display);
1138
if (max_request_size == 0)
1139
max_request_size = XMaxRequestSize (display->display);
1140
if (max_request_size > 8192)
1141
max_request_size = 8192;
1142
if (image->stride * image->height > max_request_size) {
1143
shm_image = _cairo_xlib_surface_create_shm__image (surface,
1144
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
if (clone->stride == image->stride) {
1150
memcpy (clone->data, image->data, clone->stride * clone->height);
1152
pixman_image_composite32 (PIXMAN_OP_SRC,
1153
image->pixman_image, NULL, clone->pixman_image,
1157
image->width, image->height);
1159
ximage.obdata = _cairo_xlib_shm_surface_get_obdata (shm_image);
1160
ximage.data = (char *)clone->data;
1161
ximage.bytes_per_line = clone->stride;
1165
ximage.obdata = _cairo_xlib_shm_surface_get_obdata (&image->base);
1167
ret = XInitImage (&ximage);
1170
else if (surface->visual == NULL || surface->visual->class == TrueColor)
1172
pixman_format_code_t intermediate_format;
1175
image_masks.alpha_mask = surface->a_mask;
1176
image_masks.red_mask = surface->r_mask;
1177
image_masks.green_mask = surface->g_mask;
1178
image_masks.blue_mask = surface->b_mask;
1179
image_masks.bpp = bits_per_pixel (surface);
1180
ret = _pixman_format_from_masks (&image_masks, &intermediate_format);
1183
shm_image = _cairo_xlib_surface_create_shm__image (surface,
1184
intermediate_format,
1186
if (shm_image && shm_image->status == CAIRO_STATUS_SUCCESS) {
1187
cairo_image_surface_t *clone = (cairo_image_surface_t *) shm_image;
1189
pixman_image_composite32 (PIXMAN_OP_SRC,
1190
image->pixman_image,
1192
clone->pixman_image,
1198
ximage.data = (char *) clone->data;
1199
ximage.obdata = _cairo_xlib_shm_surface_get_obdata (&clone->base);
1200
ximage.bytes_per_line = clone->stride;
1202
pixman_image = pixman_image_create_bits (intermediate_format,
1203
width, height, NULL, 0);
1204
if (pixman_image == NULL) {
1205
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1209
pixman_image_composite32 (PIXMAN_OP_SRC,
1210
image->pixman_image,
1218
ximage.data = (char *) pixman_image_get_data (pixman_image);
1219
ximage.bytes_per_line = pixman_image_get_stride (pixman_image);
1222
ximage.width = width;
1223
ximage.height = height;
1224
ximage.bits_per_pixel = image_masks.bpp;
1226
ret = XInitImage (&ximage);
1233
unsigned int stride, rowstride;
1234
int x, y, x0, y0, x_off, y_off;
1235
uint32_t in_pixel, out_pixel, *row;
1236
int i_a_width=0, i_r_width=0, i_g_width=0, i_b_width=0;
1237
int i_a_shift=0, i_r_shift=0, i_g_shift=0, i_b_shift=0;
1238
int o_a_width=0, o_r_width=0, o_g_width=0, o_b_width=0;
1239
int o_a_shift=0, o_r_shift=0, o_g_shift=0, o_b_shift=0;
1240
cairo_xlib_visual_info_t *visual_info = NULL;
1241
cairo_bool_t true_color;
1244
ximage.bits_per_pixel = bits_per_pixel(surface);
1245
stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
1246
ximage.bits_per_pixel);
1247
ximage.bytes_per_line = stride;
1248
ximage.data = _cairo_malloc_ab (stride, ximage.height);
1249
if (unlikely (ximage.data == NULL)) {
1250
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1256
ret = XInitImage (&ximage);
1259
_characterize_field (image_masks.alpha_mask, &i_a_width, &i_a_shift);
1260
_characterize_field (image_masks.red_mask , &i_r_width, &i_r_shift);
1261
_characterize_field (image_masks.green_mask, &i_g_width, &i_g_shift);
1262
_characterize_field (image_masks.blue_mask , &i_b_width, &i_b_shift);
1264
true_color = surface->visual == NULL ||
1265
surface->visual->class == TrueColor;
1267
_characterize_field (surface->a_mask, &o_a_width, &o_a_shift);
1268
_characterize_field (surface->r_mask, &o_r_width, &o_r_shift);
1269
_characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
1270
_characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
1272
status = _cairo_xlib_screen_get_visual_info (display,
1276
if (unlikely (status))
1280
rowstride = image->stride >> 2;
1281
row = (uint32_t *) image->data;
1282
x0 = dst_x + surface->base.device_transform.x0;
1283
y0 = dst_y + surface->base.device_transform.y0;
1284
for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
1286
y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern))
1288
const int8_t *dither_row = dither_pattern[y_off];
1290
for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]);
1292
x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0]))
1294
int dither_adjustment = dither_row[x_off];
1297
if (image_masks.bpp == 1)
1298
in_pixel = !! (((uint8_t*)row)[x/8] & (1 << (x & 7)));
1299
else if (image_masks.bpp <= 8)
1300
in_pixel = ((uint8_t*)row)[x];
1301
else if (image_masks.bpp <= 16)
1302
in_pixel = ((uint16_t*)row)[x];
1303
else if (image_masks.bpp <= 24)
1304
#ifdef WORDS_BIGENDIAN
1305
in_pixel = ((uint8_t*)row)[3 * x] << 16 |
1306
((uint8_t*)row)[3 * x + 1] << 8 |
1307
((uint8_t*)row)[3 * x + 2];
1309
in_pixel = ((uint8_t*)row)[3 * x] |
1310
((uint8_t*)row)[3 * x + 1] << 8 |
1311
((uint8_t*)row)[3 * x + 2] << 16;
1316
/* If the incoming image has no alpha channel, then the input
1317
* is opaque and the output should have the maximum alpha value.
1318
* For all other channels, their absence implies 0.
1320
if (image_masks.alpha_mask == 0x0)
1323
a = _field_to_8 (in_pixel & image_masks.alpha_mask, i_a_width, i_a_shift);
1324
r = _field_to_8 (in_pixel & image_masks.red_mask , i_r_width, i_r_shift);
1325
g = _field_to_8 (in_pixel & image_masks.green_mask, i_g_width, i_g_shift);
1326
b = _field_to_8 (in_pixel & image_masks.blue_mask , i_b_width, i_b_shift);
1329
out_pixel = _field_from_8 (a, o_a_width, o_a_shift) |
1330
_field_from_8_dither (r, o_r_width, o_r_shift, dither_adjustment) |
1331
_field_from_8_dither (g, o_g_width, o_g_shift, dither_adjustment) |
1332
_field_from_8_dither (b, o_b_width, o_b_shift, dither_adjustment);
1334
out_pixel = _pseudocolor_from_rgb888_dither (visual_info, r, g, b, dither_adjustment);
1337
XPutPixel (&ximage, x, y, out_pixel);
1344
status = _cairo_xlib_surface_get_gc (display, surface, &gc);
1345
if (unlikely (status))
1349
XShmPutImage (display->display, surface->drawable, gc, &ximage,
1350
src_x, src_y, dst_x, dst_y, width, height,
1353
XPutImage (display->display, surface->drawable, gc, &ximage,
1354
src_x, src_y, dst_x, dst_y, width, height);
1356
_cairo_xlib_surface_put_gc (display, surface, gc);
1359
cairo_device_release (&display->base);
1364
cairo_surface_destroy (shm_image);
1366
pixman_image_unref (pixman_image);
1368
return CAIRO_STATUS_SUCCESS;
1371
static cairo_surface_t *
1372
_cairo_xlib_surface_source(void *abstract_surface,
1373
cairo_rectangle_int_t *extents)
1375
cairo_xlib_surface_t *surface = abstract_surface;
1378
extents->x = extents->y = 0;
1379
extents->width = surface->width;
1380
extents->height = surface->height;
1383
return &surface->base;
1386
static cairo_status_t
1387
_cairo_xlib_surface_acquire_source_image (void *abstract_surface,
1388
cairo_image_surface_t **image_out,
1391
cairo_xlib_surface_t *surface = abstract_surface;
1392
cairo_rectangle_int_t extents;
1394
*image_extra = NULL;
1395
*image_out = (cairo_image_surface_t *)
1396
_cairo_xlib_surface_get_shm (abstract_surface, FALSE);
1398
return (*image_out)->base.status;
1400
extents.x = extents.y = 0;
1401
extents.width = surface->width;
1402
extents.height = surface->height;
1404
*image_out = (cairo_image_surface_t*)
1405
_get_image_surface (surface, &extents, TRUE);
1406
return (*image_out)->base.status;
1409
static cairo_surface_t *
1410
_cairo_xlib_surface_snapshot (void *abstract_surface)
1412
cairo_xlib_surface_t *surface = abstract_surface;
1413
cairo_rectangle_int_t extents;
1415
extents.x = extents.y = 0;
1416
extents.width = surface->width;
1417
extents.height = surface->height;
1419
return _get_image_surface (surface, &extents, FALSE);
1423
_cairo_xlib_surface_release_source_image (void *abstract_surface,
1424
cairo_image_surface_t *image,
1427
cairo_xlib_surface_t *surface = abstract_surface;
1429
if (&image->base == surface->shm)
1432
cairo_surface_destroy (&image->base);
1435
static cairo_image_surface_t *
1436
_cairo_xlib_surface_map_to_image (void *abstract_surface,
1437
const cairo_rectangle_int_t *extents)
1439
cairo_xlib_surface_t *surface = abstract_surface;
1440
cairo_surface_t *image;
1442
image = _cairo_xlib_surface_get_shm (abstract_surface, FALSE);
1444
assert (surface->base.damage);
1445
surface->fallback++;
1446
return _cairo_image_surface_map_to_image (image, extents);
1449
image = _get_image_surface (abstract_surface, extents, TRUE);
1450
cairo_surface_set_device_offset (image, -extents->x, -extents->y);
1452
return (cairo_image_surface_t *) image;
1455
static cairo_int_status_t
1456
_cairo_xlib_surface_unmap_image (void *abstract_surface,
1457
cairo_image_surface_t *image)
1459
cairo_xlib_surface_t *surface = abstract_surface;
1460
cairo_int_status_t status;
1463
cairo_rectangle_int_t r;
1465
assert (surface->fallback);
1466
assert (surface->base.damage);
1468
r.x = image->base.device_transform_inverse.x0;
1469
r.y = image->base.device_transform_inverse.y0;
1470
r.width = image->width;
1471
r.height = image->height;
1473
TRACE ((stderr, "%s: adding damage (%d,%d)x(%d,%d)\n",
1474
__FUNCTION__, r.x, r.y, r.width, r.height));
1475
surface->shm->damage =
1476
_cairo_damage_add_rectangle (surface->shm->damage, &r);
1478
return _cairo_image_surface_unmap_image (surface->shm, image);
1481
status = _cairo_xlib_surface_draw_image (abstract_surface, image,
1483
image->width, image->height,
1484
image->base.device_transform_inverse.x0,
1485
image->base.device_transform_inverse.y0);
1487
cairo_surface_finish (&image->base);
1488
cairo_surface_destroy (&image->base);
1493
static cairo_status_t
1494
_cairo_xlib_surface_flush (void *abstract_surface,
1497
cairo_xlib_surface_t *surface = abstract_surface;
1498
cairo_int_status_t status;
1501
return CAIRO_STATUS_SUCCESS;
1503
status = _cairo_xlib_surface_put_shm (surface);
1504
if (unlikely (status))
1507
surface->fallback >>= 1;
1508
if (surface->shm && _cairo_xlib_shm_surface_is_idle (surface->shm))
1509
_cairo_xlib_surface_discard_shm (surface);
1511
return CAIRO_STATUS_SUCCESS;
1515
_cairo_xlib_surface_get_extents (void *abstract_surface,
1516
cairo_rectangle_int_t *rectangle)
1518
cairo_xlib_surface_t *surface = abstract_surface;
1523
rectangle->width = surface->width;
1524
rectangle->height = surface->height;
1530
_cairo_xlib_surface_get_font_options (void *abstract_surface,
1531
cairo_font_options_t *options)
1533
cairo_xlib_surface_t *surface = abstract_surface;
1535
*options = *_cairo_xlib_screen_get_font_options (surface->screen);
1538
static inline cairo_int_status_t
1539
get_compositor (cairo_xlib_surface_t **surface,
1540
const cairo_compositor_t **compositor)
1542
cairo_xlib_surface_t *s = *surface;
1543
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;;
1546
assert (s->base.damage != NULL);
1547
assert (s->shm != NULL);
1548
assert (s->shm->damage != NULL);
1549
if (! _cairo_xlib_shm_surface_is_active (s->shm)) {
1550
*surface = (cairo_xlib_surface_t *) s->shm;
1551
*compositor = ((cairo_image_surface_t *) s->shm)->compositor;
1554
status = _cairo_xlib_surface_put_shm (s);
1556
*compositor = s->compositor;
1559
*compositor = s->compositor;
1564
static cairo_int_status_t
1565
_cairo_xlib_surface_paint (void *_surface,
1566
cairo_operator_t op,
1567
const cairo_pattern_t *source,
1568
const cairo_clip_t *clip)
1570
cairo_xlib_surface_t *surface = _surface;
1571
const cairo_compositor_t *compositor;
1572
cairo_int_status_t status;
1574
status = get_compositor (&surface, &compositor);
1575
if (unlikely (status))
1578
return _cairo_compositor_paint (compositor, &surface->base,
1583
static cairo_int_status_t
1584
_cairo_xlib_surface_mask (void *_surface,
1585
cairo_operator_t op,
1586
const cairo_pattern_t *source,
1587
const cairo_pattern_t *mask,
1588
const cairo_clip_t *clip)
1590
cairo_xlib_surface_t *surface = _surface;
1591
const cairo_compositor_t *compositor;
1592
cairo_int_status_t status;
1594
status = get_compositor (&surface, &compositor);
1595
if (unlikely (status))
1598
return _cairo_compositor_mask (compositor, &surface->base,
1603
static cairo_int_status_t
1604
_cairo_xlib_surface_stroke (void *_surface,
1605
cairo_operator_t op,
1606
const cairo_pattern_t *source,
1607
const cairo_path_fixed_t *path,
1608
const cairo_stroke_style_t *style,
1609
const cairo_matrix_t *ctm,
1610
const cairo_matrix_t *ctm_inverse,
1612
cairo_antialias_t antialias,
1613
const cairo_clip_t *clip)
1615
cairo_xlib_surface_t *surface = _surface;
1616
const cairo_compositor_t *compositor;
1617
cairo_int_status_t status;
1619
status = get_compositor (&surface, &compositor);
1620
if (unlikely (status))
1623
return _cairo_compositor_stroke (compositor, &surface->base,
1625
path, style, ctm, ctm_inverse,
1626
tolerance, antialias,
1630
static cairo_int_status_t
1631
_cairo_xlib_surface_fill (void *_surface,
1632
cairo_operator_t op,
1633
const cairo_pattern_t *source,
1634
const cairo_path_fixed_t *path,
1635
cairo_fill_rule_t fill_rule,
1637
cairo_antialias_t antialias,
1638
const cairo_clip_t *clip)
1640
cairo_xlib_surface_t *surface = _surface;
1641
const cairo_compositor_t *compositor;
1642
cairo_int_status_t status;
1644
status = get_compositor (&surface, &compositor);
1645
if (unlikely (status))
1648
return _cairo_compositor_fill (compositor, &surface->base,
1650
path, fill_rule, tolerance, antialias,
1654
static cairo_int_status_t
1655
_cairo_xlib_surface_glyphs (void *_surface,
1656
cairo_operator_t op,
1657
const cairo_pattern_t *source,
1658
cairo_glyph_t *glyphs,
1660
cairo_scaled_font_t *scaled_font,
1661
const cairo_clip_t *clip)
1663
cairo_xlib_surface_t *surface = _surface;
1664
const cairo_compositor_t *compositor;
1665
cairo_int_status_t status;
1667
status = get_compositor (&surface, &compositor);
1668
if (unlikely (status))
1671
return _cairo_compositor_glyphs (compositor, &surface->base,
1673
glyphs, num_glyphs, scaled_font,
1677
static const cairo_surface_backend_t cairo_xlib_surface_backend = {
1678
CAIRO_SURFACE_TYPE_XLIB,
1679
_cairo_xlib_surface_finish,
1681
_cairo_default_context_create,
1683
_cairo_xlib_surface_create_similar,
1684
_cairo_xlib_surface_create_similar_shm,
1685
_cairo_xlib_surface_map_to_image,
1686
_cairo_xlib_surface_unmap_image,
1688
_cairo_xlib_surface_source,
1689
_cairo_xlib_surface_acquire_source_image,
1690
_cairo_xlib_surface_release_source_image,
1691
_cairo_xlib_surface_snapshot,
1693
NULL, /* copy_page */
1694
NULL, /* show_page */
1696
_cairo_xlib_surface_get_extents,
1697
_cairo_xlib_surface_get_font_options,
1699
_cairo_xlib_surface_flush,
1700
NULL, /* mark_dirty_rectangle */
1702
_cairo_xlib_surface_paint,
1703
_cairo_xlib_surface_mask,
1704
_cairo_xlib_surface_stroke,
1705
_cairo_xlib_surface_fill,
1706
NULL, /* fill-stroke */
1707
_cairo_xlib_surface_glyphs,
1711
* _cairo_surface_is_xlib:
1712
* @surface: a #cairo_surface_t
1714
* Checks if a surface is a #cairo_xlib_surface_t
1716
* Return value: True if the surface is an xlib surface
1719
_cairo_surface_is_xlib (cairo_surface_t *surface)
1721
return surface->backend == &cairo_xlib_surface_backend;
1724
static cairo_surface_t *
1725
_cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
1728
XRenderPictFormat *xrender_format,
1733
cairo_xlib_surface_t *surface;
1734
cairo_xlib_display_t *display;
1735
cairo_status_t status;
1738
if (xrender_format) {
1739
depth = xrender_format->depth;
1741
/* XXX find matching visual for core/dithering fallbacks? */
1742
} else if (visual) {
1743
Screen *scr = screen->screen;
1745
if (visual == DefaultVisualOfScreen (scr)) {
1746
depth = DefaultDepthOfScreen (scr);
1750
/* This is ugly, but we have to walk over all visuals
1751
* for the display to find the correct depth.
1754
for (j = 0; j < scr->ndepths; j++) {
1755
Depth *d = &scr->depths[j];
1756
for (k = 0; k < d->nvisuals; k++) {
1757
if (&d->visuals[k] == visual) {
1767
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1773
surface = malloc (sizeof (cairo_xlib_surface_t));
1774
if (unlikely (surface == NULL))
1775
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1777
status = _cairo_xlib_display_acquire (screen->device, &display);
1778
if (unlikely (status)) {
1780
return _cairo_surface_create_in_error (_cairo_error (status));
1783
surface->display = display;
1784
if (CAIRO_RENDER_HAS_CREATE_PICTURE (display)) {
1785
if (!xrender_format) {
1787
xrender_format = XRenderFindVisualFormat (display->display, visual);
1788
} else if (depth == 1) {
1790
_cairo_xlib_display_get_xrender_format (display,
1796
cairo_device_release (&display->base);
1798
_cairo_surface_init (&surface->base,
1799
&cairo_xlib_surface_backend,
1801
_xrender_format_to_content (xrender_format));
1803
surface->screen = screen;
1804
surface->compositor = display->compositor;
1805
surface->shm = NULL;
1806
surface->fallback = 0;
1808
surface->drawable = drawable;
1809
surface->owns_pixmap = FALSE;
1810
surface->use_pixmap = 0;
1811
surface->width = width;
1812
surface->height = height;
1814
surface->picture = None;
1815
surface->precision = PolyModePrecise;
1817
surface->embedded_source.picture = None;
1819
surface->visual = visual;
1820
surface->xrender_format = xrender_format;
1821
surface->depth = depth;
1824
* Compute the pixel format masks from either a XrenderFormat or
1825
* else from a visual; failing that we assume the drawable is an
1826
* alpha-only pixmap as it could only have been created that way
1827
* through the cairo_xlib_surface_create_for_bitmap function.
1829
if (xrender_format) {
1830
surface->a_mask = (unsigned long)
1831
surface->xrender_format->direct.alphaMask
1832
<< surface->xrender_format->direct.alpha;
1833
surface->r_mask = (unsigned long)
1834
surface->xrender_format->direct.redMask
1835
<< surface->xrender_format->direct.red;
1836
surface->g_mask = (unsigned long)
1837
surface->xrender_format->direct.greenMask
1838
<< surface->xrender_format->direct.green;
1839
surface->b_mask = (unsigned long)
1840
surface->xrender_format->direct.blueMask
1841
<< surface->xrender_format->direct.blue;
1842
} else if (visual) {
1843
surface->a_mask = 0;
1844
surface->r_mask = visual->red_mask;
1845
surface->g_mask = visual->green_mask;
1846
surface->b_mask = visual->blue_mask;
1849
surface->a_mask = (1 << depth) - 1;
1851
surface->a_mask = 0xffffffff;
1852
surface->r_mask = 0;
1853
surface->g_mask = 0;
1854
surface->b_mask = 0;
1857
cairo_list_add (&surface->link, &screen->surfaces);
1859
return &surface->base;
1863
_cairo_xlib_screen_from_visual (Display *dpy, Visual *visual)
1867
for (s = 0; s < ScreenCount (dpy); s++) {
1870
screen = ScreenOfDisplay (dpy, s);
1871
if (visual == DefaultVisualOfScreen (screen))
1874
for (d = 0; d < screen->ndepths; d++) {
1877
depth = &screen->depths[d];
1878
for (v = 0; v < depth->nvisuals; v++)
1879
if (visual == &depth->visuals[v])
1887
static cairo_bool_t valid_size (int width, int height)
1889
/* Note: the minimum surface size allowed in the X protocol is 1x1.
1890
* However, as we historically did not check the minimum size we
1891
* allowed applications to lie and set the correct size later (one hopes).
1892
* To preserve compatability we must allow applications to use
1895
return (width >= 0 && width <= XLIB_COORD_MAX &&
1896
height >= 0 && height <= XLIB_COORD_MAX);
1900
* cairo_xlib_surface_create:
1901
* @dpy: an X Display
1902
* @drawable: an X Drawable, (a Pixmap or a Window)
1903
* @visual: the visual to use for drawing to @drawable. The depth
1904
* of the visual must match the depth of the drawable.
1905
* Currently, only TrueColor visuals are fully supported.
1906
* @width: the current width of @drawable.
1907
* @height: the current height of @drawable.
1909
* Creates an Xlib surface that draws to the given drawable.
1910
* The way that colors are represented in the drawable is specified
1911
* by the provided visual.
1913
* Note: If @drawable is a Window, then the function
1914
* cairo_xlib_surface_set_size() must be called whenever the size of the
1917
* When @drawable is a Window containing child windows then drawing to
1918
* the created surface will be clipped by those child windows. When
1919
* the created surface is used as a source, the contents of the
1920
* children will be included.
1922
* Return value: the newly created surface
1927
cairo_xlib_surface_create (Display *dpy,
1934
cairo_xlib_screen_t *screen;
1935
cairo_status_t status;
1937
if (! valid_size (width, height)) {
1938
/* you're lying, and you know it! */
1939
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1942
scr = _cairo_xlib_screen_from_visual (dpy, visual);
1944
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1946
status = _cairo_xlib_screen_get (dpy, scr, &screen);
1947
if (unlikely (status))
1948
return _cairo_surface_create_in_error (status);
1950
X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable));
1952
return _cairo_xlib_surface_create_internal (screen, drawable,
1958
* cairo_xlib_surface_create_for_bitmap:
1959
* @dpy: an X Display
1960
* @bitmap: an X Drawable, (a depth-1 Pixmap)
1961
* @screen: the X Screen associated with @bitmap
1962
* @width: the current width of @bitmap.
1963
* @height: the current height of @bitmap.
1965
* Creates an Xlib surface that draws to the given bitmap.
1966
* This will be drawn to as a %CAIRO_FORMAT_A1 object.
1968
* Return value: the newly created surface
1973
cairo_xlib_surface_create_for_bitmap (Display *dpy,
1979
cairo_xlib_screen_t *screen;
1980
cairo_status_t status;
1982
if (! valid_size (width, height))
1983
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1985
status = _cairo_xlib_screen_get (dpy, scr, &screen);
1986
if (unlikely (status))
1987
return _cairo_surface_create_in_error (status);
1989
X_DEBUG ((dpy, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap));
1991
return _cairo_xlib_surface_create_internal (screen, bitmap,
1996
#if CAIRO_HAS_XLIB_XRENDER_SURFACE
1998
* cairo_xlib_surface_create_with_xrender_format:
1999
* @dpy: an X Display
2000
* @drawable: an X Drawable, (a Pixmap or a Window)
2001
* @screen: the X Screen associated with @drawable
2002
* @format: the picture format to use for drawing to @drawable. The depth
2003
* of @format must match the depth of the drawable.
2004
* @width: the current width of @drawable.
2005
* @height: the current height of @drawable.
2007
* Creates an Xlib surface that draws to the given drawable.
2008
* The way that colors are represented in the drawable is specified
2009
* by the provided picture format.
2011
* Note: If @drawable is a Window, then the function
2012
* cairo_xlib_surface_set_size() must be called whenever the size of the
2015
* Return value: the newly created surface
2020
cairo_xlib_surface_create_with_xrender_format (Display *dpy,
2023
XRenderPictFormat *format,
2027
cairo_xlib_screen_t *screen;
2028
cairo_status_t status;
2030
if (! valid_size (width, height))
2031
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
2033
status = _cairo_xlib_screen_get (dpy, scr, &screen);
2034
if (unlikely (status))
2035
return _cairo_surface_create_in_error (status);
2037
X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable));
2039
return _cairo_xlib_surface_create_internal (screen, drawable,
2040
_visual_for_xrender_format (scr, format),
2041
format, width, height, 0);
2045
* cairo_xlib_surface_get_xrender_format:
2046
* @surface: an xlib surface
2048
* Gets the X Render picture format that @surface uses for rendering with the
2049
* X Render extension. If the surface was created by
2050
* cairo_xlib_surface_create_with_xrender_format() originally, the return
2051
* value is the format passed to that constructor.
2053
* Return value: the XRenderPictFormat* associated with @surface,
2054
* or %NULL if the surface is not an xlib surface
2055
* or if the X Render extension is not available.
2060
cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface)
2062
cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
2064
/* Throw an error for a non-xlib surface */
2065
if (! _cairo_surface_is_xlib (surface)) {
2066
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2070
return xlib_surface->xrender_format;
2075
* cairo_xlib_surface_set_size:
2076
* @surface: a #cairo_surface_t for the XLib backend
2077
* @width: the new width of the surface
2078
* @height: the new height of the surface
2080
* Informs cairo of the new size of the X Drawable underlying the
2081
* surface. For a surface created for a Window (rather than a Pixmap),
2082
* this function must be called each time the size of the window
2083
* changes. (For a subwindow, you are normally resizing the window
2084
* yourself, but for a toplevel window, it is necessary to listen for
2085
* ConfigureNotify events.)
2087
* A Pixmap can never change size, so it is never necessary to call
2088
* this function on a surface created for a Pixmap.
2093
cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface,
2097
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2098
cairo_status_t status;
2100
if (unlikely (abstract_surface->status))
2102
if (unlikely (abstract_surface->finished)) {
2103
_cairo_surface_set_error (abstract_surface,
2104
_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2108
if (! _cairo_surface_is_xlib (abstract_surface)) {
2109
_cairo_surface_set_error (abstract_surface,
2110
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
2114
if (surface->width == width && surface->height == height)
2117
if (! valid_size (width, height)) {
2118
_cairo_surface_set_error (abstract_surface,
2119
_cairo_error (CAIRO_STATUS_INVALID_SIZE));
2123
status = _cairo_surface_flush (abstract_surface, 0);
2124
if (unlikely (status)) {
2125
_cairo_surface_set_error (abstract_surface, status);
2129
_cairo_xlib_surface_discard_shm (surface);
2131
surface->width = width;
2132
surface->height = height;
2136
* cairo_xlib_surface_set_drawable:
2137
* @surface: a #cairo_surface_t for the XLib backend
2138
* @drawable: the new drawable for the surface
2139
* @width: the width of the new drawable
2140
* @height: the height of the new drawable
2142
* Informs cairo of a new X Drawable underlying the
2143
* surface. The drawable must match the display, screen
2144
* and format of the existing drawable or the application
2145
* will get X protocol errors and will probably terminate.
2146
* No checks are done by this function to ensure this
2152
cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
2157
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
2158
cairo_status_t status;
2160
if (unlikely (abstract_surface->status))
2162
if (unlikely (abstract_surface->finished)) {
2163
status = _cairo_surface_set_error (abstract_surface,
2164
_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2168
if (! _cairo_surface_is_xlib (abstract_surface)) {
2169
status = _cairo_surface_set_error (abstract_surface,
2170
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
2174
if (! valid_size (width, height)) {
2175
status = _cairo_surface_set_error (abstract_surface,
2176
_cairo_error (CAIRO_STATUS_INVALID_SIZE));
2180
/* XXX: and what about this case? */
2181
if (surface->owns_pixmap)
2184
status = _cairo_surface_flush (abstract_surface, 0);
2185
if (unlikely (status)) {
2186
_cairo_surface_set_error (abstract_surface, status);
2190
if (surface->drawable != drawable) {
2191
cairo_xlib_display_t *display;
2193
status = _cairo_xlib_display_acquire (surface->base.device, &display);
2194
if (unlikely (status))
2197
X_DEBUG ((display->display, "set_drawable (drawable=%x)", (unsigned int) drawable));
2199
if (surface->picture != None) {
2200
XRenderFreePicture (display->display, surface->picture);
2201
if (unlikely (status)) {
2202
status = _cairo_surface_set_error (&surface->base, status);
2206
surface->picture = None;
2209
cairo_device_release (&display->base);
2211
surface->drawable = drawable;
2214
if (surface->width != width || surface->height != height) {
2215
_cairo_xlib_surface_discard_shm (surface);
2217
surface->width = width;
2218
surface->height = height;
2223
* cairo_xlib_surface_get_display:
2224
* @surface: a #cairo_xlib_surface_t
2226
* Get the X Display for the underlying X Drawable.
2228
* Return value: the display.
2233
cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
2235
if (! _cairo_surface_is_xlib (abstract_surface)) {
2236
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2240
return ((cairo_xlib_display_t *) abstract_surface->device)->display;
2244
* cairo_xlib_surface_get_drawable:
2245
* @surface: a #cairo_xlib_surface_t
2247
* Get the underlying X Drawable used for the surface.
2249
* Return value: the drawable.
2254
cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface)
2256
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2258
if (! _cairo_surface_is_xlib (abstract_surface)) {
2259
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2263
return surface->drawable;
2267
* cairo_xlib_surface_get_screen:
2268
* @surface: a #cairo_xlib_surface_t
2270
* Get the X Screen for the underlying X Drawable.
2272
* Return value: the screen.
2277
cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
2279
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2281
if (! _cairo_surface_is_xlib (abstract_surface)) {
2282
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2286
return surface->screen->screen;
2290
* cairo_xlib_surface_get_visual:
2291
* @surface: a #cairo_xlib_surface_t
2293
* Gets the X Visual associated with @surface, suitable for use with the
2294
* underlying X Drawable. If @surface was created by
2295
* cairo_xlib_surface_create(), the return value is the Visual passed to that
2298
* Return value: the Visual or %NULL if there is no appropriate Visual for
2304
cairo_xlib_surface_get_visual (cairo_surface_t *surface)
2306
cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
2308
if (! _cairo_surface_is_xlib (surface)) {
2309
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2313
return xlib_surface->visual;
2317
* cairo_xlib_surface_get_depth:
2318
* @surface: a #cairo_xlib_surface_t
2320
* Get the number of bits used to represent each pixel value.
2322
* Return value: the depth of the surface in bits.
2327
cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
2329
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2331
if (! _cairo_surface_is_xlib (abstract_surface)) {
2332
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2336
return surface->depth;
2340
* cairo_xlib_surface_get_width:
2341
* @surface: a #cairo_xlib_surface_t
2343
* Get the width of the X Drawable underlying the surface in pixels.
2345
* Return value: the width of the surface in pixels.
2350
cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface)
2352
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2354
if (! _cairo_surface_is_xlib (abstract_surface)) {
2355
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2359
return surface->width;
2363
* cairo_xlib_surface_get_height:
2364
* @surface: a #cairo_xlib_surface_t
2366
* Get the height of the X Drawable underlying the surface in pixels.
2368
* Return value: the height of the surface in pixels.
2373
cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface)
2375
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2377
if (! _cairo_surface_is_xlib (abstract_surface)) {
2378
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2382
return surface->height;
2385
#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */