Bug Summary

File:root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-surface.c
Warning:line 1254, column 6
Value stored to 'status' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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