mirror of OpenBSD xenocara tree github.com/openbsd/xenocara
openbsd
at master 926 lines 25 kB view raw
1/* 2 * 3 * Copyright © 2000 SuSE, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of SuSE not be used in advertising or 10 * publicity pertaining to distribution of the software without specific, 11 * written prior permission. SuSE makes no representations about the 12 * suitability of this software for any purpose. It is provided "as is" 13 * without express or implied warranty. 14 * 15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Author: Keith Packard, SuSE, Inc. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include <config.h> 27#endif 28#include "Xrenderint.h" 29#include <limits.h> 30 31XRenderExtInfo XRenderExtensionInfo; 32char XRenderExtensionName[] = RENDER_NAME; 33 34static int XRenderCloseDisplay (Display *dpy, XExtCodes *codes); 35 36/* 37 * XRenderExtFindDisplay - look for a display in this extension; keeps a 38 * cache of the most-recently used for efficiency. (Replaces 39 * XextFindDisplay.) 40 */ 41static XRenderExtDisplayInfo * 42XRenderExtFindDisplay (XRenderExtInfo *extinfo, 43 Display *dpy) 44{ 45 XRenderExtDisplayInfo *dpyinfo; 46 47 /* 48 * see if this was the most recently accessed display 49 */ 50 if ((dpyinfo = extinfo->cur) && dpyinfo->display == dpy) 51 return dpyinfo; 52 53 /* 54 * look for display in list 55 */ 56 _XLockMutex(_Xglobal_lock); 57 for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 58 if (dpyinfo->display == dpy) { 59 extinfo->cur = dpyinfo; /* cache most recently used */ 60 _XUnlockMutex(_Xglobal_lock); 61 return dpyinfo; 62 } 63 } 64 _XUnlockMutex(_Xglobal_lock); 65 66 return NULL; 67} 68 69/* 70 * If the server is missing support for any of the required depths on 71 * any screen, tell the application that Render is not present. 72 */ 73 74#define DEPTH_MASK(d) (1U << ((d) - 1)) 75 76/* 77 * Render requires support for depth 1, 4, 8, 24 and 32 pixmaps 78 */ 79 80#define REQUIRED_DEPTHS (DEPTH_MASK(1) | \ 81 DEPTH_MASK(4) | \ 82 DEPTH_MASK(8) | \ 83 DEPTH_MASK(24) | \ 84 DEPTH_MASK(32)) 85 86typedef struct _DepthCheckRec { 87 struct _DepthCheckRec *next; 88 Display *dpy; 89 CARD32 missing; 90 unsigned long serial; 91} DepthCheckRec, *DepthCheckPtr; 92 93static DepthCheckPtr depthChecks; 94 95static int 96XRenderDepthCheckErrorHandler (Display *dpy, XErrorEvent *evt) 97{ 98 if (evt->request_code == X_CreatePixmap && evt->error_code == BadValue) 99 { 100 DepthCheckPtr d; 101 _XLockMutex(_Xglobal_lock); 102 for (d = depthChecks; d; d = d->next) 103 if (d->dpy == dpy) 104 { 105 if ((long) (evt->serial - d->serial) >= 0) 106 d->missing |= DEPTH_MASK(evt->resourceid); 107 break; 108 } 109 _XUnlockMutex (_Xglobal_lock); 110 } 111 return 0; 112} 113 114static Bool 115XRenderHasDepths (Display *dpy) 116{ 117 int s; 118 119 for (s = 0; s < ScreenCount (dpy); s++) 120 { 121 CARD32 depths = 0; 122 CARD32 missing; 123 Screen *scr = ScreenOfDisplay (dpy, s); 124 int d; 125 126 for (d = 0; d < scr->ndepths; d++) 127 depths |= DEPTH_MASK(scr->depths[d].depth); 128 missing = ~depths & REQUIRED_DEPTHS; 129 if (missing) 130 { 131 DepthCheckRec dc, **dp; 132 XErrorHandler previousHandler; 133 134 /* 135 * Ok, this is ugly. It should be sufficient at this 136 * point to just return False, but Xinerama is broken at 137 * this point and only advertises depths which have an 138 * associated visual. Of course, the other depths still 139 * work, but the only way to find out is to try them. 140 */ 141 dc.dpy = dpy; 142 dc.missing = 0; 143 dc.serial = XNextRequest (dpy); 144 _XLockMutex(_Xglobal_lock); 145 dc.next = depthChecks; 146 depthChecks = &dc; 147 _XUnlockMutex (_Xglobal_lock); 148 /* 149 * I suspect this is not really thread safe, but Xlib doesn't 150 * provide a lot of options here 151 */ 152 previousHandler = XSetErrorHandler (XRenderDepthCheckErrorHandler); 153 /* 154 * Try each missing depth and see if pixmap creation succeeds 155 */ 156 for (d = 1; d <= 32; d++) 157 /* don't check depth 1 == Xcursor recurses... */ 158 if ((missing & DEPTH_MASK(d)) && d != 1) 159 { 160 Pixmap p; 161 p = XCreatePixmap (dpy, RootWindow (dpy, s), 1, 1, d); 162 XFreePixmap (dpy, p); 163 } 164 XSync (dpy, False); 165 XSetErrorHandler (previousHandler); 166 /* 167 * Unhook from the list of depth check records 168 */ 169 _XLockMutex(_Xglobal_lock); 170 for (dp = &depthChecks; *dp; dp = &(*dp)->next) 171 { 172 if (*dp == &dc) 173 { 174 *dp = dc.next; 175 break; 176 } 177 } 178 _XUnlockMutex (_Xglobal_lock); 179 if (dc.missing) 180 return False; 181 } 182 } 183 return True; 184} 185 186/* 187 * XRenderExtAddDisplay - add a display to this extension. (Replaces 188 * XextAddDisplay) 189 */ 190static XRenderExtDisplayInfo * 191XRenderExtAddDisplay (XRenderExtInfo *extinfo, 192 Display *dpy, 193 char *ext_name) 194{ 195 XRenderExtDisplayInfo *dpyinfo; 196 197 dpyinfo = (XRenderExtDisplayInfo *) Xmalloc (sizeof (XRenderExtDisplayInfo)); 198 if (!dpyinfo) return NULL; 199 dpyinfo->display = dpy; 200 dpyinfo->info = NULL; 201 202 if (XRenderHasDepths (dpy)) 203 dpyinfo->codes = XInitExtension (dpy, ext_name); 204 else 205 dpyinfo->codes = NULL; 206 207 /* 208 * if the server has the extension, then we can initialize the 209 * appropriate function vectors 210 */ 211 if (dpyinfo->codes) { 212 XESetCloseDisplay (dpy, dpyinfo->codes->extension, 213 XRenderCloseDisplay); 214 } else { 215 /* The server doesn't have this extension. 216 * Use a private Xlib-internal extension to hang the close_display 217 * hook on so that the "cache" (extinfo->cur) is properly cleaned. 218 * (XBUG 7955) 219 */ 220 XExtCodes *codes = XAddExtension(dpy); 221 if (!codes) { 222 XFree(dpyinfo); 223 return NULL; 224 } 225 XESetCloseDisplay (dpy, codes->extension, XRenderCloseDisplay); 226 } 227 228 /* 229 * now, chain it onto the list 230 */ 231 _XLockMutex(_Xglobal_lock); 232 dpyinfo->next = extinfo->head; 233 extinfo->head = dpyinfo; 234 extinfo->cur = dpyinfo; 235 extinfo->ndisplays++; 236 _XUnlockMutex(_Xglobal_lock); 237 return dpyinfo; 238} 239 240 241/* 242 * XRenderExtRemoveDisplay - remove the indicated display from the 243 * extension object. (Replaces XextRemoveDisplay.) 244 */ 245static int 246XRenderExtRemoveDisplay (XRenderExtInfo *extinfo, Display *dpy) 247{ 248 XRenderExtDisplayInfo *dpyinfo, *prev; 249 250 /* 251 * locate this display and its back link so that it can be removed 252 */ 253 _XLockMutex(_Xglobal_lock); 254 prev = NULL; 255 for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 256 if (dpyinfo->display == dpy) break; 257 prev = dpyinfo; 258 } 259 if (!dpyinfo) { 260 _XUnlockMutex(_Xglobal_lock); 261 return 0; /* hmm, actually an error */ 262 } 263 264 /* 265 * remove the display from the list; handles going to zero 266 */ 267 if (prev) 268 prev->next = dpyinfo->next; 269 else 270 extinfo->head = dpyinfo->next; 271 272 extinfo->ndisplays--; 273 if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */ 274 _XUnlockMutex(_Xglobal_lock); 275 276 Xfree ((char *) dpyinfo); 277 return 1; 278} 279 280 281 282XRenderExtDisplayInfo * 283XRenderFindDisplay (Display *dpy) 284{ 285 XRenderExtDisplayInfo *dpyinfo; 286 287 dpyinfo = XRenderExtFindDisplay (&XRenderExtensionInfo, dpy); 288 if (!dpyinfo) 289 dpyinfo = XRenderExtAddDisplay (&XRenderExtensionInfo, dpy, 290 XRenderExtensionName); 291 return dpyinfo; 292} 293 294static int 295XRenderCloseDisplay (Display *dpy, XExtCodes *codes) 296{ 297 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 298 if (info && info->info) XFree (info->info); 299 300 return XRenderExtRemoveDisplay (&XRenderExtensionInfo, dpy); 301} 302 303/**************************************************************************** 304 * * 305 * Render public interfaces * 306 * * 307 ****************************************************************************/ 308 309Bool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep) 310{ 311 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 312 313 if (RenderHasExtension(info)) { 314 *event_basep = info->codes->first_event; 315 *error_basep = info->codes->first_error; 316 return True; 317 } else { 318 return False; 319 } 320} 321 322 323Status XRenderQueryVersion (Display *dpy, 324 int *major_versionp, 325 int *minor_versionp) 326{ 327 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 328 XRenderInfo *xri; 329 330 if (!RenderHasExtension (info)) 331 return 0; 332 333 if (!XRenderQueryFormats (dpy)) 334 return 0; 335 336 xri = info->info; 337 *major_versionp = xri->major_version; 338 *minor_versionp = xri->minor_version; 339 return 1; 340} 341 342static XRenderPictFormat * 343_XRenderFindFormat (XRenderInfo *xri, PictFormat format) 344{ 345 int nf; 346 347 for (nf = 0; nf < xri->nformat; nf++) 348 if (xri->format[nf].id == format) 349 return &xri->format[nf]; 350 return NULL; 351} 352 353static Visual * 354_XRenderFindVisual (Display *dpy, VisualID vid) 355{ 356 return _XVIDtoVisual (dpy, vid); 357} 358 359typedef struct _renderVersionState { 360 unsigned long version_seq; 361 Bool error; 362 int major_version; 363 int minor_version; 364 365} _XrenderVersionState; 366 367static Bool 368_XRenderVersionHandler (Display *dpy, 369 xReply *rep, 370 char *buf, 371 int len, 372 XPointer data) 373{ 374 xRenderQueryVersionReply replbuf; 375 xRenderQueryVersionReply *repl; 376 _XrenderVersionState *state = (_XrenderVersionState *) data; 377 378 if (dpy->last_request_read != state->version_seq) 379 return False; 380 if (rep->generic.type == X_Error) 381 { 382 state->error = True; 383 return False; 384 } 385 repl = (xRenderQueryVersionReply *) 386 _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, 387 (SIZEOF(xRenderQueryVersionReply) - SIZEOF(xReply)) >> 2, 388 True); 389 state->major_version = repl->majorVersion; 390 state->minor_version = repl->minorVersion; 391 return True; 392} 393 394Status 395XRenderQueryFormats (Display *dpy) 396{ 397 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 398 _XAsyncHandler async; 399 _XrenderVersionState async_state; 400 xRenderQueryVersionReq *vreq; 401 xRenderQueryPictFormatsReply rep; 402 xRenderQueryPictFormatsReq *req; 403 XRenderInfo *xri; 404 XRenderPictFormat *format; 405 XRenderScreen *screen; 406 XRenderDepth *depth; 407 XRenderVisual *visual; 408 xPictFormInfo *xFormat; 409 xPictScreen *xScreen; 410 xPictDepth *xDepth; 411 xPictVisual *xVisual; 412 CARD32 *xSubpixel; 413 void *xData; 414 int nf, ns, nd, nv; 415 unsigned long rlength; 416 unsigned long nbytes; 417 418 RenderCheckExtension (dpy, info, 0); 419 LockDisplay (dpy); 420 if (info->info) 421 { 422 UnlockDisplay (dpy); 423 return 1; 424 } 425 GetReq (RenderQueryVersion, vreq); 426 vreq->reqType = info->codes->major_opcode; 427 vreq->renderReqType = X_RenderQueryVersion; 428 vreq->majorVersion = RENDER_MAJOR; 429 vreq->minorVersion = RENDER_MINOR; 430 431 async_state.version_seq = dpy->request; 432 async_state.error = False; 433 async.next = dpy->async_handlers; 434 async.handler = _XRenderVersionHandler; 435 async.data = (XPointer) &async_state; 436 dpy->async_handlers = &async; 437 438 GetReq (RenderQueryPictFormats, req); 439 req->reqType = info->codes->major_opcode; 440 req->renderReqType = X_RenderQueryPictFormats; 441 442 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 443 { 444 DeqAsyncHandler (dpy, &async); 445 UnlockDisplay (dpy); 446 SyncHandle (); 447 return 0; 448 } 449 DeqAsyncHandler (dpy, &async); 450 if (async_state.error) 451 { 452 UnlockDisplay(dpy); 453 SyncHandle(); 454 return 0; 455 } 456 /* 457 * Check for the lack of sub-pixel data 458 */ 459 if (async_state.major_version == 0 && async_state.minor_version < 6) 460 rep.numSubpixel = 0; 461 462 if ((rep.numFormats < ((INT_MAX / 4) / sizeof (XRenderPictFormat))) && 463 (rep.numScreens < ((INT_MAX / 4) / sizeof (XRenderScreen))) && 464 (rep.numDepths < ((INT_MAX / 4) / sizeof (XRenderDepth))) && 465 (rep.numVisuals < ((INT_MAX / 4) / sizeof (XRenderVisual))) && 466 (rep.numSubpixel < ((INT_MAX / 4) / 4)) && 467 (rep.length < (INT_MAX >> 2)) ) { 468 xri = Xmalloc (sizeof (XRenderInfo) + 469 (rep.numFormats * sizeof (XRenderPictFormat)) + 470 (rep.numScreens * sizeof (XRenderScreen)) + 471 (rep.numDepths * sizeof (XRenderDepth)) + 472 (rep.numVisuals * sizeof (XRenderVisual))); 473 rlength = ((rep.numFormats * sizeof (xPictFormInfo)) + 474 (rep.numScreens * sizeof (xPictScreen)) + 475 (rep.numDepths * sizeof (xPictDepth)) + 476 (rep.numVisuals * sizeof (xPictVisual)) + 477 (rep.numSubpixel * 4)); 478 xData = Xmalloc (rlength); 479 nbytes = (unsigned long) rep.length << 2; 480 } else { 481 xri = NULL; 482 xData = NULL; 483 rlength = nbytes = 0; 484 } 485 486 if (!xri || !xData || nbytes < rlength) 487 { 488 if (xri) Xfree (xri); 489 if (xData) Xfree (xData); 490 _XEatDataWords (dpy, rep.length); 491 UnlockDisplay (dpy); 492 SyncHandle (); 493 return 0; 494 } 495 xri->major_version = async_state.major_version; 496 xri->minor_version = async_state.minor_version; 497 xri->format = (XRenderPictFormat *) (xri + 1); 498 xri->nformat = rep.numFormats; 499 xri->screen = (XRenderScreen *) (xri->format + rep.numFormats); 500 xri->nscreen = rep.numScreens; 501 xri->depth = (XRenderDepth *) (xri->screen + rep.numScreens); 502 xri->ndepth = rep.numDepths; 503 xri->visual = (XRenderVisual *) (xri->depth + rep.numDepths); 504 xri->nvisual = rep.numVisuals; 505 _XRead (dpy, (char *) xData, rlength); 506 format = xri->format; 507 xFormat = (xPictFormInfo *) xData; 508 for (nf = 0; nf < rep.numFormats; nf++) 509 { 510 format->id = xFormat->id; 511 format->type = xFormat->type; 512 format->depth = xFormat->depth; 513 format->direct.red = xFormat->direct.red; 514 format->direct.redMask = xFormat->direct.redMask; 515 format->direct.green = xFormat->direct.green; 516 format->direct.greenMask = xFormat->direct.greenMask; 517 format->direct.blue = xFormat->direct.blue; 518 format->direct.blueMask = xFormat->direct.blueMask; 519 format->direct.alpha = xFormat->direct.alpha; 520 format->direct.alphaMask = xFormat->direct.alphaMask; 521 format->colormap = xFormat->colormap; 522 format++; 523 xFormat++; 524 } 525 xScreen = (xPictScreen *) xFormat; 526 screen = xri->screen; 527 depth = xri->depth; 528 visual = xri->visual; 529 for (ns = 0; ns < xri->nscreen; ns++) 530 { 531 screen->depths = depth; 532 screen->ndepths = xScreen->nDepth; 533 screen->fallback = _XRenderFindFormat (xri, xScreen->fallback); 534 screen->subpixel = SubPixelUnknown; 535 xDepth = (xPictDepth *) (xScreen + 1); 536 if (screen->ndepths > rep.numDepths) { 537 Xfree (xri); 538 Xfree (xData); 539 _XEatDataWords (dpy, rep.length); 540 UnlockDisplay (dpy); 541 SyncHandle (); 542 return 0; 543 } 544 rep.numDepths -= screen->ndepths; 545 for (nd = 0; nd < screen->ndepths; nd++) 546 { 547 depth->depth = xDepth->depth; 548 depth->nvisuals = xDepth->nPictVisuals; 549 depth->visuals = visual; 550 xVisual = (xPictVisual *) (xDepth + 1); 551 if (depth->nvisuals > rep.numVisuals) { 552 Xfree (xri); 553 Xfree (xData); 554 _XEatDataWords (dpy, rep.length); 555 UnlockDisplay (dpy); 556 SyncHandle (); 557 return 0; 558 } 559 rep.numVisuals -= depth->nvisuals; 560 for (nv = 0; nv < depth->nvisuals; nv++) 561 { 562 visual->visual = _XRenderFindVisual (dpy, xVisual->visual); 563 visual->format = _XRenderFindFormat (xri, xVisual->format); 564 visual++; 565 xVisual++; 566 } 567 depth++; 568 xDepth = (xPictDepth *) xVisual; 569 } 570 screen++; 571 xScreen = (xPictScreen *) xDepth; 572 } 573 xSubpixel = (CARD32 *) xScreen; 574 screen = xri->screen; 575 for (ns = 0; ns < rep.numSubpixel; ns++) 576 { 577 screen->subpixel = *xSubpixel; 578 xSubpixel++; 579 screen++; 580 } 581 info->info = xri; 582 /* 583 * Skip any extra data 584 */ 585 if (nbytes > rlength) 586 _XEatData (dpy, (unsigned long) (nbytes - rlength)); 587 588 UnlockDisplay (dpy); 589 SyncHandle (); 590 Xfree (xData); 591 return 1; 592} 593 594int 595XRenderQuerySubpixelOrder (Display *dpy, int screen) 596{ 597 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 598 XRenderInfo *xri; 599 600 if (!RenderHasExtension (info)) 601 return SubPixelUnknown; 602 603 if (!XRenderQueryFormats (dpy)) 604 return SubPixelUnknown; 605 606 xri = info->info; 607 return xri->screen[screen].subpixel; 608} 609 610Bool 611XRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel) 612{ 613 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 614 XRenderInfo *xri; 615 616 if (!RenderHasExtension (info)) 617 return False; 618 619 if (!XRenderQueryFormats (dpy)) 620 return False; 621 622 xri = info->info; 623 xri->screen[screen].subpixel = subpixel; 624 return True; 625} 626 627XRenderPictFormat * 628XRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual) 629{ 630 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 631 int nv; 632 XRenderInfo *xri; 633 XRenderVisual *xrv; 634 635 RenderCheckExtension (dpy, info, NULL); 636 if (!XRenderQueryFormats (dpy)) 637 return NULL; 638 xri = info->info; 639 for (nv = 0, xrv = xri->visual; nv < xri->nvisual; nv++, xrv++) 640 if (xrv->visual == visual) 641 return xrv->format; 642 return NULL; 643} 644 645XRenderPictFormat * 646XRenderFindFormat (Display *dpy, 647 unsigned long mask, 648 _Xconst XRenderPictFormat *template, 649 int count) 650{ 651 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 652 int nf; 653 XRenderInfo *xri; 654 655 RenderCheckExtension (dpy, info, NULL); 656 if (!XRenderQueryFormats (dpy)) 657 return NULL; 658 xri = info->info; 659 for (nf = 0; nf < xri->nformat; nf++) 660 { 661 if (mask & PictFormatID) 662 if (template->id != xri->format[nf].id) 663 continue; 664 if (mask & PictFormatType) 665 if (template->type != xri->format[nf].type) 666 continue; 667 if (mask & PictFormatDepth) 668 if (template->depth != xri->format[nf].depth) 669 continue; 670 if (mask & PictFormatRed) 671 if (template->direct.red != xri->format[nf].direct.red) 672 continue; 673 if (mask & PictFormatRedMask) 674 if (template->direct.redMask != xri->format[nf].direct.redMask) 675 continue; 676 if (mask & PictFormatGreen) 677 if (template->direct.green != xri->format[nf].direct.green) 678 continue; 679 if (mask & PictFormatGreenMask) 680 if (template->direct.greenMask != xri->format[nf].direct.greenMask) 681 continue; 682 if (mask & PictFormatBlue) 683 if (template->direct.blue != xri->format[nf].direct.blue) 684 continue; 685 if (mask & PictFormatBlueMask) 686 if (template->direct.blueMask != xri->format[nf].direct.blueMask) 687 continue; 688 if (mask & PictFormatAlpha) 689 if (template->direct.alpha != xri->format[nf].direct.alpha) 690 continue; 691 if (mask & PictFormatAlphaMask) 692 if (template->direct.alphaMask != xri->format[nf].direct.alphaMask) 693 continue; 694 if (mask & PictFormatColormap) 695 if (template->colormap != xri->format[nf].colormap) 696 continue; 697 if (count-- == 0) 698 return &xri->format[nf]; 699 } 700 return NULL; 701} 702 703XRenderPictFormat * 704XRenderFindStandardFormat (Display *dpy, 705 int format) 706{ 707 static struct { 708 XRenderPictFormat templ; 709 unsigned long mask; 710 } standardFormats[PictStandardNUM] = { 711 /* PictStandardARGB32 */ 712 { 713 { 714 0, /* id */ 715 PictTypeDirect, /* type */ 716 32, /* depth */ 717 { /* direct */ 718 16, /* direct.red */ 719 0xff, /* direct.redMask */ 720 8, /* direct.green */ 721 0xff, /* direct.greenMask */ 722 0, /* direct.blue */ 723 0xff, /* direct.blueMask */ 724 24, /* direct.alpha */ 725 0xff, /* direct.alphaMask */ 726 }, 727 0, /* colormap */ 728 }, 729 PictFormatType | 730 PictFormatDepth | 731 PictFormatRed | 732 PictFormatRedMask | 733 PictFormatGreen | 734 PictFormatGreenMask | 735 PictFormatBlue | 736 PictFormatBlueMask | 737 PictFormatAlpha | 738 PictFormatAlphaMask, 739 }, 740 /* PictStandardRGB24 */ 741 { 742 { 743 0, /* id */ 744 PictTypeDirect, /* type */ 745 24, /* depth */ 746 { /* direct */ 747 16, /* direct.red */ 748 0xff, /* direct.redMask */ 749 8, /* direct.green */ 750 0xff, /* direct.greenMask */ 751 0, /* direct.blue */ 752 0xff, /* direct.blueMask */ 753 0, /* direct.alpha */ 754 0x00, /* direct.alphaMask */ 755 }, 756 0, /* colormap */ 757 }, 758 PictFormatType | 759 PictFormatDepth | 760 PictFormatRed | 761 PictFormatRedMask | 762 PictFormatGreen | 763 PictFormatGreenMask | 764 PictFormatBlue | 765 PictFormatBlueMask | 766 PictFormatAlphaMask, 767 }, 768 /* PictStandardA8 */ 769 { 770 { 771 0, /* id */ 772 PictTypeDirect, /* type */ 773 8, /* depth */ 774 { /* direct */ 775 0, /* direct.red */ 776 0x00, /* direct.redMask */ 777 0, /* direct.green */ 778 0x00, /* direct.greenMask */ 779 0, /* direct.blue */ 780 0x00, /* direct.blueMask */ 781 0, /* direct.alpha */ 782 0xff, /* direct.alphaMask */ 783 }, 784 0, /* colormap */ 785 }, 786 PictFormatType | 787 PictFormatDepth | 788 PictFormatRedMask | 789 PictFormatGreenMask | 790 PictFormatBlueMask | 791 PictFormatAlpha | 792 PictFormatAlphaMask, 793 }, 794 /* PictStandardA4 */ 795 { 796 { 797 0, /* id */ 798 PictTypeDirect, /* type */ 799 4, /* depth */ 800 { /* direct */ 801 0, /* direct.red */ 802 0x00, /* direct.redMask */ 803 0, /* direct.green */ 804 0x00, /* direct.greenMask */ 805 0, /* direct.blue */ 806 0x00, /* direct.blueMask */ 807 0, /* direct.alpha */ 808 0x0f, /* direct.alphaMask */ 809 }, 810 0, /* colormap */ 811 }, 812 PictFormatType | 813 PictFormatDepth | 814 PictFormatRedMask | 815 PictFormatGreenMask | 816 PictFormatBlueMask | 817 PictFormatAlpha | 818 PictFormatAlphaMask, 819 }, 820 /* PictStandardA1 */ 821 { 822 { 823 0, /* id */ 824 PictTypeDirect, /* type */ 825 1, /* depth */ 826 { /* direct */ 827 0, /* direct.red */ 828 0x00, /* direct.redMask */ 829 0, /* direct.green */ 830 0x00, /* direct.greenMask */ 831 0, /* direct.blue */ 832 0x00, /* direct.blueMask */ 833 0, /* direct.alpha */ 834 0x01, /* direct.alphaMask */ 835 }, 836 0, /* colormap */ 837 }, 838 PictFormatType | 839 PictFormatDepth | 840 PictFormatRedMask | 841 PictFormatGreenMask | 842 PictFormatBlueMask | 843 PictFormatAlpha | 844 PictFormatAlphaMask, 845 }, 846 }; 847 848 if (0 <= format && format < PictStandardNUM) 849 return XRenderFindFormat (dpy, 850 standardFormats[format].mask, 851 &standardFormats[format].templ, 852 0); 853 return NULL; 854} 855 856XIndexValue * 857XRenderQueryPictIndexValues(Display *dpy, 858 _Xconst XRenderPictFormat *format, 859 int *num) 860{ 861 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 862 xRenderQueryPictIndexValuesReq *req; 863 xRenderQueryPictIndexValuesReply rep; 864 XIndexValue *values; 865 unsigned int nbytes, nread, rlength, i; 866 867 RenderCheckExtension (dpy, info, NULL); 868 869 LockDisplay (dpy); 870 GetReq (RenderQueryPictIndexValues, req); 871 req->reqType = info->codes->major_opcode; 872 req->renderReqType = X_RenderQueryPictIndexValues; 873 req->format = format->id; 874 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 875 { 876 UnlockDisplay (dpy); 877 SyncHandle (); 878 return NULL; 879 } 880 881 if ((rep.length < (INT_MAX >> 2)) && 882 (rep.numIndexValues < (INT_MAX / sizeof (XIndexValue)))) { 883 /* request data length */ 884 nbytes = rep.length << 2; 885 /* bytes of actual data in the request */ 886 nread = rep.numIndexValues * SIZEOF (xIndexValue); 887 /* size of array returned to application */ 888 rlength = rep.numIndexValues * sizeof (XIndexValue); 889 890 /* allocate returned data */ 891 values = Xmalloc (rlength); 892 } else { 893 nbytes = nread = rlength = 0; 894 values = NULL; 895 } 896 897 if (!values) 898 { 899 _XEatDataWords (dpy, rep.length); 900 UnlockDisplay (dpy); 901 SyncHandle (); 902 return NULL; 903 } 904 905 /* read the values one at a time and convert */ 906 *num = rep.numIndexValues; 907 for(i = 0; i < rep.numIndexValues; i++) 908 { 909 xIndexValue value; 910 911 _XRead (dpy, (char *) &value, SIZEOF (xIndexValue)); 912 values[i].pixel = value.pixel; 913 values[i].red = value.red; 914 values[i].green = value.green; 915 values[i].blue = value.blue; 916 values[i].alpha = value.alpha; 917 } 918 /* skip any padding */ 919 if(nbytes > nread) 920 { 921 _XEatData (dpy, (unsigned long) (nbytes - nread)); 922 } 923 UnlockDisplay (dpy); 924 SyncHandle (); 925 return values; 926}