e9e647a191ff458c48367865690fe7ac4e1cf9f1
[platform/upstream/cairo.git] / src / cairo-xlib-surface.c
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
3  *
4  * Copyright © 2002 University of Southern California
5  * Copyright © 2005 Red Hat, Inc.
6  *
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.
14  *
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
20  *
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/
25  *
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.
29  *
30  * The Original Code is the cairo graphics library.
31  *
32  * The Initial Developer of the Original Code is University of Southern
33  * California.
34  *
35  * Contributor(s):
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
40  */
41
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."
46  */
47
48 #include "cairoint.h"
49
50 #if !CAIRO_HAS_XLIB_XCB_FUNCTIONS
51
52 #include "cairo-xlib-private.h"
53 #include "cairo-xlib-surface-private.h"
54
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"
67
68 #include <X11/Xutil.h> /* for XDestroyImage */
69
70 #include <X11/extensions/XShm.h>
71 #include <sys/ipc.h>
72 #include <sys/shm.h>
73
74 #define XLIB_COORD_MAX 32767
75
76 #define DEBUG 0
77
78 #if DEBUG
79 #define UNSUPPORTED(reason) \
80     fprintf (stderr, \
81              "cairo-xlib: hit unsupported operation %s(), line %d: %s\n", \
82              __FUNCTION__, __LINE__, reason), \
83     CAIRO_INT_STATUS_UNSUPPORTED
84 #else
85 #define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
86 #endif
87
88 #if DEBUG
89 #include <X11/Xlibint.h>
90 static void CAIRO_PRINTF_FORMAT (2, 3)
91 _x_bread_crumb (Display *dpy,
92                 const char *fmt,
93                 ...)
94 {
95     xReq *req;
96     char buf[2048];
97     unsigned int len, len_dwords;
98     va_list ap;
99
100     va_start (ap, fmt);
101     len = vsnprintf (buf, sizeof (buf), fmt, ap);
102     va_end (ap);
103
104     buf[len++] = '\0';
105     while (len & 3)
106         buf[len++] = '\0';
107
108     LockDisplay (dpy);
109     GetEmptyReq (NoOperation, req);
110
111     len_dwords = len >> 2;
112     SetReqLen (req, len_dwords, len_dwords);
113     Data (dpy, buf, len);
114
115     UnlockDisplay (dpy);
116     SyncHandle ();
117 }
118 #define X_DEBUG(x) _x_bread_crumb x
119 #else
120 #define X_DEBUG(x)
121 #endif
122
123 /**
124  * SECTION:cairo-xlib
125  * @Title: XLib Surfaces
126  * @Short_Description: X Window System rendering using XLib
127  * @See_Also: #cairo_surface_t
128  *
129  * The XLib surface is used to render cairo graphics to X Window System
130  * windows and pixmaps using the XLib library.
131  *
132  * Note that the XLib surface automatically takes advantage of X render extension
133  * if it is available.
134  **/
135
136 /**
137  * CAIRO_HAS_XLIB_SURFACE:
138  *
139  * Defined if the Xlib surface backend is available.
140  * This macro can be used to conditionally compile backend-specific code.
141  *
142  * Since: 1.0
143  **/
144
145 /**
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
150  *
151  * The XLib surface is used to render cairo graphics to X Window System
152  * windows and pixmaps using the XLib and Xrender libraries.
153  *
154  * Note that the XLib surface automatically takes advantage of X Render extension
155  * if it is available.
156  **/
157
158 /**
159  * CAIRO_HAS_XLIB_XRENDER_SURFACE:
160  *
161  * Defined if the XLib/XRender surface functions are available.
162  * This macro can be used to conditionally compile backend-specific code.
163  *
164  * Since: 1.6
165  **/
166
167 /* Xlib doesn't define a typedef, so define one ourselves */
168 typedef int (*cairo_xlib_error_func_t) (Display     *display,
169                                         XErrorEvent *event);
170
171 static cairo_surface_t *
172 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t        *screen,
173                                      Drawable                   drawable,
174                                      Visual                    *visual,
175                                      XRenderPictFormat         *xrender_format,
176                                      int                        width,
177                                      int                        height,
178                                      int                        depth);
179
180 static cairo_bool_t
181 _cairo_surface_is_xlib (cairo_surface_t *surface);
182
183 /*
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
187  */
188
189 #define CAIRO_ASSUME_PIXMAP     20
190
191 static const XTransform identity = { {
192     { 1 << 16, 0x00000, 0x00000 },
193     { 0x00000, 1 << 16, 0x00000 },
194     { 0x00000, 0x00000, 1 << 16 },
195 } };
196
197 static Visual *
198 _visual_for_xrender_format(Screen *screen,
199                            XRenderPictFormat *xrender_format)
200 {
201     int d, v;
202
203     /* XXX Consider searching through the list of known cairo_visual_t for
204      * the reverse mapping.
205      */
206
207     for (d = 0; d < screen->ndepths; d++) {
208         Depth *d_info = &screen->depths[d];
209
210         if (d_info->depth != xrender_format->depth)
211             continue;
212
213         for (v = 0; v < d_info->nvisuals; v++) {
214             Visual *visual = &d_info->visuals[v];
215
216             switch (visual->class) {
217             case TrueColor:
218                 if (xrender_format->type != PictTypeDirect)
219                     continue;
220                 break;
221
222             case DirectColor:
223                 /* Prefer TrueColor to DirectColor.
224                  * (XRenderFindVisualFormat considers both TrueColor and DirectColor
225                  * Visuals to match the same PictFormat.)
226                  */
227                 continue;
228
229             case StaticGray:
230             case GrayScale:
231             case StaticColor:
232             case PseudoColor:
233                 if (xrender_format->type != PictTypeIndexed)
234                     continue;
235                 break;
236             }
237
238             if (xrender_format ==
239                 XRenderFindVisualFormat (DisplayOfScreen(screen), visual))
240                 return visual;
241         }
242     }
243
244     return NULL;
245 }
246
247 static cairo_content_t
248 _xrender_format_to_content (XRenderPictFormat *xrender_format)
249 {
250     cairo_content_t content;
251
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;
256
257     content = 0;
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;
264
265     return content;
266 }
267
268 static cairo_surface_t *
269 _cairo_xlib_surface_create_similar (void               *abstract_src,
270                                     cairo_content_t     content,
271                                     int                 width,
272                                     int                 height)
273 {
274     cairo_xlib_surface_t *src = abstract_src;
275     XRenderPictFormat *xrender_format;
276     cairo_xlib_surface_t *surface;
277     cairo_xlib_display_t *display;
278     Pixmap pix;
279
280     if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
281         return NULL;
282
283     if (width == 0 || height == 0)
284         return NULL;
285
286     if (_cairo_xlib_display_acquire (src->base.device, &display))
287         return NULL;
288
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.
293      */
294     xrender_format = NULL;
295     if (src->xrender_format &&
296         _xrender_format_to_content (src->xrender_format) == content)
297     {
298         xrender_format = src->xrender_format;
299     }
300     if (xrender_format == NULL) {
301         xrender_format =
302             _cairo_xlib_display_get_xrender_format (display,
303                                                     _cairo_format_from_content (content));
304     }
305     if (xrender_format) {
306         Visual *visual;
307
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);
313
314         if (xrender_format == src->xrender_format)
315             visual = src->visual;
316         else
317             visual = _visual_for_xrender_format(src->screen->screen,
318                                                 xrender_format);
319
320         surface = (cairo_xlib_surface_t *)
321                   _cairo_xlib_surface_create_internal (src->screen, pix, visual,
322                                                        xrender_format,
323                                                        width, height,
324                                                        xrender_format->depth);
325     }
326     else
327     {
328         Screen *screen = src->screen->screen;
329         int depth;
330
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);
335             return NULL;
336         }
337
338         depth = DefaultDepthOfScreen (screen);
339
340         pix = XCreatePixmap (display->display, RootWindowOfScreen (screen),
341                              width <= 0 ? 1 : width, height <= 0 ? 1 : height,
342                              depth);
343
344         surface = (cairo_xlib_surface_t *)
345                   _cairo_xlib_surface_create_internal (src->screen, pix,
346                                                        DefaultVisualOfScreen (screen),
347                                                        NULL,
348                                                        width, height, depth);
349     }
350
351     if (likely (surface->base.status == CAIRO_STATUS_SUCCESS))
352         surface->owns_pixmap = TRUE;
353     else
354         XFreePixmap (display->display, pix);
355
356     cairo_device_release (&display->base);
357
358     return &surface->base;
359 }
360
361 static void
362 _cairo_xlib_surface_discard_shm (cairo_xlib_surface_t *surface)
363 {
364     if (surface->shm == NULL)
365         return;
366
367     /* Force the flush for an external surface */
368     if (!surface->owns_pixmap)
369         cairo_surface_flush (surface->shm);
370
371     cairo_surface_finish (surface->shm);
372     cairo_surface_destroy (surface->shm);
373     surface->shm = NULL;
374
375     _cairo_damage_destroy (surface->base.damage);
376     surface->base.damage = NULL;
377
378     surface->fallback = 0;
379 }
380
381 static cairo_status_t
382 _cairo_xlib_surface_finish (void *abstract_surface)
383 {
384     cairo_xlib_surface_t *surface = abstract_surface;
385     cairo_status_t        status;
386     cairo_xlib_display_t *display;
387
388     X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable));
389
390     cairo_list_del (&surface->link);
391
392     status = _cairo_xlib_display_acquire (surface->base.device, &display);
393     if (unlikely (status))
394         return status;
395
396     if (surface->embedded_source.picture)
397         XRenderFreePicture (display->display, surface->embedded_source.picture);
398     if (surface->picture)
399         XRenderFreePicture (display->display, surface->picture);
400
401     _cairo_xlib_surface_discard_shm (surface);
402
403     if (surface->owns_pixmap)
404         XFreePixmap (display->display, surface->drawable);
405
406     cairo_device_release (&display->base);
407
408     return status;
409 }
410
411 cairo_status_t
412 _cairo_xlib_surface_get_gc (cairo_xlib_display_t *display,
413                             cairo_xlib_surface_t *surface,
414                             GC                   *gc)
415 {
416     *gc = _cairo_xlib_screen_get_gc (display,
417                                      surface->screen,
418                                      surface->depth,
419                                      surface->drawable);
420     if (unlikely (*gc == NULL))
421         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
422
423     return CAIRO_STATUS_SUCCESS;
424 }
425
426 static int
427 _noop_error_handler (Display     *display,
428                      XErrorEvent *event)
429 {
430     return False;               /* return value is ignored */
431 }
432
433 static void
434 _swap_ximage_2bytes (XImage *ximage)
435 {
436     int i, j;
437     char *line = ximage->data;
438
439     for (j = ximage->height; j; j--) {
440         uint16_t *p = (uint16_t *) line;
441         for (i = ximage->width; i; i--) {
442             *p = bswap_16 (*p);
443             p++;
444         }
445
446         line += ximage->bytes_per_line;
447     }
448 }
449
450 static void
451 _swap_ximage_3bytes (XImage *ximage)
452 {
453     int i, j;
454     char *line = ximage->data;
455
456     for (j = ximage->height; j; j--) {
457         uint8_t *p = (uint8_t *) line;
458         for (i = ximage->width; i; i--) {
459             uint8_t tmp;
460             tmp = p[2];
461             p[2] = p[0];
462             p[0] = tmp;
463             p += 3;
464         }
465
466         line += ximage->bytes_per_line;
467     }
468 }
469
470 static void
471 _swap_ximage_4bytes (XImage *ximage)
472 {
473     int i, j;
474     char *line = ximage->data;
475
476     for (j = ximage->height; j; j--) {
477         uint32_t *p = (uint32_t *) line;
478         for (i = ximage->width; i; i--) {
479             *p = bswap_32 (*p);
480             p++;
481         }
482
483         line += ximage->bytes_per_line;
484     }
485 }
486
487 static void
488 _swap_ximage_nibbles (XImage *ximage)
489 {
490     int i, j;
491     char *line = ximage->data;
492
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);
497             p++;
498         }
499
500         line += ximage->bytes_per_line;
501     }
502 }
503
504 static void
505 _swap_ximage_bits (XImage *ximage)
506 {
507     int i, j;
508     char *line = ximage->data;
509     int unit = ximage->bitmap_unit;
510     int line_bytes = ((ximage->width + unit - 1) & ~(unit - 1)) / 8;
511
512     for (j = ximage->height; j; j--) {
513         char *p = line;
514
515         for (i = line_bytes; i; i--) {
516             char b = *p;
517             b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55);
518             b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33);
519             b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f);
520             *p = b;
521
522             p++;
523         }
524
525         line += ximage->bytes_per_line;
526     }
527 }
528
529 static void
530 _swap_ximage_to_native (XImage *ximage)
531 {
532     int unit_bytes = 0;
533     int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst;
534
535     if (ximage->bits_per_pixel == 1 &&
536         ximage->bitmap_bit_order != native_byte_order)
537     {
538         _swap_ximage_bits (ximage);
539         if (ximage->bitmap_bit_order == ximage->byte_order)
540             return;
541     }
542
543     if (ximage->byte_order == native_byte_order)
544         return;
545
546     switch (ximage->bits_per_pixel) {
547     case 1:
548         unit_bytes = ximage->bitmap_unit / 8;
549         break;
550     case 4:
551         _swap_ximage_nibbles (ximage);
552         /* fall-through */
553     case 8:
554     case 16:
555     case 20:
556     case 24:
557     case 28:
558     case 30:
559     case 32:
560         unit_bytes = (ximage->bits_per_pixel + 7) / 8;
561         break;
562     default:
563         /* This could be hit on some rare but possible cases. */
564         ASSERT_NOT_REACHED;
565     }
566
567     switch (unit_bytes) {
568     case 1:
569         break;
570     case 2:
571         _swap_ximage_2bytes (ximage);
572         break;
573     case 3:
574         _swap_ximage_3bytes (ximage);
575         break;
576     case 4:
577         _swap_ximage_4bytes (ximage);
578         break;
579     default:
580         ASSERT_NOT_REACHED;
581     }
582 }
583
584
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'. */
588 static void
589 _characterize_field (uint32_t mask, int *width, int *shift)
590 {
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;
594 }
595
596 /* Convert a field of 'width' bits to 'new_width' bits with correct
597  * rounding. */
598 static inline uint32_t
599 _resize_field (uint32_t field, int width, int new_width)
600 {
601     if (width == 0)
602         return 0;
603
604     if (width >= new_width) {
605         return field >> (width - new_width);
606     } else {
607         uint32_t result = field << (new_width - width);
608
609         while (width < new_width) {
610             result |= result >> width;
611             width <<= 1;
612         }
613         return result;
614     }
615 }
616
617 static inline uint32_t
618 _adjust_field (uint32_t field, int adjustment)
619 {
620     return MIN (255, MAX(0, (int)field + adjustment));
621 }
622
623 /* Given a shifted field value, (described by 'width' and 'shift),
624  * resize it 8-bits and return that value.
625  *
626  * Note that the original field value must not have any non-field bits
627  * set.
628  */
629 static inline uint32_t
630 _field_to_8 (uint32_t field, int width, int shift)
631 {
632     return _resize_field (field >> shift, width, 8);
633 }
634
635 static inline uint32_t
636 _field_to_8_undither (uint32_t field, int width, int shift,
637                       int dither_adjustment)
638 {
639     return _adjust_field (_field_to_8 (field, width, shift), - dither_adjustment>>width);
640 }
641
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)
646 {
647     return _resize_field (field, 8, width) << shift;
648 }
649
650 static inline uint32_t
651 _field_from_8_dither (uint32_t field, int width, int shift,
652                       int8_t dither_adjustment)
653 {
654     return _field_from_8 (_adjust_field (field, dither_adjustment>>width), width, shift);
655 }
656
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)
661 {
662     if (r == g && g == b) {
663         dither_adjustment /= RAMP_SIZE;
664         return visual_info->gray8_to_pseudocolor[_adjust_field (r, dither_adjustment)];
665     } else {
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)]];
670     }
671 }
672
673 static inline uint32_t
674 _pseudocolor_to_rgb888 (cairo_xlib_visual_info_t *visual_info,
675                         uint32_t pixel)
676 {
677     uint32_t r, g, b;
678     pixel &= 0xff;
679     r = visual_info->colors[pixel].r;
680     g = visual_info->colors[pixel].g;
681     b = visual_info->colors[pixel].b;
682     return (r << 16) |
683            (g <<  8) |
684            (b      );
685 }
686
687 /* should range from -128 to 127 */
688 #define X 16
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}
694 };
695 #undef X
696
697 static int bits_per_pixel(cairo_xlib_surface_t *surface)
698 {
699     if (surface->depth > 16)
700         return 32;
701     else if (surface->depth > 8)
702         return 16;
703     else if (surface->depth > 1)
704         return 8;
705     else
706         return 1;
707 }
708
709 pixman_format_code_t
710 _pixman_format_for_xlib_surface (cairo_xlib_surface_t *surface)
711 {
712     cairo_format_masks_t masks;
713     pixman_format_code_t format;
714
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))
721         return 0;
722
723     return format;
724 }
725
726 static cairo_surface_t *
727 _get_image_surface (cairo_xlib_surface_t    *surface,
728                     const cairo_rectangle_int_t *extents,
729                     int try_shm)
730 {
731     cairo_int_status_t status;
732     cairo_image_surface_t *image = NULL;
733     XImage *ximage;
734     pixman_format_code_t pixman_format;
735     cairo_xlib_display_t *display;
736
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);
741
742     if (surface->base.is_clear ||
743         (surface->base.serial == 0 && surface->owns_pixmap))
744     {
745         pixman_format = _pixman_format_for_xlib_surface (surface);
746         if (pixman_format)
747         {
748             return _cairo_image_surface_create_with_pixman_format (NULL,
749                                                                    pixman_format,
750                                                                    extents->width,
751                                                                    extents->height,
752                                                                    0);
753         }
754     }
755
756     if (surface->shm) {
757         cairo_image_surface_t *src = (cairo_image_surface_t *) surface->shm;
758         cairo_surface_t *dst;
759         cairo_surface_pattern_t pattern;
760
761         dst = cairo_image_surface_create (src->format,
762                                           extents->width, extents->height);
763         if (unlikely (dst->status))
764             return dst;
765
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);
774         }
775
776         return dst;
777     }
778
779     status = _cairo_xlib_display_acquire (surface->base.device, &display);
780     if (status)
781         return _cairo_surface_create_in_error (status);
782
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;
790             XImage shm_image;
791             Bool success;
792
793             _cairo_xlib_shm_surface_get_ximage (&image->base, &shm_image);
794
795             old_handler = XSetErrorHandler (_noop_error_handler);
796             success = XShmGetImage (display->display,
797                                     surface->drawable,
798                                     &shm_image,
799                                     extents->x, extents->y,
800                                     AllPlanes);
801             XSetErrorHandler (old_handler);
802
803             if (success) {
804                 cairo_device_release (&display->base);
805                 return &image->base;
806             }
807
808             cairo_surface_destroy (&image->base);
809         }
810     }
811
812     if (surface->use_pixmap == 0) {
813         cairo_xlib_error_func_t old_handler;
814
815         old_handler = XSetErrorHandler (_noop_error_handler);
816
817         ximage = XGetImage (display->display,
818                             surface->drawable,
819                             extents->x, extents->y,
820                             extents->width, extents->height,
821                             AllPlanes, ZPixmap);
822
823         XSetErrorHandler (old_handler);
824
825         /* If we get an error, the surface must have been a window,
826          * so retry with the safe code path.
827          */
828         if (!ximage)
829             surface->use_pixmap = CAIRO_ASSUME_PIXMAP;
830     } else {
831         surface->use_pixmap--;
832         ximage = NULL;
833     }
834
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
840          * temporary pixmap
841          */
842         Pixmap pixmap;
843         GC gc;
844
845         status = _cairo_xlib_surface_get_gc (display, surface, &gc);
846         if (unlikely (status))
847             goto BAIL;
848
849         pixmap = XCreatePixmap (display->display,
850                                 surface->drawable,
851                                 extents->width, extents->height,
852                                 surface->depth);
853         if (pixmap) {
854             XGCValues gcv;
855
856             gcv.subwindow_mode = IncludeInferiors;
857             XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
858
859             XCopyArea (display->display, surface->drawable, pixmap, gc,
860                        extents->x, extents->y,
861                        extents->width, extents->height,
862                        0, 0);
863
864             gcv.subwindow_mode = ClipByChildren;
865             XChangeGC (display->display, gc, GCSubwindowMode, &gcv);
866
867             ximage = XGetImage (display->display,
868                                 pixmap,
869                                 0, 0,
870                                 extents->width, extents->height,
871                                 AllPlanes, ZPixmap);
872
873             XFreePixmap (display->display, pixmap);
874         }
875
876         _cairo_xlib_surface_put_gc (display, surface, gc);
877
878         if (ximage == NULL) {
879             status =  _cairo_error (CAIRO_STATUS_NO_MEMORY);
880             goto BAIL;
881         }
882     }
883
884     _swap_ximage_to_native (ximage);
885
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.
890      */
891     if (pixman_format &&
892         ximage->bitmap_unit == 32 && ximage->bitmap_pad == 32 &&
893         (surface->visual == NULL || surface->visual->class == TrueColor))
894     {
895         image = (cairo_image_surface_t*)
896             _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
897                                                             pixman_format,
898                                                             ximage->width,
899                                                             ximage->height,
900                                                             ximage->bytes_per_line);
901         status = image->base.status;
902         if (unlikely (status))
903             goto BAIL;
904
905         /* Let the surface take ownership of the data */
906         _cairo_image_surface_assume_ownership_of_data (image);
907         ximage->data = NULL;
908     } else {
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. */
912
913         cairo_format_t format;
914         unsigned char *data;
915         uint32_t *row;
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;
923
924         if (surface->visual == NULL || surface->visual->class == TrueColor) {
925             cairo_bool_t has_alpha;
926             cairo_bool_t has_color;
927
928             has_alpha =  surface->a_mask;
929             has_color = (surface->r_mask ||
930                          surface->g_mask ||
931                          surface->b_mask);
932
933             if (has_color) {
934                 if (has_alpha) {
935                     format = CAIRO_FORMAT_ARGB32;
936                 } else {
937                     format = CAIRO_FORMAT_RGB24;
938                 }
939             } else {
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;
945             }
946
947             a_mask = surface->a_mask;
948             r_mask = surface->r_mask;
949             g_mask = surface->g_mask;
950             b_mask = surface->b_mask;
951
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);
956
957         } else {
958             format = CAIRO_FORMAT_RGB24;
959
960             status = _cairo_xlib_screen_get_visual_info (display,
961                                                          surface->screen,
962                                                          surface->visual,
963                                                          &visual_info);
964             if (unlikely (status))
965                 goto BAIL;
966         }
967
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))
972             goto BAIL;
973
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);
980              y < ximage->height;
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]);
984                  x < ximage->width;
985                  x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0])) {
986                 int dither_adjustment = dither_row[x_off];
987
988                 in_pixel = XGetPixel (ximage, x, y);
989                 if (visual_info == NULL) {
990                     out_pixel = (
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));
995                 } else {
996                     /* Undithering pseudocolor does not look better */
997                     out_pixel = _pseudocolor_to_rgb888 (visual_info, in_pixel);
998                 }
999                 row[x] = out_pixel;
1000             }
1001             row += rowstride;
1002         }
1003         cairo_surface_mark_dirty (&image->base);
1004     }
1005
1006  BAIL:
1007     if (ximage)
1008         XDestroyImage (ximage);
1009
1010     cairo_device_release (&display->base);
1011
1012     if (unlikely (status)) {
1013         cairo_surface_destroy (&image->base);
1014         return _cairo_surface_create_in_error (status);
1015     }
1016
1017     return &image->base;
1018 }
1019
1020 void
1021 _cairo_xlib_surface_set_precision (cairo_xlib_surface_t *surface,
1022                                    cairo_antialias_t     antialias)
1023 {
1024     cairo_xlib_display_t        *display = surface->display;
1025     int precision;
1026
1027     if (display->force_precision != -1)
1028             precision = display->force_precision;
1029     else switch (antialias) {
1030     default:
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;
1037         break;
1038     case CAIRO_ANTIALIAS_BEST:
1039     case CAIRO_ANTIALIAS_SUBPIXEL:
1040         precision = PolyModePrecise;
1041         break;
1042     }
1043
1044     if (surface->precision != precision) {
1045         XRenderPictureAttributes pa;
1046
1047         pa.poly_mode = precision;
1048         XRenderChangePicture (display->display, surface->picture,
1049                               CPPolyMode, &pa);
1050
1051         surface->precision = precision;
1052     }
1053 }
1054
1055 void
1056 _cairo_xlib_surface_ensure_picture (cairo_xlib_surface_t    *surface)
1057 {
1058     cairo_xlib_display_t *display = surface->display;
1059     XRenderPictureAttributes pa;
1060     int mask = 0;
1061
1062     if (surface->picture)
1063         return;
1064
1065     if (display->force_precision != -1)
1066         pa.poly_mode = display->force_precision;
1067     else
1068         pa.poly_mode = PolyModeImprecise;
1069     if (pa.poly_mode)
1070             mask |= CPPolyMode;
1071
1072     surface->precision = pa.poly_mode;
1073     surface->picture = XRenderCreatePicture (display->display,
1074                                              surface->drawable,
1075                                              surface->xrender_format,
1076                                              mask, &pa);
1077 }
1078
1079 cairo_status_t
1080 _cairo_xlib_surface_draw_image (cairo_xlib_surface_t   *surface,
1081                                 cairo_image_surface_t  *image,
1082                                 int                    src_x,
1083                                 int                    src_y,
1084                                 int                    width,
1085                                 int                    height,
1086                                 int                    dst_x,
1087                                 int                    dst_y)
1088 {
1089     cairo_xlib_display_t *display;
1090     XImage ximage;
1091     cairo_format_masks_t image_masks;
1092     int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst;
1093     pixman_image_t *pixman_image = NULL;
1094     cairo_status_t status;
1095     cairo_bool_t own_data;
1096     cairo_bool_t is_rgb_image;
1097     GC gc;
1098
1099     ximage.width = image->width;
1100     ximage.height = image->height;
1101     ximage.format = ZPixmap;
1102     ximage.byte_order = native_byte_order;
1103     ximage.bitmap_unit = 32;    /* always for libpixman */
1104     ximage.bitmap_bit_order = native_byte_order;
1105     ximage.bitmap_pad = 32;     /* always for libpixman */
1106     ximage.depth = surface->depth;
1107     ximage.red_mask = surface->r_mask;
1108     ximage.green_mask = surface->g_mask;
1109     ximage.blue_mask = surface->b_mask;
1110     ximage.xoffset = 0;
1111     ximage.obdata = NULL;
1112
1113     status = _cairo_xlib_display_acquire (surface->base.device, &display);
1114     if (unlikely (status))
1115         return status;
1116
1117     is_rgb_image = _pixman_format_to_masks (image->pixman_format, &image_masks);
1118
1119     if (is_rgb_image &&
1120         (image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) &&
1121         (image_masks.red_mask   == surface->r_mask || surface->r_mask == 0) &&
1122         (image_masks.green_mask == surface->g_mask || surface->g_mask == 0) &&
1123         (image_masks.blue_mask  == surface->b_mask || surface->b_mask == 0))
1124     {
1125         int ret;
1126
1127         ximage.bits_per_pixel = image_masks.bpp;
1128         ximage.bytes_per_line = image->stride;
1129         ximage.data = (char *)image->data;
1130         if (image->base.device == surface->base.device)
1131             ximage.obdata = _cairo_xlib_shm_surface_get_obdata (&image->base);
1132         own_data = FALSE;
1133
1134         ret = XInitImage (&ximage);
1135         assert (ret != 0);
1136     }
1137     else if (surface->visual == NULL || surface->visual->class == TrueColor)
1138     {
1139         pixman_format_code_t intermediate_format;
1140         int ret;
1141
1142         image_masks.alpha_mask = surface->a_mask;
1143         image_masks.red_mask   = surface->r_mask;
1144         image_masks.green_mask = surface->g_mask;
1145         image_masks.blue_mask  = surface->b_mask;
1146         image_masks.bpp        = bits_per_pixel (surface);
1147         ret = _pixman_format_from_masks (&image_masks, &intermediate_format);
1148         assert (ret);
1149
1150         own_data = FALSE;
1151
1152         pixman_image = pixman_image_create_bits (intermediate_format,
1153                                                  width, height, NULL, 0);
1154         if (pixman_image == NULL) {
1155             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1156             goto BAIL;
1157         }
1158
1159         pixman_image_composite32 (PIXMAN_OP_SRC,
1160                                   image->pixman_image,
1161                                   NULL,
1162                                   pixman_image,
1163                                   src_x, src_y,
1164                                   0, 0,
1165                                   0, 0,
1166                                   width, height);
1167
1168         ximage.width = width;
1169         ximage.height = height;
1170         ximage.bits_per_pixel = image_masks.bpp;
1171         ximage.data = (char *) pixman_image_get_data (pixman_image);
1172         ximage.bytes_per_line = pixman_image_get_stride (pixman_image);
1173
1174         ret = XInitImage (&ximage);
1175         assert (ret != 0);
1176
1177         src_x = src_y = 0;
1178     }
1179     else
1180     {
1181         unsigned int stride, rowstride;
1182         int x, y, x0, y0, x_off, y_off;
1183         uint32_t in_pixel, out_pixel, *row;
1184         int i_a_width=0, i_r_width=0, i_g_width=0, i_b_width=0;
1185         int i_a_shift=0, i_r_shift=0, i_g_shift=0, i_b_shift=0;
1186         int o_a_width=0, o_r_width=0, o_g_width=0, o_b_width=0;
1187         int o_a_shift=0, o_r_shift=0, o_g_shift=0, o_b_shift=0;
1188         cairo_xlib_visual_info_t *visual_info = NULL;
1189         cairo_bool_t true_color;
1190         int ret;
1191
1192         ximage.bits_per_pixel = bits_per_pixel(surface);
1193         stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
1194                                              ximage.bits_per_pixel);
1195         ximage.bytes_per_line = stride;
1196         ximage.data = _cairo_malloc_ab (stride, ximage.height);
1197         if (unlikely (ximage.data == NULL)) {
1198             own_data = FALSE;
1199             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1200             goto BAIL;
1201         }
1202
1203         own_data = TRUE;
1204
1205         ret = XInitImage (&ximage);
1206         assert (ret != 0);
1207
1208         _characterize_field (image_masks.alpha_mask, &i_a_width, &i_a_shift);
1209         _characterize_field (image_masks.red_mask  , &i_r_width, &i_r_shift);
1210         _characterize_field (image_masks.green_mask, &i_g_width, &i_g_shift);
1211         _characterize_field (image_masks.blue_mask , &i_b_width, &i_b_shift);
1212
1213         true_color = surface->visual == NULL ||
1214                      surface->visual->class == TrueColor;
1215         if (true_color) {
1216             _characterize_field (surface->a_mask, &o_a_width, &o_a_shift);
1217             _characterize_field (surface->r_mask, &o_r_width, &o_r_shift);
1218             _characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
1219             _characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
1220         } else {
1221             status = _cairo_xlib_screen_get_visual_info (display,
1222                                                          surface->screen,
1223                                                          surface->visual,
1224                                                          &visual_info);
1225             if (unlikely (status))
1226                 goto BAIL;
1227         }
1228
1229         rowstride = image->stride >> 2;
1230         row = (uint32_t *) image->data;
1231         x0 = dst_x + surface->base.device_transform.x0;
1232         y0 = dst_y + surface->base.device_transform.y0;
1233         for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
1234              y < ximage.height;
1235              y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern))
1236         {
1237             const int8_t *dither_row = dither_pattern[y_off];
1238
1239             for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]);
1240                  x < ximage.width;
1241                  x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0]))
1242             {
1243                 int dither_adjustment = dither_row[x_off];
1244                 int a, r, g, b;
1245
1246                 if (image_masks.bpp == 1)
1247                     in_pixel = !! (((uint8_t*)row)[x/8] & (1 << (x & 7)));
1248                 else if (image_masks.bpp <= 8)
1249                     in_pixel = ((uint8_t*)row)[x];
1250                 else if (image_masks.bpp <= 16)
1251                     in_pixel = ((uint16_t*)row)[x];
1252                 else if (image_masks.bpp <= 24)
1253 #ifdef WORDS_BIGENDIAN
1254                     in_pixel = ((uint8_t*)row)[3 * x]     << 16 |
1255                                ((uint8_t*)row)[3 * x + 1] << 8  |
1256                                ((uint8_t*)row)[3 * x + 2];
1257 #else
1258                     in_pixel = ((uint8_t*)row)[3 * x]           |
1259                                ((uint8_t*)row)[3 * x + 1] << 8  |
1260                                ((uint8_t*)row)[3 * x + 2] << 16;
1261 #endif
1262                 else
1263                     in_pixel = row[x];
1264
1265                 /* If the incoming image has no alpha channel, then the input
1266                  * is opaque and the output should have the maximum alpha value.
1267                  * For all other channels, their absence implies 0.
1268                  */
1269                 if (image_masks.alpha_mask == 0x0)
1270                     a = 0xff;
1271                 else
1272                     a = _field_to_8 (in_pixel & image_masks.alpha_mask, i_a_width, i_a_shift);
1273                 r = _field_to_8 (in_pixel & image_masks.red_mask  , i_r_width, i_r_shift);
1274                 g = _field_to_8 (in_pixel & image_masks.green_mask, i_g_width, i_g_shift);
1275                 b = _field_to_8 (in_pixel & image_masks.blue_mask , i_b_width, i_b_shift);
1276
1277                 if (true_color) {
1278                     out_pixel = _field_from_8        (a, o_a_width, o_a_shift) |
1279                                 _field_from_8_dither (r, o_r_width, o_r_shift, dither_adjustment) |
1280                                 _field_from_8_dither (g, o_g_width, o_g_shift, dither_adjustment) |
1281                                 _field_from_8_dither (b, o_b_width, o_b_shift, dither_adjustment);
1282                 } else {
1283                     out_pixel = _pseudocolor_from_rgb888_dither (visual_info, r, g, b, dither_adjustment);
1284                 }
1285
1286                 XPutPixel (&ximage, x, y, out_pixel);
1287             }
1288
1289             row += rowstride;
1290         }
1291     }
1292
1293     status = _cairo_xlib_surface_get_gc (display, surface, &gc);
1294     if (unlikely (status))
1295         goto BAIL;
1296
1297     if (ximage.obdata)
1298         XShmPutImage (display->display, surface->drawable, gc, &ximage,
1299                       src_x, src_y, dst_x, dst_y, width, height, TRUE);
1300     else
1301         XPutImage (display->display, surface->drawable, gc, &ximage,
1302                    src_x, src_y, dst_x, dst_y, width, height);
1303
1304     _cairo_xlib_surface_put_gc (display, surface, gc);
1305
1306   BAIL:
1307     cairo_device_release (&display->base);
1308
1309     if (own_data)
1310         free (ximage.data);
1311     if (pixman_image)
1312         pixman_image_unref (pixman_image);
1313
1314     return CAIRO_STATUS_SUCCESS;
1315 }
1316
1317 static cairo_surface_t *
1318 _cairo_xlib_surface_source(void                    *abstract_surface,
1319                            cairo_rectangle_int_t *extents)
1320 {
1321     cairo_xlib_surface_t *surface = abstract_surface;
1322
1323     if (extents) {
1324         extents->x = extents->y = 0;
1325         extents->width  = surface->width;
1326         extents->height = surface->height;
1327     }
1328
1329     return &surface->base;
1330 }
1331
1332 static cairo_status_t
1333 _cairo_xlib_surface_acquire_source_image (void                    *abstract_surface,
1334                                           cairo_image_surface_t  **image_out,
1335                                           void                   **image_extra)
1336 {
1337     cairo_xlib_surface_t *surface = abstract_surface;
1338     cairo_rectangle_int_t extents;
1339
1340     *image_extra = NULL;
1341     *image_out = (cairo_image_surface_t *)
1342         _cairo_xlib_surface_get_shm (abstract_surface, FALSE);
1343     if (*image_out) 
1344             return (*image_out)->base.status;
1345
1346     extents.x = extents.y = 0;
1347     extents.width = surface->width;
1348     extents.height = surface->height;
1349
1350     *image_out = (cairo_image_surface_t*)
1351         _get_image_surface (surface, &extents, TRUE);
1352     return (*image_out)->base.status;
1353 }
1354
1355 static cairo_surface_t *
1356 _cairo_xlib_surface_snapshot (void *abstract_surface)
1357 {
1358     cairo_xlib_surface_t *surface = abstract_surface;
1359     cairo_rectangle_int_t extents;
1360
1361     extents.x = extents.y = 0;
1362     extents.width = surface->width;
1363     extents.height = surface->height;
1364
1365     return _get_image_surface (surface, &extents, FALSE);
1366 }
1367
1368 static void
1369 _cairo_xlib_surface_release_source_image (void                   *abstract_surface,
1370                                           cairo_image_surface_t  *image,
1371                                           void                   *image_extra)
1372 {
1373     cairo_xlib_surface_t *surface = abstract_surface;
1374
1375     if (&image->base == surface->shm)
1376         return;
1377
1378     cairo_surface_destroy (&image->base);
1379 }
1380
1381 static cairo_image_surface_t *
1382 _cairo_xlib_surface_map_to_image (void                    *abstract_surface,
1383                                   const cairo_rectangle_int_t   *extents)
1384 {
1385     cairo_xlib_surface_t *surface = abstract_surface;
1386     cairo_surface_t *image;
1387
1388     image = _cairo_xlib_surface_get_shm (abstract_surface, FALSE);
1389     if (image) {
1390         assert (surface->base.damage);
1391         surface->fallback++;
1392         return _cairo_image_surface_map_to_image (image, extents);
1393     }
1394
1395     image = _get_image_surface (abstract_surface, extents, TRUE);
1396     cairo_surface_set_device_offset (image, -extents->x, -extents->y);
1397
1398     return (cairo_image_surface_t *) image;
1399 }
1400
1401 static cairo_int_status_t
1402 _cairo_xlib_surface_unmap_image (void *abstract_surface,
1403                                  cairo_image_surface_t *image)
1404 {
1405     cairo_xlib_surface_t *surface = abstract_surface;
1406     cairo_int_status_t status;
1407
1408     if (surface->shm) {
1409         cairo_rectangle_int_t r;
1410
1411         assert (surface->fallback);
1412         assert (surface->base.damage);
1413
1414         r.x = image->base.device_transform_inverse.x0;
1415         r.y = image->base.device_transform_inverse.y0;
1416         r.width  = image->width;
1417         r.height = image->height;
1418
1419         TRACE ((stderr, "%s: adding damage (%d,%d)x(%d,%d)\n",
1420                 __FUNCTION__, r.x, r.y, r.width, r.height));
1421         surface->shm->damage =
1422             _cairo_damage_add_rectangle (surface->shm->damage, &r);
1423
1424         return _cairo_image_surface_unmap_image (surface->shm, image);
1425     }
1426
1427     status = _cairo_xlib_surface_draw_image (abstract_surface, image,
1428                                              0, 0,
1429                                              image->width, image->height,
1430                                              image->base.device_transform_inverse.x0,
1431                                              image->base.device_transform_inverse.y0);
1432
1433     cairo_surface_finish (&image->base);
1434     cairo_surface_destroy (&image->base);
1435
1436     return status;
1437 }
1438
1439 static cairo_status_t
1440 _cairo_xlib_surface_flush (void *abstract_surface,
1441                            unsigned flags)
1442 {
1443     cairo_xlib_surface_t *surface = abstract_surface;
1444     cairo_int_status_t status;
1445
1446     if (flags)
1447         return CAIRO_STATUS_SUCCESS;
1448
1449     status = _cairo_xlib_surface_put_shm (surface);
1450     if (unlikely (status))
1451         return status;
1452
1453     surface->fallback >>= 1;
1454     if (surface->shm && _cairo_xlib_shm_surface_is_idle (surface->shm))
1455         _cairo_xlib_surface_discard_shm (surface);
1456
1457     return CAIRO_STATUS_SUCCESS;
1458 }
1459
1460 static cairo_bool_t
1461 _cairo_xlib_surface_get_extents (void                    *abstract_surface,
1462                                  cairo_rectangle_int_t   *rectangle)
1463 {
1464     cairo_xlib_surface_t *surface = abstract_surface;
1465
1466     rectangle->x = 0;
1467     rectangle->y = 0;
1468
1469     rectangle->width  = surface->width;
1470     rectangle->height = surface->height;
1471
1472     return TRUE;
1473 }
1474
1475 static void
1476 _cairo_xlib_surface_get_font_options (void                  *abstract_surface,
1477                                       cairo_font_options_t  *options)
1478 {
1479     cairo_xlib_surface_t *surface = abstract_surface;
1480
1481     *options = *_cairo_xlib_screen_get_font_options (surface->screen);
1482 }
1483
1484 static inline cairo_int_status_t
1485 get_compositor (cairo_xlib_surface_t **surface,
1486                 const cairo_compositor_t **compositor)
1487 {
1488     cairo_xlib_surface_t *s = *surface;
1489     cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;;
1490
1491     if (s->fallback) {
1492         assert (s->base.damage != NULL);
1493         assert (s->shm != NULL);
1494         assert (s->shm->damage != NULL);
1495         if (! _cairo_xlib_shm_surface_is_active (s->shm)) {
1496             *surface = (cairo_xlib_surface_t *) s->shm;
1497             *compositor = ((cairo_image_surface_t *) s->shm)->compositor;
1498             s->fallback++;
1499         } else {
1500             status = _cairo_xlib_surface_put_shm (s);
1501             s->fallback = 0;
1502             *compositor = s->compositor;
1503         }
1504     } else
1505         *compositor = s->compositor;
1506
1507     return status;
1508 }
1509
1510 static cairo_int_status_t
1511 _cairo_xlib_surface_paint (void                         *_surface,
1512                            cairo_operator_t              op,
1513                            const cairo_pattern_t        *source,
1514                            const cairo_clip_t           *clip)
1515 {
1516     cairo_xlib_surface_t *surface = _surface;
1517     const cairo_compositor_t *compositor;
1518     cairo_int_status_t status;
1519
1520     status = get_compositor (&surface, &compositor);
1521     if (unlikely (status))
1522         return status;
1523
1524     return _cairo_compositor_paint (compositor, &surface->base,
1525                                     op, source,
1526                                     clip);
1527 }
1528
1529 static cairo_int_status_t
1530 _cairo_xlib_surface_mask (void                  *_surface,
1531                           cairo_operator_t       op,
1532                           const cairo_pattern_t *source,
1533                           const cairo_pattern_t *mask,
1534                           const cairo_clip_t    *clip)
1535 {
1536     cairo_xlib_surface_t *surface = _surface;
1537     const cairo_compositor_t *compositor;
1538     cairo_int_status_t status;
1539
1540     status = get_compositor (&surface, &compositor);
1541     if (unlikely (status))
1542         return status;
1543
1544     return _cairo_compositor_mask (compositor, &surface->base,
1545                                    op, source, mask,
1546                                    clip);
1547 }
1548
1549 static cairo_int_status_t
1550 _cairo_xlib_surface_stroke (void                        *_surface,
1551                             cairo_operator_t             op,
1552                             const cairo_pattern_t       *source,
1553                             const cairo_path_fixed_t    *path,
1554                             const cairo_stroke_style_t  *style,
1555                             const cairo_matrix_t        *ctm,
1556                             const cairo_matrix_t        *ctm_inverse,
1557                             double                       tolerance,
1558                             cairo_antialias_t            antialias,
1559                             const cairo_clip_t          *clip)
1560 {
1561     cairo_xlib_surface_t *surface = _surface;
1562     const cairo_compositor_t *compositor;
1563     cairo_int_status_t status;
1564
1565     status = get_compositor (&surface, &compositor);
1566     if (unlikely (status))
1567         return status;
1568
1569     return _cairo_compositor_stroke (compositor, &surface->base,
1570                                      op, source,
1571                                      path, style, ctm, ctm_inverse,
1572                                      tolerance, antialias,
1573                                      clip);
1574 }
1575
1576 static cairo_int_status_t
1577 _cairo_xlib_surface_fill (void                          *_surface,
1578                           cairo_operator_t               op,
1579                           const cairo_pattern_t         *source,
1580                           const cairo_path_fixed_t      *path,
1581                           cairo_fill_rule_t              fill_rule,
1582                           double                         tolerance,
1583                           cairo_antialias_t              antialias,
1584                           const cairo_clip_t            *clip)
1585 {
1586     cairo_xlib_surface_t *surface = _surface;
1587     const cairo_compositor_t *compositor;
1588     cairo_int_status_t status;
1589
1590     status = get_compositor (&surface, &compositor);
1591     if (unlikely (status))
1592         return status;
1593
1594     return _cairo_compositor_fill (compositor, &surface->base,
1595                                    op, source,
1596                                    path, fill_rule, tolerance, antialias,
1597                                    clip);
1598 }
1599
1600 static cairo_int_status_t
1601 _cairo_xlib_surface_glyphs (void                        *_surface,
1602                             cairo_operator_t             op,
1603                             const cairo_pattern_t       *source,
1604                             cairo_glyph_t               *glyphs,
1605                             int                          num_glyphs,
1606                             cairo_scaled_font_t         *scaled_font,
1607                             const cairo_clip_t          *clip)
1608 {
1609     cairo_xlib_surface_t *surface = _surface;
1610     const cairo_compositor_t *compositor;
1611     cairo_int_status_t status;
1612
1613     status = get_compositor (&surface, &compositor);
1614     if (unlikely (status))
1615         return status;
1616
1617     return _cairo_compositor_glyphs (compositor, &surface->base,
1618                                      op, source,
1619                                      glyphs, num_glyphs, scaled_font,
1620                                      clip);
1621 }
1622
1623 static const cairo_surface_backend_t cairo_xlib_surface_backend = {
1624     CAIRO_SURFACE_TYPE_XLIB,
1625     _cairo_xlib_surface_finish,
1626
1627     _cairo_default_context_create,
1628
1629     _cairo_xlib_surface_create_similar,
1630     _cairo_xlib_surface_create_similar_shm,
1631     _cairo_xlib_surface_map_to_image,
1632     _cairo_xlib_surface_unmap_image,
1633
1634     _cairo_xlib_surface_source,
1635     _cairo_xlib_surface_acquire_source_image,
1636     _cairo_xlib_surface_release_source_image,
1637     _cairo_xlib_surface_snapshot,
1638
1639     NULL, /* copy_page */
1640     NULL, /* show_page */
1641
1642     _cairo_xlib_surface_get_extents,
1643     _cairo_xlib_surface_get_font_options,
1644
1645     _cairo_xlib_surface_flush,
1646     NULL, /* mark_dirty_rectangle */
1647
1648     _cairo_xlib_surface_paint,
1649     _cairo_xlib_surface_mask,
1650     _cairo_xlib_surface_stroke,
1651     _cairo_xlib_surface_fill,
1652     NULL, /* fill-stroke */
1653     _cairo_xlib_surface_glyphs,
1654 };
1655
1656 /**
1657  * _cairo_surface_is_xlib:
1658  * @surface: a #cairo_surface_t
1659  *
1660  * Checks if a surface is a #cairo_xlib_surface_t
1661  *
1662  * Return value: True if the surface is an xlib surface
1663  **/
1664 static cairo_bool_t
1665 _cairo_surface_is_xlib (cairo_surface_t *surface)
1666 {
1667     return surface->backend == &cairo_xlib_surface_backend;
1668 }
1669
1670 static cairo_surface_t *
1671 _cairo_xlib_surface_create_internal (cairo_xlib_screen_t        *screen,
1672                                      Drawable                    drawable,
1673                                      Visual                     *visual,
1674                                      XRenderPictFormat          *xrender_format,
1675                                      int                         width,
1676                                      int                         height,
1677                                      int                         depth)
1678 {
1679     cairo_xlib_surface_t *surface;
1680     cairo_xlib_display_t *display;
1681     cairo_status_t status;
1682
1683     if (depth == 0) {
1684         if (xrender_format) {
1685             depth = xrender_format->depth;
1686
1687             /* XXX find matching visual for core/dithering fallbacks? */
1688         } else if (visual) {
1689             Screen *scr = screen->screen;
1690
1691             if (visual == DefaultVisualOfScreen (scr)) {
1692                 depth = DefaultDepthOfScreen (scr);
1693             } else  {
1694                 int j, k;
1695
1696                 /* This is ugly, but we have to walk over all visuals
1697                  * for the display to find the correct depth.
1698                  */
1699                 depth = 0;
1700                 for (j = 0; j < scr->ndepths; j++) {
1701                     Depth *d = &scr->depths[j];
1702                     for (k = 0; k < d->nvisuals; k++) {
1703                         if (&d->visuals[k] == visual) {
1704                             depth = d->depth;
1705                             goto found;
1706                         }
1707                     }
1708                 }
1709             }
1710         }
1711
1712         if (depth == 0)
1713             return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1714
1715 found:
1716         ;
1717     }
1718
1719     surface = malloc (sizeof (cairo_xlib_surface_t));
1720     if (unlikely (surface == NULL))
1721         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1722
1723     status = _cairo_xlib_display_acquire (screen->device, &display);
1724     if (unlikely (status)) {
1725         free (surface);
1726         return _cairo_surface_create_in_error (_cairo_error (status));
1727     }
1728
1729     surface->display = display;
1730     if (CAIRO_RENDER_HAS_CREATE_PICTURE (display)) {
1731         if (!xrender_format) {
1732             if (visual) {
1733                 xrender_format = XRenderFindVisualFormat (display->display, visual);
1734             } else if (depth == 1) {
1735                 xrender_format =
1736                     _cairo_xlib_display_get_xrender_format (display,
1737                                                             CAIRO_FORMAT_A1);
1738             }
1739         }
1740     }
1741
1742     cairo_device_release (&display->base);
1743
1744     _cairo_surface_init (&surface->base,
1745                          &cairo_xlib_surface_backend,
1746                          screen->device,
1747                          _xrender_format_to_content (xrender_format));
1748
1749     surface->screen = screen;
1750     surface->compositor = display->compositor;
1751     surface->shm = NULL;
1752     surface->fallback = 0;
1753
1754     surface->drawable = drawable;
1755     surface->owns_pixmap = FALSE;
1756     surface->use_pixmap = 0;
1757     surface->width = width;
1758     surface->height = height;
1759
1760     surface->picture = None;
1761     surface->precision = PolyModePrecise;
1762
1763     surface->embedded_source.picture = None;
1764
1765     surface->visual = visual;
1766     surface->xrender_format = xrender_format;
1767     surface->depth = depth;
1768
1769     /*
1770      * Compute the pixel format masks from either a XrenderFormat or
1771      * else from a visual; failing that we assume the drawable is an
1772      * alpha-only pixmap as it could only have been created that way
1773      * through the cairo_xlib_surface_create_for_bitmap function.
1774      */
1775     if (xrender_format) {
1776         surface->a_mask = (unsigned long)
1777             surface->xrender_format->direct.alphaMask
1778             << surface->xrender_format->direct.alpha;
1779         surface->r_mask = (unsigned long)
1780             surface->xrender_format->direct.redMask
1781             << surface->xrender_format->direct.red;
1782         surface->g_mask = (unsigned long)
1783             surface->xrender_format->direct.greenMask
1784             << surface->xrender_format->direct.green;
1785         surface->b_mask = (unsigned long)
1786             surface->xrender_format->direct.blueMask
1787             << surface->xrender_format->direct.blue;
1788     } else if (visual) {
1789         surface->a_mask = 0;
1790         surface->r_mask = visual->red_mask;
1791         surface->g_mask = visual->green_mask;
1792         surface->b_mask = visual->blue_mask;
1793     } else {
1794         if (depth < 32)
1795             surface->a_mask = (1 << depth) - 1;
1796         else
1797             surface->a_mask = 0xffffffff;
1798         surface->r_mask = 0;
1799         surface->g_mask = 0;
1800         surface->b_mask = 0;
1801     }
1802
1803     cairo_list_add (&surface->link, &screen->surfaces);
1804
1805     return &surface->base;
1806 }
1807
1808 static Screen *
1809 _cairo_xlib_screen_from_visual (Display *dpy, Visual *visual)
1810 {
1811     int s, d, v;
1812
1813     for (s = 0; s < ScreenCount (dpy); s++) {
1814         Screen *screen;
1815
1816         screen = ScreenOfDisplay (dpy, s);
1817         if (visual == DefaultVisualOfScreen (screen))
1818             return screen;
1819
1820         for (d = 0; d < screen->ndepths; d++) {
1821             Depth  *depth;
1822
1823             depth = &screen->depths[d];
1824             for (v = 0; v < depth->nvisuals; v++)
1825                 if (visual == &depth->visuals[v])
1826                     return screen;
1827         }
1828     }
1829
1830     return NULL;
1831 }
1832
1833 static cairo_bool_t valid_size (int width, int height)
1834 {
1835     /* Note: the minimum surface size allowed in the X protocol is 1x1.
1836      * However, as we historically did not check the minimum size we
1837      * allowed applications to lie and set the correct size later (one hopes).
1838      * To preserve compatability we must allow applications to use
1839      * 0x0 surfaces.
1840      */
1841     return (width  >= 0 && width  <= XLIB_COORD_MAX &&
1842             height >= 0 && height <= XLIB_COORD_MAX);
1843 }
1844
1845 /**
1846  * cairo_xlib_surface_create:
1847  * @dpy: an X Display
1848  * @drawable: an X Drawable, (a Pixmap or a Window)
1849  * @visual: the visual to use for drawing to @drawable. The depth
1850  *          of the visual must match the depth of the drawable.
1851  *          Currently, only TrueColor visuals are fully supported.
1852  * @width: the current width of @drawable.
1853  * @height: the current height of @drawable.
1854  *
1855  * Creates an Xlib surface that draws to the given drawable.
1856  * The way that colors are represented in the drawable is specified
1857  * by the provided visual.
1858  *
1859  * Note: If @drawable is a Window, then the function
1860  * cairo_xlib_surface_set_size() must be called whenever the size of the
1861  * window changes.
1862  *
1863  * When @drawable is a Window containing child windows then drawing to
1864  * the created surface will be clipped by those child windows.  When
1865  * the created surface is used as a source, the contents of the
1866  * children will be included.
1867  *
1868  * Return value: the newly created surface
1869  *
1870  * Since: 1.0
1871  **/
1872 cairo_surface_t *
1873 cairo_xlib_surface_create (Display     *dpy,
1874                            Drawable     drawable,
1875                            Visual      *visual,
1876                            int          width,
1877                            int          height)
1878 {
1879     Screen *scr;
1880     cairo_xlib_screen_t *screen;
1881     cairo_status_t status;
1882
1883     if (! valid_size (width, height)) {
1884         /* you're lying, and you know it! */
1885         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1886     }
1887
1888     scr = _cairo_xlib_screen_from_visual (dpy, visual);
1889     if (scr == NULL)
1890         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
1891
1892     status = _cairo_xlib_screen_get (dpy, scr, &screen);
1893     if (unlikely (status))
1894         return _cairo_surface_create_in_error (status);
1895
1896     X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable));
1897
1898     return _cairo_xlib_surface_create_internal (screen, drawable,
1899                                                 visual, NULL,
1900                                                 width, height, 0);
1901 }
1902
1903 /**
1904  * cairo_xlib_surface_create_for_bitmap:
1905  * @dpy: an X Display
1906  * @bitmap: an X Drawable, (a depth-1 Pixmap)
1907  * @screen: the X Screen associated with @bitmap
1908  * @width: the current width of @bitmap.
1909  * @height: the current height of @bitmap.
1910  *
1911  * Creates an Xlib surface that draws to the given bitmap.
1912  * This will be drawn to as a %CAIRO_FORMAT_A1 object.
1913  *
1914  * Return value: the newly created surface
1915  *
1916  * Since: 1.0
1917  **/
1918 cairo_surface_t *
1919 cairo_xlib_surface_create_for_bitmap (Display  *dpy,
1920                                       Pixmap    bitmap,
1921                                       Screen   *scr,
1922                                       int       width,
1923                                       int       height)
1924 {
1925     cairo_xlib_screen_t *screen;
1926     cairo_status_t status;
1927
1928     if (! valid_size (width, height))
1929         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1930
1931     status = _cairo_xlib_screen_get (dpy, scr, &screen);
1932     if (unlikely (status))
1933         return _cairo_surface_create_in_error (status);
1934
1935     X_DEBUG ((dpy, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap));
1936
1937     return _cairo_xlib_surface_create_internal (screen, bitmap,
1938                                                 NULL, NULL,
1939                                                 width, height, 1);
1940 }
1941
1942 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
1943 /**
1944  * cairo_xlib_surface_create_with_xrender_format:
1945  * @dpy: an X Display
1946  * @drawable: an X Drawable, (a Pixmap or a Window)
1947  * @screen: the X Screen associated with @drawable
1948  * @format: the picture format to use for drawing to @drawable. The depth
1949  *          of @format must match the depth of the drawable.
1950  * @width: the current width of @drawable.
1951  * @height: the current height of @drawable.
1952  *
1953  * Creates an Xlib surface that draws to the given drawable.
1954  * The way that colors are represented in the drawable is specified
1955  * by the provided picture format.
1956  *
1957  * Note: If @drawable is a Window, then the function
1958  * cairo_xlib_surface_set_size() must be called whenever the size of the
1959  * window changes.
1960  *
1961  * Return value: the newly created surface
1962  *
1963  * Since: 1.0
1964  **/
1965 cairo_surface_t *
1966 cairo_xlib_surface_create_with_xrender_format (Display              *dpy,
1967                                                Drawable             drawable,
1968                                                Screen               *scr,
1969                                                XRenderPictFormat    *format,
1970                                                int                  width,
1971                                                int                  height)
1972 {
1973     cairo_xlib_screen_t *screen;
1974     cairo_status_t status;
1975
1976     if (! valid_size (width, height))
1977         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
1978
1979     status = _cairo_xlib_screen_get (dpy, scr, &screen);
1980     if (unlikely (status))
1981         return _cairo_surface_create_in_error (status);
1982
1983     X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable));
1984
1985     return _cairo_xlib_surface_create_internal (screen, drawable,
1986                                                 _visual_for_xrender_format (scr, format),
1987                                                 format, width, height, 0);
1988 }
1989
1990 /**
1991  * cairo_xlib_surface_get_xrender_format:
1992  * @surface: an xlib surface
1993  *
1994  * Gets the X Render picture format that @surface uses for rendering with the
1995  * X Render extension. If the surface was created by
1996  * cairo_xlib_surface_create_with_xrender_format() originally, the return
1997  * value is the format passed to that constructor.
1998  *
1999  * Return value: the XRenderPictFormat* associated with @surface,
2000  * or %NULL if the surface is not an xlib surface
2001  * or if the X Render extension is not available.
2002  *
2003  * Since: 1.6
2004  **/
2005 XRenderPictFormat *
2006 cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface)
2007 {
2008     cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
2009
2010     /* Throw an error for a non-xlib surface */
2011     if (! _cairo_surface_is_xlib (surface)) {
2012         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2013         return NULL;
2014     }
2015
2016     return xlib_surface->xrender_format;
2017 }
2018 #endif
2019
2020 /**
2021  * cairo_xlib_surface_set_size:
2022  * @surface: a #cairo_surface_t for the XLib backend
2023  * @width: the new width of the surface
2024  * @height: the new height of the surface
2025  *
2026  * Informs cairo of the new size of the X Drawable underlying the
2027  * surface. For a surface created for a Window (rather than a Pixmap),
2028  * this function must be called each time the size of the window
2029  * changes. (For a subwindow, you are normally resizing the window
2030  * yourself, but for a toplevel window, it is necessary to listen for
2031  * ConfigureNotify events.)
2032  *
2033  * A Pixmap can never change size, so it is never necessary to call
2034  * this function on a surface created for a Pixmap.
2035  *
2036  * Since: 1.0
2037  **/
2038 void
2039 cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface,
2040                              int              width,
2041                              int              height)
2042 {
2043     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2044     cairo_status_t status;
2045
2046     if (unlikely (abstract_surface->status))
2047         return;
2048     if (unlikely (abstract_surface->finished)) {
2049         _cairo_surface_set_error (abstract_surface,
2050                                   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2051         return;
2052     }
2053
2054     if (! _cairo_surface_is_xlib (abstract_surface)) {
2055         _cairo_surface_set_error (abstract_surface,
2056                                   _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
2057         return;
2058     }
2059
2060     if (surface->width == width && surface->height == height)
2061         return;
2062
2063     if (! valid_size (width, height)) {
2064         _cairo_surface_set_error (abstract_surface,
2065                                   _cairo_error (CAIRO_STATUS_INVALID_SIZE));
2066         return;
2067     }
2068
2069     status = _cairo_surface_flush (abstract_surface, 0);
2070     if (unlikely (status)) {
2071         _cairo_surface_set_error (abstract_surface, status);
2072         return;
2073     }
2074
2075     _cairo_xlib_surface_discard_shm (surface);
2076
2077     surface->width = width;
2078     surface->height = height;
2079 }
2080
2081 /**
2082  * cairo_xlib_surface_set_drawable:
2083  * @surface: a #cairo_surface_t for the XLib backend
2084  * @drawable: the new drawable for the surface
2085  * @width: the width of the new drawable
2086  * @height: the height of the new drawable
2087  *
2088  * Informs cairo of a new X Drawable underlying the
2089  * surface. The drawable must match the display, screen
2090  * and format of the existing drawable or the application
2091  * will get X protocol errors and will probably terminate.
2092  * No checks are done by this function to ensure this
2093  * compatibility.
2094  *
2095  * Since: 1.0
2096  **/
2097 void
2098 cairo_xlib_surface_set_drawable (cairo_surface_t   *abstract_surface,
2099                                  Drawable           drawable,
2100                                  int                width,
2101                                  int                height)
2102 {
2103     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
2104     cairo_status_t status;
2105
2106     if (unlikely (abstract_surface->status))
2107         return;
2108     if (unlikely (abstract_surface->finished)) {
2109         status = _cairo_surface_set_error (abstract_surface,
2110                                            _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2111         return;
2112     }
2113
2114     if (! _cairo_surface_is_xlib (abstract_surface)) {
2115         status = _cairo_surface_set_error (abstract_surface,
2116                                            _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
2117         return;
2118     }
2119
2120     if (! valid_size (width, height)) {
2121         status = _cairo_surface_set_error (abstract_surface,
2122                                            _cairo_error (CAIRO_STATUS_INVALID_SIZE));
2123         return;
2124     }
2125
2126     /* XXX: and what about this case? */
2127     if (surface->owns_pixmap)
2128         return;
2129
2130     status = _cairo_surface_flush (abstract_surface, 0);
2131     if (unlikely (status)) {
2132         _cairo_surface_set_error (abstract_surface, status);
2133         return;
2134     }
2135
2136     if (surface->drawable != drawable) {
2137         cairo_xlib_display_t *display;
2138
2139         status = _cairo_xlib_display_acquire (surface->base.device, &display);
2140         if (unlikely (status))
2141             return;
2142
2143         X_DEBUG ((display->display, "set_drawable (drawable=%x)", (unsigned int) drawable));
2144
2145         if (surface->picture != None) {
2146             XRenderFreePicture (display->display, surface->picture);
2147             if (unlikely (status)) {
2148                 status = _cairo_surface_set_error (&surface->base, status);
2149                 return;
2150             }
2151
2152             surface->picture = None;
2153         }
2154
2155         cairo_device_release (&display->base);
2156
2157         surface->drawable = drawable;
2158     }
2159
2160     if (surface->width != width || surface->height != height) {
2161         _cairo_xlib_surface_discard_shm (surface);
2162
2163         surface->width = width;
2164         surface->height = height;
2165     }
2166 }
2167
2168 /**
2169  * cairo_xlib_surface_get_display:
2170  * @surface: a #cairo_xlib_surface_t
2171  *
2172  * Get the X Display for the underlying X Drawable.
2173  *
2174  * Return value: the display.
2175  *
2176  * Since: 1.2
2177  **/
2178 Display *
2179 cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
2180 {
2181     if (! _cairo_surface_is_xlib (abstract_surface)) {
2182         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2183         return NULL;
2184     }
2185
2186     return ((cairo_xlib_display_t *) abstract_surface->device)->display;
2187 }
2188
2189 /**
2190  * cairo_xlib_surface_get_drawable:
2191  * @surface: a #cairo_xlib_surface_t
2192  *
2193  * Get the underlying X Drawable used for the surface.
2194  *
2195  * Return value: the drawable.
2196  *
2197  * Since: 1.2
2198  **/
2199 Drawable
2200 cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface)
2201 {
2202     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2203
2204     if (! _cairo_surface_is_xlib (abstract_surface)) {
2205         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2206         return 0;
2207     }
2208
2209     return surface->drawable;
2210 }
2211
2212 /**
2213  * cairo_xlib_surface_get_screen:
2214  * @surface: a #cairo_xlib_surface_t
2215  *
2216  * Get the X Screen for the underlying X Drawable.
2217  *
2218  * Return value: the screen.
2219  *
2220  * Since: 1.2
2221  **/
2222 Screen *
2223 cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
2224 {
2225     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2226
2227     if (! _cairo_surface_is_xlib (abstract_surface)) {
2228         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2229         return NULL;
2230     }
2231
2232     return surface->screen->screen;
2233 }
2234
2235 /**
2236  * cairo_xlib_surface_get_visual:
2237  * @surface: a #cairo_xlib_surface_t
2238  *
2239  * Gets the X Visual associated with @surface, suitable for use with the
2240  * underlying X Drawable.  If @surface was created by
2241  * cairo_xlib_surface_create(), the return value is the Visual passed to that
2242  * constructor.
2243  *
2244  * Return value: the Visual or %NULL if there is no appropriate Visual for
2245  * @surface.
2246  *
2247  * Since: 1.2
2248  **/
2249 Visual *
2250 cairo_xlib_surface_get_visual (cairo_surface_t *surface)
2251 {
2252     cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
2253
2254     if (! _cairo_surface_is_xlib (surface)) {
2255         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2256         return NULL;
2257     }
2258
2259     return xlib_surface->visual;
2260 }
2261
2262 /**
2263  * cairo_xlib_surface_get_depth:
2264  * @surface: a #cairo_xlib_surface_t
2265  *
2266  * Get the number of bits used to represent each pixel value.
2267  *
2268  * Return value: the depth of the surface in bits.
2269  *
2270  * Since: 1.2
2271  **/
2272 int
2273 cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
2274 {
2275     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2276
2277     if (! _cairo_surface_is_xlib (abstract_surface)) {
2278         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2279         return 0;
2280     }
2281
2282     return surface->depth;
2283 }
2284
2285 /**
2286  * cairo_xlib_surface_get_width:
2287  * @surface: a #cairo_xlib_surface_t
2288  *
2289  * Get the width of the X Drawable underlying the surface in pixels.
2290  *
2291  * Return value: the width of the surface in pixels.
2292  *
2293  * Since: 1.2
2294  **/
2295 int
2296 cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface)
2297 {
2298     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2299
2300     if (! _cairo_surface_is_xlib (abstract_surface)) {
2301         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2302         return 0;
2303     }
2304
2305     return surface->width;
2306 }
2307
2308 /**
2309  * cairo_xlib_surface_get_height:
2310  * @surface: a #cairo_xlib_surface_t
2311  *
2312  * Get the height of the X Drawable underlying the surface in pixels.
2313  *
2314  * Return value: the height of the surface in pixels.
2315  *
2316  * Since: 1.2
2317  **/
2318 int
2319 cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface)
2320 {
2321     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
2322
2323     if (! _cairo_surface_is_xlib (abstract_surface)) {
2324         _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
2325         return 0;
2326     }
2327
2328     return surface->height;
2329 }
2330
2331 #endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */