Bug Summary

File:root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-display.c
Warning:line 133, column 22
Access to field 'display' results in a dereference of a null pointer (loaded from variable 'display')

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-display.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-display.c
1/* Cairo - a vector graphics library with display and print output
2 *
3 * Copyright © 2007 Chris Wilson
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it either under the terms of the GNU Lesser General Public
7 * License version 2.1 as published by the Free Software Foundation
8 * (the "LGPL") or, at your option, under the terms of the Mozilla
9 * Public License Version 1.1 (the "MPL"). If you do not alter this
10 * notice, a recipient may use your version of this file under either
11 * the MPL or the LGPL.
12 *
13 * You should have received a copy of the LGPL along with this library
14 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 * You should have received a copy of the MPL along with this library
17 * in the file COPYING-MPL-1.1
18 *
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License at
22 * http://www.mozilla.org/MPL/
23 *
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 * the specific language governing rights and limitations.
27 *
28 * The Original Code is the cairo graphics library.
29 *
30 * The Initial Developer of the Original Code is Chris Wilson.
31 *
32 * Contributor(s):
33 * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
34 */
35
36#include "cairoint.h"
37
38#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS
39
40#include "cairo-xlib-private.h"
41#include "cairo-xlib-xrender-private.h"
42#include "cairo-freelist-private.h"
43#include "cairo-error-private.h"
44#include "cairo-list-inline.h"
45
46#include <X11/Xlibint.h> /* For XESetCloseDisplay */
47
48typedef int (*cairo_xlib_error_func_t) (Display *display,
49 XErrorEvent *event);
50
51static cairo_xlib_display_t *_cairo_xlib_display_list;
52
53static int
54_noop_error_handler (Display *display,
55 XErrorEvent *event)
56{
57 return False0; /* return value is ignored */
58}
59
60static void
61_cairo_xlib_display_finish (void *abstract_display)
62{
63 cairo_xlib_display_t *display = abstract_display;
64 Display *dpy = display->display;
65
66 _cairo_xlib_display_fini_shm (display);
67
68 if (! cairo_device_acquire_moz_cairo_device_acquire (&display->base)) {
69 cairo_xlib_error_func_t old_handler;
70
71 /* protect the notifies from triggering XErrors */
72 XSync (dpy, False0);
73 old_handler = XSetErrorHandler (_noop_error_handler);
74
75 while (! cairo_list_is_empty (&display->fonts)) {
76 _cairo_xlib_font_close (cairo_list_first_entry (&display->fonts,({ const __typeof__ (((cairo_xlib_font_t *) 0)->link) *mptr__
= ((&display->fonts)->next); (cairo_xlib_font_t *)
((char *) mptr__ - __builtin_offsetof(cairo_xlib_font_t, link
)); })
77 cairo_xlib_font_t,({ const __typeof__ (((cairo_xlib_font_t *) 0)->link) *mptr__
= ((&display->fonts)->next); (cairo_xlib_font_t *)
((char *) mptr__ - __builtin_offsetof(cairo_xlib_font_t, link
)); })
78 link)({ const __typeof__ (((cairo_xlib_font_t *) 0)->link) *mptr__
= ((&display->fonts)->next); (cairo_xlib_font_t *)
((char *) mptr__ - __builtin_offsetof(cairo_xlib_font_t, link
)); })
);
79 }
80
81 while (! cairo_list_is_empty (&display->screens)) {
82 _cairo_xlib_screen_destroy (display,
83 cairo_list_first_entry (&display->screens,({ const __typeof__ (((cairo_xlib_screen_t *) 0)->link) *mptr__
= ((&display->screens)->next); (cairo_xlib_screen_t
*) ((char *) mptr__ - __builtin_offsetof(cairo_xlib_screen_t
, link)); })
84 cairo_xlib_screen_t,({ const __typeof__ (((cairo_xlib_screen_t *) 0)->link) *mptr__
= ((&display->screens)->next); (cairo_xlib_screen_t
*) ((char *) mptr__ - __builtin_offsetof(cairo_xlib_screen_t
, link)); })
85 link)({ const __typeof__ (((cairo_xlib_screen_t *) 0)->link) *mptr__
= ((&display->screens)->next); (cairo_xlib_screen_t
*) ((char *) mptr__ - __builtin_offsetof(cairo_xlib_screen_t
, link)); })
);
86 }
87
88 XSync (dpy, False0);
89 XSetErrorHandler (old_handler);
90
91 cairo_device_release_moz_cairo_device_release (&display->base);
92 }
93}
94
95static void
96_cairo_xlib_display_destroy (void *abstract_display)
97{
98 cairo_xlib_display_t *display = abstract_display;
99
100 free (display);
101}
102
103static int
104_cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
105{
106 cairo_xlib_display_t *display, **prev, *next;
107
108 CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex)pthread_mutex_lock (&(_cairo_xlib_display_mutex));
109 for (display = _cairo_xlib_display_list; display; display = display->next)
1
Loop condition is true. Entering loop body
110 if (display->display == dpy)
2
Assuming 'dpy' is equal to field 'display'
3
Taking true branch
111 break;
4
Execution continues on line 112
112 CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex)pthread_mutex_unlock (&(_cairo_xlib_display_mutex));
113 if (display
4.1
'display' is not equal to NULL
== NULL((void*)0))
5
Taking false branch
114 return 0;
115
116 cairo_device_finish_moz_cairo_device_finish (&display->base);
6
Value assigned to '_cairo_xlib_display_list'
117
118 /*
119 * Unhook from the global list
120 */
121 CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex)pthread_mutex_lock (&(_cairo_xlib_display_mutex));
122 prev = &_cairo_xlib_display_list;
123 for (display = _cairo_xlib_display_list; display; display = next) {
7
The value of '_cairo_xlib_display_list' is assigned to 'display'
8
Assuming pointer value is null
9
Loop condition is false. Execution continues on line 131
124 next = display->next;
125 if (display->display == dpy) {
126 *prev = next;
127 break;
128 } else
129 prev = &display->next;
130 }
131 CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex)pthread_mutex_unlock (&(_cairo_xlib_display_mutex));
132
133 display->display = NULL((void*)0); /* catch any later invalid access */
10
Access to field 'display' results in a dereference of a null pointer (loaded from variable 'display')
134 cairo_device_destroy_moz_cairo_device_destroy (&display->base);
135
136 /* Return value in accordance with requirements of
137 * XESetCloseDisplay */
138 return 0;
139}
140
141static const cairo_device_backend_t _cairo_xlib_device_backend = {
142 CAIRO_DEVICE_TYPE_XLIB,
143
144 NULL((void*)0),
145 NULL((void*)0),
146
147 NULL((void*)0), /* flush */
148 _cairo_xlib_display_finish,
149 _cairo_xlib_display_destroy,
150};
151
152static void _cairo_xlib_display_select_compositor (cairo_xlib_display_t *display)
153{
154#if 1
155 if (display->render_major > 0 || display->render_minor >= 4)
156 display->compositor = _cairo_xlib_traps_compositor_get ();
157 else if (display->render_major > 0 || display->render_minor >= 0)
158 display->compositor = _cairo_xlib_mask_compositor_get ();
159 else
160 display->compositor = _cairo_xlib_core_compositor_get ();
161#else
162 display->compositor = _cairo_xlib_fallback_compositor_get ();
163#endif
164}
165
166/**
167 * _cairo_xlib_device_create:
168 * @dpy: the display to create the device for
169 *
170 * Gets the device belonging to @dpy, or creates it if it doesn't exist yet.
171 *
172 * Returns: the device belonging to @dpy
173 **/
174cairo_device_t *
175_cairo_xlib_device_create (Display *dpy)
176{
177 cairo_xlib_display_t *display;
178 cairo_xlib_display_t **prev;
179 cairo_device_t *device;
180 XExtCodes *codes;
181 const char *env;
182
183 CAIRO_MUTEX_INITIALIZE ()do { } while (0);
184
185 /* There is an apparent deadlock between this mutex and the
186 * mutex for the display, but it's actually safe. For the
187 * app to call XCloseDisplay() while any other thread is
188 * inside this function would be an error in the logic
189 * app, and the CloseDisplay hook is the only other place we
190 * acquire this mutex.
191 */
192 CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex)pthread_mutex_lock (&(_cairo_xlib_display_mutex));
193
194 for (prev = &_cairo_xlib_display_list; (display = *prev); prev = &(*prev)->next)
195 {
196 if (display->display == dpy) {
197 /*
198 * MRU the list
199 */
200 if (prev != &_cairo_xlib_display_list) {
201 *prev = display->next;
202 display->next = _cairo_xlib_display_list;
203 _cairo_xlib_display_list = display;
204 }
205 device = cairo_device_reference_moz_cairo_device_reference (&display->base);
206 goto UNLOCK;
207 }
208 }
209
210 display = _cairo_malloc (sizeof (cairo_xlib_display_t))((sizeof (cairo_xlib_display_t)) != 0 ? malloc(sizeof (cairo_xlib_display_t
)) : ((void*)0))
;
211 if (unlikely (display == NULL)(__builtin_expect (!!(display == ((void*)0)), 0))) {
212 device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
213 goto UNLOCK;
214 }
215
216 _cairo_device_init (&display->base, &_cairo_xlib_device_backend);
217
218 display->display = dpy;
219 cairo_list_init (&display->screens);
220 cairo_list_init (&display->fonts);
221 display->closed = FALSE0;
222
223 /* Xlib calls out to the extension close_display hooks in LIFO
224 * order. So we have to ensure that all extensions that we depend
225 * on in our close_display hook are properly initialized before we
226 * add our hook. For now, that means Render, so we call into its
227 * QueryVersion function to ensure it gets initialized.
228 */
229 display->render_major = display->render_minor = -1;
230 XRenderQueryVersion_int_consume (dpy, &display->render_major, &display->render_minor);
231 env = getenv ("CAIRO_DEBUG");
232 if (env != NULL((void*)0) && (env = strstr (env, "xrender-version=")) != NULL((void*)0)) {
233 int max_render_major, max_render_minor;
234
235 env += sizeof ("xrender-version=") - 1;
236 if (sscanf (env, "%d.%d", &max_render_major, &max_render_minor) != 2)
237 max_render_major = max_render_minor = -1;
238
239 if (max_render_major < display->render_major ||
240 (max_render_major == display->render_major &&
241 max_render_minor < display->render_minor))
242 {
243 display->render_major = max_render_major;
244 display->render_minor = max_render_minor;
245 }
246 }
247
248 _cairo_xlib_display_select_compositor (display);
249
250 display->white = NULL((void*)0);
251 memset (display->alpha, 0, sizeof (display->alpha));
252 memset (display->solid, 0, sizeof (display->solid));
253 memset (display->solid_cache, 0, sizeof (display->solid_cache));
254 memset (display->last_solid_cache, 0, sizeof (display->last_solid_cache));
255
256 memset (display->cached_xrender_formats, 0,
257 sizeof (display->cached_xrender_formats));
258
259 display->force_precision = -1;
260
261 _cairo_xlib_display_init_shm (display);
262
263 /* Prior to Render 0.10, there is no protocol support for gradients and
264 * we call function stubs instead, which would silently consume the drawing.
265 */
266#if RENDER_MAJOR == 0 && RENDER_MINOR < 10
267 display->buggy_gradients = TRUE1;
268#else
269 display->buggy_gradients = FALSE0;
270#endif
271 display->buggy_pad_reflect = FALSE0;
272 display->buggy_repeat = FALSE0;
273
274 /* This buggy_repeat condition is very complicated because there
275 * are multiple X server code bases (with multiple versioning
276 * schemes within a code base), and multiple bugs.
277 *
278 * The X servers:
279 *
280 * 1. The Vendor=="XFree86" code base with release numbers such
281 * as 4.7.0 (VendorRelease==40700000).
282 *
283 * 2. The Vendor=="X.Org" code base (a descendant of the
284 * XFree86 code base). It originally had things like
285 * VendorRelease==60700000 for release 6.7.0 but then changed
286 * its versioning scheme so that, for example,
287 * VendorRelease==10400000 for the 1.4.0 X server within the
288 * X.Org 7.3 release.
289 *
290 * The bugs:
291 *
292 * 1. The original bug that led to the buggy_repeat
293 * workaround. This was a bug that Owen Taylor investigated,
294 * understood well, and characterized against various X
295 * servers. Confirmed X servers with this bug include:
296 *
297 * "XFree86" <= 40500000
298 * "X.Org" <= 60802000 (only with old numbering >= 60700000)
299 *
300 * 2. A separate bug resulting in a crash of the X server when
301 * using cairo's extend-reflect test case, (which, surprisingly
302 * enough was not passing RepeatReflect to the X server, but
303 * instead using RepeatNormal in a workaround). Nobody to date
304 * has understood the bug well, but it appears to be gone as of
305 * the X.Org 1.4.0 server. This bug is coincidentally avoided
306 * by using the same buggy_repeat workaround. Confirmed X
307 * servers with this bug include:
308 *
309 * "X.org" == 60900000 (old versioning scheme)
310 * "X.org" < 10400000 (new numbering scheme)
311 *
312 * For the old-versioning-scheme X servers we don't know
313 * exactly when second the bug started, but since bug 1 is
314 * present through 6.8.2 and bug 2 is present in 6.9.0 it seems
315 * safest to just blacklist all old-versioning-scheme X servers,
316 * (just using VendorRelease < 70000000), as buggy_repeat=TRUE.
317 */
318 if (_cairo_xlib_vendor_is_xorg (dpy)) {
319 if (VendorRelease (dpy)(((_XPrivDisplay)(dpy))->release) >= 60700000) {
320 if (VendorRelease (dpy)(((_XPrivDisplay)(dpy))->release) < 70000000)
321 display->buggy_repeat = TRUE1;
322
323 /* We know that gradients simply do not work in early Xorg servers */
324 if (VendorRelease (dpy)(((_XPrivDisplay)(dpy))->release) < 70200000)
325 display->buggy_gradients = TRUE1;
326
327 /* And the extended repeat modes were not fixed until much later */
328 display->buggy_pad_reflect = TRUE1;
329 } else {
330 if (VendorRelease (dpy)(((_XPrivDisplay)(dpy))->release) < 10400000)
331 display->buggy_repeat = TRUE1;
332
333 /* Too many bugs in the early drivers */
334 if (VendorRelease (dpy)(((_XPrivDisplay)(dpy))->release) < 10699000)
335 display->buggy_pad_reflect = TRUE1;
336 }
337 } else if (strstr (ServerVendor (dpy)(((_XPrivDisplay)(dpy))->vendor), "XFree86") != NULL((void*)0)) {
338 if (VendorRelease (dpy)(((_XPrivDisplay)(dpy))->release) <= 40500000)
339 display->buggy_repeat = TRUE1;
340
341 display->buggy_gradients = TRUE1;
342 display->buggy_pad_reflect = TRUE1;
343 }
344
345 codes = XAddExtension (dpy);
346 if (unlikely (codes == NULL)(__builtin_expect (!!(codes == ((void*)0)), 0))) {
347 device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
348 free (display);
349 goto UNLOCK;
350 }
351
352 XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);
353 cairo_device_reference_moz_cairo_device_reference (&display->base); /* add one for the CloseDisplay */
354
355 display->next = _cairo_xlib_display_list;
356 _cairo_xlib_display_list = display;
357
358 device = &display->base;
359
360UNLOCK:
361 CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex)pthread_mutex_unlock (&(_cairo_xlib_display_mutex));
362 return device;
363}
364
365cairo_status_t
366_cairo_xlib_display_acquire (cairo_device_t *device, cairo_xlib_display_t **display)
367{
368 cairo_status_t status;
369
370 status = cairo_device_acquire_moz_cairo_device_acquire (device);
371 if (status)
372 return status;
373
374 *display = (cairo_xlib_display_t *) device;
375 return CAIRO_STATUS_SUCCESS;
376}
377
378XRenderPictFormat *
379_cairo_xlib_display_get_xrender_format_for_pixman(cairo_xlib_display_t *display,
380 pixman_format_code_t format)
381{
382 Display *dpy = display->display;
383 XRenderPictFormat tmpl;
384 int mask;
385
386 /* No equivalent in X11 yet. */
387 if (format == PIXMAN_rgba_float || format == PIXMAN_rgb_float)
388 return NULL((void*)0);
389
390#define MASK(x) ((1<<(x))-1)
391
392 tmpl.depth = PIXMAN_FORMAT_DEPTH(format)((((format >> (12)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3)) + (((format >> (8)) &
((1 << (4)) - 1)) << ((format >> 22) &
3)) + (((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3)) + (((format >> (0)) &
((1 << (4)) - 1)) << ((format >> 22) &
3)))
;
393 mask = PictFormatType(1 << 1) | PictFormatDepth(1 << 2);
394
395 switch (PIXMAN_FORMAT_TYPE(format)(((format) >> 16) & 0x3f)) {
396 case PIXMAN_TYPE_ARGB2:
397 tmpl.type = PictTypeDirect1;
398
399 tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)(((format >> (12)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
400 if (PIXMAN_FORMAT_A(format)(((format >> (12)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
)
401 tmpl.direct.alpha = (PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
+
402 PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
+
403 PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
404
405 tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
406 tmpl.direct.red = (PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
+
407 PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
408
409 tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
410 tmpl.direct.green = PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
;
411
412 tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
413 tmpl.direct.blue = 0;
414
415 mask |= PictFormatRed(1 << 3) | PictFormatRedMask(1 << 4);
416 mask |= PictFormatGreen(1 << 5) | PictFormatGreenMask(1 << 6);
417 mask |= PictFormatBlue(1 << 7) | PictFormatBlueMask(1 << 8);
418 mask |= PictFormatAlpha(1 << 9) | PictFormatAlphaMask(1 << 10);
419 break;
420
421 case PIXMAN_TYPE_ABGR3:
422 tmpl.type = PictTypeDirect1;
423
424 tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)(((format >> (12)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
425 if (tmpl.direct.alphaMask)
426 tmpl.direct.alpha = (PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
+
427 PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
+
428 PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
429
430 tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
431 tmpl.direct.blue = (PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
+
432 PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
433
434 tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
435 tmpl.direct.green = PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
;
436
437 tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
438 tmpl.direct.red = 0;
439
440 mask |= PictFormatRed(1 << 3) | PictFormatRedMask(1 << 4);
441 mask |= PictFormatGreen(1 << 5) | PictFormatGreenMask(1 << 6);
442 mask |= PictFormatBlue(1 << 7) | PictFormatBlueMask(1 << 8);
443 mask |= PictFormatAlpha(1 << 9) | PictFormatAlphaMask(1 << 10);
444 break;
445
446 case PIXMAN_TYPE_BGRA8:
447 tmpl.type = PictTypeDirect1;
448
449 tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
450 tmpl.direct.blue = (PIXMAN_FORMAT_BPP(format)(((format >> (24)) & ((1 << (8)) - 1)) <<
((format >> 22) & 3))
- PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
451
452 tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
453 tmpl.direct.green = (PIXMAN_FORMAT_BPP(format)(((format >> (24)) & ((1 << (8)) - 1)) <<
((format >> 22) & 3))
- PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
-
454 PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
455
456 tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
457 tmpl.direct.red = (PIXMAN_FORMAT_BPP(format)(((format >> (24)) & ((1 << (8)) - 1)) <<
((format >> 22) & 3))
- PIXMAN_FORMAT_B(format)(((format >> (0)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
-
458 PIXMAN_FORMAT_G(format)(((format >> (4)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
- PIXMAN_FORMAT_R(format)(((format >> (8)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
459
460 tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)(((format >> (12)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
461 tmpl.direct.alpha = 0;
462
463 mask |= PictFormatRed(1 << 3) | PictFormatRedMask(1 << 4);
464 mask |= PictFormatGreen(1 << 5) | PictFormatGreenMask(1 << 6);
465 mask |= PictFormatBlue(1 << 7) | PictFormatBlueMask(1 << 8);
466 mask |= PictFormatAlpha(1 << 9) | PictFormatAlphaMask(1 << 10);
467 break;
468
469 case PIXMAN_TYPE_A1:
470 tmpl.type = PictTypeDirect1;
471
472 tmpl.direct.alpha = 0;
473 tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)(((format >> (12)) & ((1 << (4)) - 1)) <<
((format >> 22) & 3))
);
474
475 mask |= PictFormatAlpha(1 << 9) | PictFormatAlphaMask(1 << 10);
476 break;
477
478 case PIXMAN_TYPE_COLOR4:
479 case PIXMAN_TYPE_GRAY5:
480 /* XXX Find matching visual/colormap */
481 tmpl.type = PictTypeIndexed0;
482 //tmpl.colormap = screen->visuals[PIXMAN_FORMAT_VIS(format)].vid;
483 //mask |= PictFormatColormap;
484 return NULL((void*)0);
485 }
486#undef MASK
487
488 /* XXX caching? */
489 return XRenderFindFormat_voidp_consume(dpy, mask, &tmpl, 0);
490}
491
492XRenderPictFormat *
493_cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
494 cairo_format_t format)
495{
496 XRenderPictFormat *xrender_format;
497
498 xrender_format = display->cached_xrender_formats[format];
499 if (xrender_format == NULL((void*)0)) {
500 int pict_format = PictStandardNUM5;
501
502 switch (format) {
503 case CAIRO_FORMAT_A1:
504 pict_format = PictStandardA14; break;
505 case CAIRO_FORMAT_A8:
506 pict_format = PictStandardA82; break;
507 case CAIRO_FORMAT_RGB24:
508 pict_format = PictStandardRGB241; break;
509 case CAIRO_FORMAT_RGB16_565:
510 xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display,
511 PIXMAN_r5g6b5);
512 break;
513 case CAIRO_FORMAT_RGB30:
514 xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display,
515 PIXMAN_x2r10g10b10);
516 break;
517 case CAIRO_FORMAT_RGBA128F:
518 xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display,
519 PIXMAN_rgba_float);
520 break;
521 case CAIRO_FORMAT_RGB96F:
522 xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display,
523 PIXMAN_rgb_float);
524 break;
525 case CAIRO_FORMAT_INVALID:
526 default:
527 ASSERT_NOT_REACHEDdo { ((void) sizeof ((!"reached") ? 1 : 0), __extension__ ({ if
(!"reached") ; else __assert_fail ("!\"reached\"", "/root/firefox-clang/gfx/cairo/cairo/src/cairo-xlib-display.c"
, 527, __extension__ __PRETTY_FUNCTION__); })); } while (0)
;
528 case CAIRO_FORMAT_ARGB32:
529 pict_format = PictStandardARGB320; break;
530 }
531 if (pict_format != PictStandardNUM5)
532 xrender_format =
533 XRenderFindStandardFormat_voidp_consume (display->display, pict_format);
534 display->cached_xrender_formats[format] = xrender_format;
535 }
536
537 return xrender_format;
538}
539
540cairo_xlib_screen_t *
541_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
542 Screen *screen)
543{
544 cairo_xlib_screen_t *info;
545
546 cairo_list_foreach_entry (info, cairo_xlib_screen_t, &display->screens, link)for (info = ({ const __typeof__ (((cairo_xlib_screen_t *) 0)->
link) *mptr__ = ((&display->screens)->next); (cairo_xlib_screen_t
*) ((char *) mptr__ - __builtin_offsetof(cairo_xlib_screen_t
, link)); }); &info->link != (&display->screens
); info = ({ const __typeof__ (((cairo_xlib_screen_t *) 0)->
link) *mptr__ = (info->link.next); (cairo_xlib_screen_t *)
((char *) mptr__ - __builtin_offsetof(cairo_xlib_screen_t, link
)); }))
{
547 if (info->screen == screen) {
548 if (display->screens.next != &info->link)
549 cairo_list_move (&info->link, &display->screens);
550 return info;
551 }
552 }
553
554 return NULL((void*)0);
555}
556
557cairo_bool_t
558_cairo_xlib_display_has_repeat (cairo_device_t *device)
559{
560 return ! ((cairo_xlib_display_t *) device)->buggy_repeat;
561}
562
563cairo_bool_t
564_cairo_xlib_display_has_reflect (cairo_device_t *device)
565{
566 return ! ((cairo_xlib_display_t *) device)->buggy_pad_reflect;
567}
568
569cairo_bool_t
570_cairo_xlib_display_has_gradients (cairo_device_t *device)
571{
572 return ! ((cairo_xlib_display_t *) device)->buggy_gradients;
573}
574
575/**
576 * cairo_xlib_device_debug_cap_xrender_version:
577 * @device: a #cairo_device_t for the Xlib backend
578 * @major_version: major version to restrict to
579 * @minor_version: minor version to restrict to
580 *
581 * Restricts all future Xlib surfaces for this devices to the specified version
582 * of the RENDER extension. This function exists solely for debugging purpose.
583 * It lets you find out how cairo would behave with an older version of
584 * the RENDER extension.
585 *
586 * Use the special values -1 and -1 for disabling the RENDER extension.
587 *
588 * Since: 1.12
589 **/
590void
591cairo_xlib_device_debug_cap_xrender_version (cairo_device_t *device,
592 int major_version,
593 int minor_version)
594{
595 cairo_xlib_display_t *display = (cairo_xlib_display_t *) device;
596
597 if (device == NULL((void*)0) || device->status)
598 return;
599
600 if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB)
601 return;
602
603 if (major_version < display->render_major ||
604 (major_version == display->render_major &&
605 minor_version < display->render_minor))
606 {
607 display->render_major = major_version;
608 display->render_minor = minor_version;
609 }
610
611 _cairo_xlib_display_select_compositor (display);
612}
613
614/**
615 * cairo_xlib_device_debug_set_precision:
616 * @device: a #cairo_device_t for the Xlib backend
617 * @precision: the precision to use
618 *
619 * Render supports two modes of precision when rendering trapezoids. Set
620 * the precision to the desired mode.
621 *
622 * Since: 1.12
623 **/
624void
625cairo_xlib_device_debug_set_precision (cairo_device_t *device,
626 int precision)
627{
628 if (device == NULL((void*)0) || device->status)
629 return;
630 if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) {
631 cairo_status_t status;
632
633 status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
634 (void) status;
635 return;
636 }
637
638 ((cairo_xlib_display_t *) device)->force_precision = precision;
639}
640
641/**
642 * cairo_xlib_device_debug_get_precision:
643 * @device: a #cairo_device_t for the Xlib backend
644 *
645 * Get the Xrender precision mode.
646 *
647 * Returns: the render precision mode
648 *
649 * Since: 1.12
650 **/
651int
652cairo_xlib_device_debug_get_precision (cairo_device_t *device)
653{
654 if (device == NULL((void*)0) || device->status)
655 return -1;
656 if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) {
657 cairo_status_t status;
658
659 status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
660 (void) status;
661 return -1;
662 }
663
664 return ((cairo_xlib_display_t *) device)->force_precision;
665}
666
667#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */