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') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
48 | typedef int (*cairo_xlib_error_func_t) (Display *display, | |||
49 | XErrorEvent *event); | |||
50 | ||||
51 | static cairo_xlib_display_t *_cairo_xlib_display_list; | |||
52 | ||||
53 | static int | |||
54 | _noop_error_handler (Display *display, | |||
55 | XErrorEvent *event) | |||
56 | { | |||
57 | return False0; /* return value is ignored */ | |||
58 | } | |||
59 | ||||
60 | static 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 | ||||
95 | static void | |||
96 | _cairo_xlib_display_destroy (void *abstract_display) | |||
97 | { | |||
98 | cairo_xlib_display_t *display = abstract_display; | |||
99 | ||||
100 | free (display); | |||
101 | } | |||
102 | ||||
103 | static 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) | |||
| ||||
110 | if (display->display == dpy) | |||
111 | break; | |||
112 | CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex)pthread_mutex_unlock (&(_cairo_xlib_display_mutex)); | |||
113 | if (display
| |||
114 | return 0; | |||
115 | ||||
116 | cairo_device_finish_moz_cairo_device_finish (&display->base); | |||
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) { | |||
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 */ | |||
| ||||
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 | ||||
141 | static 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 | ||||
152 | static 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 | **/ | |||
174 | cairo_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 | ||||
360 | UNLOCK: | |||
361 | CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex)pthread_mutex_unlock (&(_cairo_xlib_display_mutex)); | |||
362 | return device; | |||
363 | } | |||
364 | ||||
365 | cairo_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 | ||||
378 | XRenderPictFormat * | |||
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 | ||||
492 | XRenderPictFormat * | |||
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 | ||||
540 | cairo_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 | ||||
557 | cairo_bool_t | |||
558 | _cairo_xlib_display_has_repeat (cairo_device_t *device) | |||
559 | { | |||
560 | return ! ((cairo_xlib_display_t *) device)->buggy_repeat; | |||
561 | } | |||
562 | ||||
563 | cairo_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 | ||||
569 | cairo_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 | **/ | |||
590 | void | |||
591 | cairo_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 | **/ | |||
624 | void | |||
625 | cairo_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 | **/ | |||
651 | int | |||
652 | cairo_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 */ |