| 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 */ |