1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2002 University of Southern California
4 * Copyright © 2009 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it either under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation
9 * (the "LGPL") or, at your option, under the terms of the Mozilla
10 * Public License Version 1.1 (the "MPL"). If you do not alter this
11 * notice, a recipient may use your version of this file under either
12 * the MPL or the LGPL.
14 * You should have received a copy of the LGPL along with this library
15 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17 * You should have received a copy of the MPL along with this library
18 * in the file COPYING-MPL-1.1
20 * The contents of this file are subject to the Mozilla Public License
21 * Version 1.1 (the "License"); you may not use this file except in
22 * compliance with the License. You may obtain a copy of the License at
23 * http://www.mozilla.org/MPL/
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27 * the specific language governing rights and limitations.
29 * The Original Code is the cairo graphics library.
31 * The Initial Developer of the Original Code is University of Southern
35 * Carl D. Worth <cworth@cworth.org>
36 * Chris Wilson <chris@chris-wilson.co.uk>
41 #if CAIRO_HAS_XLIB_XCB_FUNCTIONS
43 #include "cairo-xlib.h"
44 #include "cairo-xcb.h"
46 #include "cairo-xcb-private.h"
47 #include "cairo-xlib-xrender-private.h"
49 #include "cairo-default-context-private.h"
50 #include "cairo-list-inline.h"
51 #include "cairo-image-surface-private.h"
52 #include "cairo-surface-backend-private.h"
54 #include <X11/Xlib-xcb.h>
55 #include <X11/Xlibint.h> /* For XESetCloseDisplay */
57 struct cairo_xlib_xcb_display_t
{
61 cairo_device_t
*xcb_device
;
66 typedef struct cairo_xlib_xcb_display_t cairo_xlib_xcb_display_t
;
68 /* List of all #cairo_xlib_xcb_display_t alive,
69 * protected by _cairo_xlib_display_mutex */
70 static cairo_list_t displays
;
72 static cairo_surface_t
*
73 _cairo_xlib_xcb_surface_create (void *dpy
,
77 cairo_surface_t
*xcb
);
79 static cairo_surface_t
*
80 _cairo_xlib_xcb_surface_create_similar (void *abstract_other
,
81 cairo_content_t content
,
85 cairo_xlib_xcb_surface_t
*other
= abstract_other
;
88 xcb
= other
->xcb
->base
.backend
->create_similar (other
->xcb
, content
, width
, height
);
89 if (unlikely (xcb
== NULL
|| xcb
->status
))
92 return _cairo_xlib_xcb_surface_create (other
->display
, other
->screen
, NULL
, NULL
, xcb
);
96 _cairo_xlib_xcb_surface_finish (void *abstract_surface
)
98 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
99 cairo_status_t status
;
101 cairo_surface_finish (&surface
->xcb
->base
);
102 status
= surface
->xcb
->base
.status
;
103 cairo_surface_destroy (&surface
->xcb
->base
);
109 static cairo_surface_t
*
110 _cairo_xlib_xcb_surface_create_similar_image (void *abstract_other
,
111 cairo_format_t format
,
115 cairo_xlib_xcb_surface_t
*surface
= abstract_other
;
116 return cairo_surface_create_similar_image (&surface
->xcb
->base
, format
, width
, height
);
119 static cairo_image_surface_t
*
120 _cairo_xlib_xcb_surface_map_to_image (void *abstract_surface
,
121 const cairo_rectangle_int_t
*extents
)
123 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
124 return _cairo_surface_map_to_image (&surface
->xcb
->base
, extents
);
127 static cairo_int_status_t
128 _cairo_xlib_xcb_surface_unmap (void *abstract_surface
,
129 cairo_image_surface_t
*image
)
131 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
132 return _cairo_surface_unmap_image (&surface
->xcb
->base
, image
);
135 static cairo_surface_t
*
136 _cairo_xlib_xcb_surface_source (void *abstract_surface
,
137 cairo_rectangle_int_t
*extents
)
139 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
140 return _cairo_surface_get_source (&surface
->xcb
->base
, extents
);
143 static cairo_status_t
144 _cairo_xlib_xcb_surface_acquire_source_image (void *abstract_surface
,
145 cairo_image_surface_t
**image_out
,
148 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
149 return _cairo_surface_acquire_source_image (&surface
->xcb
->base
,
150 image_out
, image_extra
);
154 _cairo_xlib_xcb_surface_release_source_image (void *abstract_surface
,
155 cairo_image_surface_t
*image_out
,
158 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
159 _cairo_surface_release_source_image (&surface
->xcb
->base
, image_out
, image_extra
);
163 _cairo_xlib_xcb_surface_get_extents (void *abstract_surface
,
164 cairo_rectangle_int_t
*extents
)
166 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
167 return _cairo_surface_get_extents (&surface
->xcb
->base
, extents
);
171 _cairo_xlib_xcb_surface_get_font_options (void *abstract_surface
,
172 cairo_font_options_t
*options
)
174 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
175 cairo_surface_get_font_options (&surface
->xcb
->base
, options
);
178 static cairo_int_status_t
179 _cairo_xlib_xcb_surface_paint (void *abstract_surface
,
181 const cairo_pattern_t
*source
,
182 const cairo_clip_t
*clip
)
184 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
185 return _cairo_surface_paint (&surface
->xcb
->base
, op
, source
, clip
);
188 static cairo_int_status_t
189 _cairo_xlib_xcb_surface_mask (void *abstract_surface
,
191 const cairo_pattern_t
*source
,
192 const cairo_pattern_t
*mask
,
193 const cairo_clip_t
*clip
)
195 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
196 return _cairo_surface_mask (&surface
->xcb
->base
, op
, source
, mask
, clip
);
199 static cairo_int_status_t
200 _cairo_xlib_xcb_surface_stroke (void *abstract_surface
,
202 const cairo_pattern_t
*source
,
203 const cairo_path_fixed_t
*path
,
204 const cairo_stroke_style_t
*style
,
205 const cairo_matrix_t
*ctm
,
206 const cairo_matrix_t
*ctm_inverse
,
208 cairo_antialias_t antialias
,
209 const cairo_clip_t
*clip
)
211 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
212 return _cairo_surface_stroke (&surface
->xcb
->base
,
213 op
, source
, path
, style
, ctm
, ctm_inverse
,
214 tolerance
, antialias
, clip
);
217 static cairo_int_status_t
218 _cairo_xlib_xcb_surface_fill (void *abstract_surface
,
220 const cairo_pattern_t
*source
,
221 const cairo_path_fixed_t
*path
,
222 cairo_fill_rule_t fill_rule
,
224 cairo_antialias_t antialias
,
225 const cairo_clip_t
*clip
)
227 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
228 return _cairo_surface_fill (&surface
->xcb
->base
,
230 fill_rule
, tolerance
,
234 static cairo_int_status_t
235 _cairo_xlib_xcb_surface_glyphs (void *abstract_surface
,
237 const cairo_pattern_t
*source
,
238 cairo_glyph_t
*glyphs
,
240 cairo_scaled_font_t
*scaled_font
,
241 const cairo_clip_t
*clip
)
243 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
244 return _cairo_surface_show_text_glyphs (&surface
->xcb
->base
, op
, source
,
251 static cairo_status_t
252 _cairo_xlib_xcb_surface_flush (void *abstract_surface
, unsigned flags
)
254 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
255 /* We have to call cairo_surface_flush() to make sure snapshots are detached */
256 return _cairo_surface_flush (&surface
->xcb
->base
, flags
);
259 static cairo_status_t
260 _cairo_xlib_xcb_surface_mark_dirty (void *abstract_surface
,
262 int width
, int height
)
264 cairo_xlib_xcb_surface_t
*surface
= abstract_surface
;
265 cairo_surface_mark_dirty_rectangle (&surface
->xcb
->base
, x
, y
, width
, height
);
266 return cairo_surface_status (&surface
->xcb
->base
);
269 static const cairo_surface_backend_t _cairo_xlib_xcb_surface_backend
= {
270 CAIRO_SURFACE_TYPE_XLIB
,
271 _cairo_xlib_xcb_surface_finish
,
273 _cairo_default_context_create
, /* XXX */
275 _cairo_xlib_xcb_surface_create_similar
,
276 _cairo_xlib_xcb_surface_create_similar_image
,
277 _cairo_xlib_xcb_surface_map_to_image
,
278 _cairo_xlib_xcb_surface_unmap
,
280 _cairo_xlib_xcb_surface_source
,
281 _cairo_xlib_xcb_surface_acquire_source_image
,
282 _cairo_xlib_xcb_surface_release_source_image
,
285 NULL
, /* copy_page */
286 NULL
, /* show_page */
288 _cairo_xlib_xcb_surface_get_extents
,
289 _cairo_xlib_xcb_surface_get_font_options
,
291 _cairo_xlib_xcb_surface_flush
,
292 _cairo_xlib_xcb_surface_mark_dirty
,
294 _cairo_xlib_xcb_surface_paint
,
295 _cairo_xlib_xcb_surface_mask
,
296 _cairo_xlib_xcb_surface_stroke
,
297 _cairo_xlib_xcb_surface_fill
,
298 NULL
, /* fill_stroke */
299 _cairo_xlib_xcb_surface_glyphs
,
303 _cairo_xlib_xcb_display_finish (void *abstract_display
)
305 cairo_xlib_xcb_display_t
*display
= (cairo_xlib_xcb_display_t
*) abstract_display
;
307 CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex
);
308 cairo_list_del (&display
->link
);
309 CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex
);
311 cairo_device_destroy (display
->xcb_device
);
312 display
->xcb_device
= NULL
;
314 XESetCloseDisplay (display
->dpy
, display
->codes
->extension
, NULL
);
315 /* Drop the reference from _cairo_xlib_xcb_device_create */
316 cairo_device_destroy (&display
->base
);
320 _cairo_xlib_xcb_close_display(Display
*dpy
, XExtCodes
*codes
)
322 cairo_xlib_xcb_display_t
*display
;
324 CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex
);
325 cairo_list_foreach_entry (display
,
326 cairo_xlib_xcb_display_t
,
330 if (display
->dpy
== dpy
)
332 /* _cairo_xlib_xcb_display_finish will lock the mutex again
333 * -> deadlock (This mutex isn't recursive) */
334 cairo_device_reference (&display
->base
);
335 CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex
);
337 /* Make sure the xcb and xlib-xcb devices are finished */
338 cairo_device_finish (display
->xcb_device
);
339 cairo_device_finish (&display
->base
);
341 cairo_device_destroy (&display
->base
);
345 CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex
);
350 static const cairo_device_backend_t _cairo_xlib_xcb_device_backend
= {
351 CAIRO_DEVICE_TYPE_XLIB
,
357 _cairo_xlib_xcb_display_finish
,
361 static cairo_device_t
*
362 _cairo_xlib_xcb_device_create (Display
*dpy
, cairo_device_t
*xcb_device
)
364 cairo_xlib_xcb_display_t
*display
= NULL
;
365 cairo_device_t
*device
;
367 if (xcb_device
== NULL
)
370 CAIRO_MUTEX_INITIALIZE ();
372 CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex
);
373 if (displays
.next
== NULL
) {
374 cairo_list_init (&displays
);
377 cairo_list_foreach_entry (display
,
378 cairo_xlib_xcb_display_t
,
382 if (display
->dpy
== dpy
) {
383 /* Maintain MRU order. */
384 if (displays
.next
!= &display
->link
)
385 cairo_list_move (&display
->link
, &displays
);
387 /* Grab a reference for our caller */
388 device
= cairo_device_reference (&display
->base
);
389 assert (display
->xcb_device
== xcb_device
);
394 display
= malloc (sizeof (cairo_xlib_xcb_display_t
));
395 if (unlikely (display
== NULL
)) {
396 device
= _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY
);
400 display
->codes
= XAddExtension (dpy
);
401 if (unlikely (display
->codes
== NULL
)) {
402 device
= _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY
);
407 _cairo_device_init (&display
->base
, &_cairo_xlib_xcb_device_backend
);
409 XESetCloseDisplay (dpy
, display
->codes
->extension
, _cairo_xlib_xcb_close_display
);
410 /* Add a reference for _cairo_xlib_xcb_display_finish. This basically means
411 * that the device's reference count never drops to zero
412 * as long as our Display* is alive. We need this because there is no
413 * "XDelExtension" to undo XAddExtension and having lots of registered
414 * extensions slows down libX11. */
415 cairo_device_reference (&display
->base
);
418 display
->xcb_device
= cairo_device_reference(xcb_device
);
420 cairo_list_add (&display
->link
, &displays
);
421 device
= &display
->base
;
424 CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex
);
429 static cairo_surface_t
*
430 _cairo_xlib_xcb_surface_create (void *dpy
,
434 cairo_surface_t
*xcb
)
436 cairo_xlib_xcb_surface_t
*surface
;
438 if (unlikely (xcb
->status
))
441 surface
= malloc (sizeof (*surface
));
442 if (unlikely (surface
== NULL
)) {
443 cairo_surface_destroy (xcb
);
444 return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY
);
447 _cairo_surface_init (&surface
->base
,
448 &_cairo_xlib_xcb_surface_backend
,
449 _cairo_xlib_xcb_device_create (dpy
, xcb
->device
),
452 /* _cairo_surface_init() got another reference to the device, drop ours */
453 cairo_device_destroy (surface
->base
.device
);
455 surface
->display
= dpy
;
456 surface
->screen
= scr
;
457 surface
->visual
= visual
;
458 surface
->format
= format
;
459 surface
->xcb
= (cairo_xcb_surface_t
*) xcb
;
461 return &surface
->base
;
465 _cairo_xlib_screen_from_visual (Display
*dpy
, Visual
*visual
)
469 for (s
= 0; s
< ScreenCount (dpy
); s
++) {
472 screen
= ScreenOfDisplay (dpy
, s
);
473 if (visual
== DefaultVisualOfScreen (screen
))
476 for (d
= 0; d
< screen
->ndepths
; d
++) {
479 depth
= &screen
->depths
[d
];
480 for (v
= 0; v
< depth
->nvisuals
; v
++)
481 if (visual
== &depth
->visuals
[v
])
490 cairo_xlib_surface_create (Display
*dpy
,
497 xcb_visualtype_t xcb_visual
;
499 scr
= _cairo_xlib_screen_from_visual (dpy
, visual
);
501 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL
));
503 xcb_visual
.visual_id
= visual
->visualid
;
504 #if defined(__cplusplus) || defined(c_plusplus)
505 xcb_visual
._class
= visual
->c_class
;
507 xcb_visual
._class
= visual
->class;
509 xcb_visual
.bits_per_rgb_value
= visual
->bits_per_rgb
;
510 xcb_visual
.colormap_entries
= visual
->map_entries
;
511 xcb_visual
.red_mask
= visual
->red_mask
;
512 xcb_visual
.green_mask
= visual
->green_mask
;
513 xcb_visual
.blue_mask
= visual
->blue_mask
;
515 return _cairo_xlib_xcb_surface_create (dpy
, scr
, visual
, NULL
,
516 cairo_xcb_surface_create (XGetXCBConnection (dpy
),
522 static xcb_screen_t
*
523 _cairo_xcb_screen_from_root (xcb_connection_t
*connection
,
526 xcb_screen_iterator_t s
;
528 s
= xcb_setup_roots_iterator (xcb_get_setup (connection
));
529 for (; s
.rem
; xcb_screen_next (&s
)) {
530 if (s
.data
->root
== id
)
538 cairo_xlib_surface_create_for_bitmap (Display
*dpy
,
544 xcb_connection_t
*connection
= XGetXCBConnection (dpy
);
545 xcb_screen_t
*screen
= _cairo_xcb_screen_from_root (connection
, (xcb_window_t
) scr
->root
);
546 return _cairo_xlib_xcb_surface_create (dpy
, scr
, NULL
, NULL
,
547 cairo_xcb_surface_create_for_bitmap (connection
,
553 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
555 cairo_xlib_surface_create_with_xrender_format (Display
*dpy
,
558 XRenderPictFormat
*format
,
562 xcb_render_pictforminfo_t xcb_format
;
563 xcb_connection_t
*connection
;
564 xcb_screen_t
*screen
;
566 xcb_format
.id
= format
->id
;
567 xcb_format
.type
= format
->type
;
568 xcb_format
.depth
= format
->depth
;
569 xcb_format
.direct
.red_shift
= format
->direct
.red
;
570 xcb_format
.direct
.red_mask
= format
->direct
.redMask
;
571 xcb_format
.direct
.green_shift
= format
->direct
.green
;
572 xcb_format
.direct
.green_mask
= format
->direct
.greenMask
;
573 xcb_format
.direct
.blue_shift
= format
->direct
.blue
;
574 xcb_format
.direct
.blue_mask
= format
->direct
.blueMask
;
575 xcb_format
.direct
.alpha_shift
= format
->direct
.alpha
;
576 xcb_format
.direct
.alpha_mask
= format
->direct
.alphaMask
;
577 xcb_format
.colormap
= format
->colormap
;
579 connection
= XGetXCBConnection (dpy
);
580 screen
= _cairo_xcb_screen_from_root (connection
, (xcb_window_t
) scr
->root
);
582 return _cairo_xlib_xcb_surface_create (dpy
, scr
, NULL
, format
,
583 cairo_xcb_surface_create_with_xrender_format (connection
, screen
,
590 cairo_xlib_surface_get_xrender_format (cairo_surface_t
*surface
)
592 cairo_xlib_xcb_surface_t
*xlib_surface
= (cairo_xlib_xcb_surface_t
*) surface
;
594 /* Throw an error for a non-xlib surface */
595 if (surface
->type
!= CAIRO_SURFACE_TYPE_XLIB
) {
596 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
600 return xlib_surface
->format
;
605 cairo_xlib_surface_set_size (cairo_surface_t
*abstract_surface
,
609 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
610 cairo_status_t status
;
612 if (unlikely (abstract_surface
->status
))
614 if (unlikely (abstract_surface
->finished
)) {
615 status
= _cairo_surface_set_error (abstract_surface
,
616 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED
));
620 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
621 status
= _cairo_surface_set_error (abstract_surface
,
622 CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
626 cairo_xcb_surface_set_size (&surface
->xcb
->base
, width
, height
);
627 if (unlikely (surface
->xcb
->base
.status
)) {
628 status
= _cairo_surface_set_error (abstract_surface
,
629 _cairo_error (surface
->xcb
->base
.status
));
634 cairo_xlib_surface_set_drawable (cairo_surface_t
*abstract_surface
,
639 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*)abstract_surface
;
640 cairo_status_t status
;
642 if (unlikely (abstract_surface
->status
))
644 if (unlikely (abstract_surface
->finished
)) {
645 status
= _cairo_surface_set_error (abstract_surface
,
646 _cairo_error (CAIRO_STATUS_SURFACE_FINISHED
));
650 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
651 status
= _cairo_surface_set_error (abstract_surface
,
652 CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
656 cairo_xcb_surface_set_drawable (&surface
->xcb
->base
, drawable
, width
, height
);
657 if (unlikely (surface
->xcb
->base
.status
)) {
658 status
= _cairo_surface_set_error (abstract_surface
,
659 _cairo_error (surface
->xcb
->base
.status
));
664 cairo_xlib_surface_get_display (cairo_surface_t
*abstract_surface
)
666 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
668 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
669 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
673 return surface
->display
;
677 cairo_xlib_surface_get_drawable (cairo_surface_t
*abstract_surface
)
679 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
681 if (unlikely (abstract_surface
->finished
)) {
682 _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED
);
685 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
686 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
689 /* This can happen when e.g. create_similar falls back to an image surface
690 * because we don't have the RENDER extension. */
691 if (surface
->xcb
->base
.type
!= CAIRO_SURFACE_TYPE_XCB
) {
692 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
696 return surface
->xcb
->drawable
;
700 cairo_xlib_surface_get_screen (cairo_surface_t
*abstract_surface
)
702 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
704 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
705 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
709 return surface
->screen
;
713 cairo_xlib_surface_get_visual (cairo_surface_t
*abstract_surface
)
715 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
717 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
718 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
722 return surface
->visual
;
726 cairo_xlib_surface_get_depth (cairo_surface_t
*abstract_surface
)
728 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
730 if (unlikely (abstract_surface
->finished
)) {
731 _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED
);
734 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
735 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
738 /* This can happen when e.g. create_similar falls back to an image surface
739 * because we don't have the RENDER extension. */
740 if (surface
->xcb
->base
.type
!= CAIRO_SURFACE_TYPE_XCB
) {
741 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
745 return surface
->xcb
->depth
;
749 cairo_xlib_surface_get_width (cairo_surface_t
*abstract_surface
)
751 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
753 if (unlikely (abstract_surface
->finished
)) {
754 _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED
);
757 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
758 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
761 /* This can happen when e.g. create_similar falls back to an image surface
762 * because we don't have the RENDER extension. */
763 if (surface
->xcb
->base
.type
!= CAIRO_SURFACE_TYPE_XCB
) {
764 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
768 return surface
->xcb
->width
;
772 cairo_xlib_surface_get_height (cairo_surface_t
*abstract_surface
)
774 cairo_xlib_xcb_surface_t
*surface
= (cairo_xlib_xcb_surface_t
*) abstract_surface
;
776 if (unlikely (abstract_surface
->finished
)) {
777 _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED
);
780 if (surface
->base
.type
!= CAIRO_SURFACE_TYPE_XLIB
) {
781 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
784 /* This can happen when e.g. create_similar falls back to an image surface
785 * because we don't have the RENDER extension. */
786 if (surface
->xcb
->base
.type
!= CAIRO_SURFACE_TYPE_XCB
) {
787 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
791 return surface
->xcb
->height
;
795 cairo_xlib_device_debug_cap_xrender_version (cairo_device_t
*device
,
796 int major
, int minor
)
798 cairo_xlib_xcb_display_t
*display
= (cairo_xlib_xcb_display_t
*) device
;
800 if (device
== NULL
|| device
->status
)
803 if (device
->backend
->type
!= CAIRO_DEVICE_TYPE_XLIB
)
806 cairo_xcb_device_debug_cap_xrender_version (display
->xcb_device
,
811 cairo_xlib_device_debug_set_precision (cairo_device_t
*device
,
814 cairo_xlib_xcb_display_t
*display
= (cairo_xlib_xcb_display_t
*) device
;
816 if (device
== NULL
|| device
->status
)
818 if (device
->backend
->type
!= CAIRO_DEVICE_TYPE_XLIB
) {
819 cairo_status_t status
;
821 status
= _cairo_device_set_error (device
, CAIRO_STATUS_DEVICE_TYPE_MISMATCH
);
826 cairo_xcb_device_debug_set_precision (display
->xcb_device
, precision
);
830 cairo_xlib_device_debug_get_precision (cairo_device_t
*device
)
832 cairo_xlib_xcb_display_t
*display
= (cairo_xlib_xcb_display_t
*) device
;
834 if (device
== NULL
|| device
->status
)
836 if (device
->backend
->type
!= CAIRO_DEVICE_TYPE_XLIB
) {
837 cairo_status_t status
;
839 status
= _cairo_device_set_error (device
, CAIRO_STATUS_DEVICE_TYPE_MISMATCH
);
844 return cairo_xcb_device_debug_get_precision (display
->xcb_device
);
847 #endif /* CAIRO_HAS_XLIB_XCB_FUNCTIONS */