11f0ac6a5Smrg/* 21f0ac6a5Smrg * 31f0ac6a5Smrg * Copyright © 2000 SuSE, Inc. 41f0ac6a5Smrg * 51f0ac6a5Smrg * Permission to use, copy, modify, distribute, and sell this software and its 61f0ac6a5Smrg * documentation for any purpose is hereby granted without fee, provided that 71f0ac6a5Smrg * the above copyright notice appear in all copies and that both that 81f0ac6a5Smrg * copyright notice and this permission notice appear in supporting 91f0ac6a5Smrg * documentation, and that the name of SuSE not be used in advertising or 101f0ac6a5Smrg * publicity pertaining to distribution of the software without specific, 111f0ac6a5Smrg * written prior permission. SuSE makes no representations about the 121f0ac6a5Smrg * suitability of this software for any purpose. It is provided "as is" 131f0ac6a5Smrg * without express or implied warranty. 141f0ac6a5Smrg * 151f0ac6a5Smrg * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 161f0ac6a5Smrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 171f0ac6a5Smrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 181f0ac6a5Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 196fae4e5dSmrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 201f0ac6a5Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 211f0ac6a5Smrg * 221f0ac6a5Smrg * Author: Keith Packard, SuSE, Inc. 231f0ac6a5Smrg */ 241f0ac6a5Smrg 251f0ac6a5Smrg#ifdef HAVE_CONFIG_H 261f0ac6a5Smrg#include <config.h> 271f0ac6a5Smrg#endif 281f0ac6a5Smrg#include "Xrenderint.h" 29190694daSmrg#include <limits.h> 301f0ac6a5Smrg 311f0ac6a5SmrgXRenderExtInfo XRenderExtensionInfo; 321f0ac6a5Smrgchar XRenderExtensionName[] = RENDER_NAME; 331f0ac6a5Smrg 341f0ac6a5Smrgstatic int XRenderCloseDisplay (Display *dpy, XExtCodes *codes); 351f0ac6a5Smrg 361f0ac6a5Smrg/* 371f0ac6a5Smrg * XRenderExtFindDisplay - look for a display in this extension; keeps a 381f0ac6a5Smrg * cache of the most-recently used for efficiency. (Replaces 391f0ac6a5Smrg * XextFindDisplay.) 401f0ac6a5Smrg */ 411f0ac6a5Smrgstatic XRenderExtDisplayInfo * 426fae4e5dSmrgXRenderExtFindDisplay (XRenderExtInfo *extinfo, 431f0ac6a5Smrg Display *dpy) 441f0ac6a5Smrg{ 451f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 461f0ac6a5Smrg 471f0ac6a5Smrg /* 481f0ac6a5Smrg * see if this was the most recently accessed display 491f0ac6a5Smrg */ 506fae4e5dSmrg if ((dpyinfo = extinfo->cur) && dpyinfo->display == dpy) 511f0ac6a5Smrg return dpyinfo; 521f0ac6a5Smrg 531f0ac6a5Smrg /* 541f0ac6a5Smrg * look for display in list 551f0ac6a5Smrg */ 561f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 571f0ac6a5Smrg for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 581f0ac6a5Smrg if (dpyinfo->display == dpy) { 591f0ac6a5Smrg extinfo->cur = dpyinfo; /* cache most recently used */ 601f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 611f0ac6a5Smrg return dpyinfo; 621f0ac6a5Smrg } 631f0ac6a5Smrg } 641f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 651f0ac6a5Smrg 661f0ac6a5Smrg return NULL; 671f0ac6a5Smrg} 681f0ac6a5Smrg 691f0ac6a5Smrg/* 701f0ac6a5Smrg * If the server is missing support for any of the required depths on 711f0ac6a5Smrg * any screen, tell the application that Render is not present. 721f0ac6a5Smrg */ 731f0ac6a5Smrg 746fae4e5dSmrg#define DEPTH_MASK(d) (1U << ((d) - 1)) 756fae4e5dSmrg 761f0ac6a5Smrg/* 771f0ac6a5Smrg * Render requires support for depth 1, 4, 8, 24 and 32 pixmaps 781f0ac6a5Smrg */ 791f0ac6a5Smrg 801f0ac6a5Smrg#define REQUIRED_DEPTHS (DEPTH_MASK(1) | \ 811f0ac6a5Smrg DEPTH_MASK(4) | \ 821f0ac6a5Smrg DEPTH_MASK(8) | \ 831f0ac6a5Smrg DEPTH_MASK(24) | \ 841f0ac6a5Smrg DEPTH_MASK(32)) 856fae4e5dSmrg 861f0ac6a5Smrgtypedef struct _DepthCheckRec { 871f0ac6a5Smrg struct _DepthCheckRec *next; 881f0ac6a5Smrg Display *dpy; 891f0ac6a5Smrg CARD32 missing; 901f0ac6a5Smrg unsigned long serial; 911f0ac6a5Smrg} DepthCheckRec, *DepthCheckPtr; 921f0ac6a5Smrg 931f0ac6a5Smrgstatic DepthCheckPtr depthChecks; 941f0ac6a5Smrg 951f0ac6a5Smrgstatic int 961f0ac6a5SmrgXRenderDepthCheckErrorHandler (Display *dpy, XErrorEvent *evt) 971f0ac6a5Smrg{ 981f0ac6a5Smrg if (evt->request_code == X_CreatePixmap && evt->error_code == BadValue) 991f0ac6a5Smrg { 1001f0ac6a5Smrg DepthCheckPtr d; 10153bb355aSmrg 1021f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1031f0ac6a5Smrg for (d = depthChecks; d; d = d->next) 10453bb355aSmrg { 1051f0ac6a5Smrg if (d->dpy == dpy) 1061f0ac6a5Smrg { 1071f0ac6a5Smrg if ((long) (evt->serial - d->serial) >= 0) 1081f0ac6a5Smrg d->missing |= DEPTH_MASK(evt->resourceid); 1091f0ac6a5Smrg break; 1101f0ac6a5Smrg } 11153bb355aSmrg } 1121f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1131f0ac6a5Smrg } 1141f0ac6a5Smrg return 0; 1151f0ac6a5Smrg} 1161f0ac6a5Smrg 1171f0ac6a5Smrgstatic Bool 1181f0ac6a5SmrgXRenderHasDepths (Display *dpy) 1191f0ac6a5Smrg{ 1201f0ac6a5Smrg int s; 1211f0ac6a5Smrg 1221f0ac6a5Smrg for (s = 0; s < ScreenCount (dpy); s++) 1231f0ac6a5Smrg { 1241f0ac6a5Smrg CARD32 depths = 0; 1251f0ac6a5Smrg CARD32 missing; 1261f0ac6a5Smrg Screen *scr = ScreenOfDisplay (dpy, s); 1271f0ac6a5Smrg int d; 1281f0ac6a5Smrg 1291f0ac6a5Smrg for (d = 0; d < scr->ndepths; d++) 1301f0ac6a5Smrg depths |= DEPTH_MASK(scr->depths[d].depth); 1311f0ac6a5Smrg missing = ~depths & REQUIRED_DEPTHS; 1321f0ac6a5Smrg if (missing) 1331f0ac6a5Smrg { 1341f0ac6a5Smrg DepthCheckRec dc, **dp; 1351f0ac6a5Smrg XErrorHandler previousHandler; 1361f0ac6a5Smrg 1371f0ac6a5Smrg /* 1381f0ac6a5Smrg * Ok, this is ugly. It should be sufficient at this 1391f0ac6a5Smrg * point to just return False, but Xinerama is broken at 1401f0ac6a5Smrg * this point and only advertises depths which have an 1411f0ac6a5Smrg * associated visual. Of course, the other depths still 1421f0ac6a5Smrg * work, but the only way to find out is to try them. 1431f0ac6a5Smrg */ 1441f0ac6a5Smrg dc.dpy = dpy; 1451f0ac6a5Smrg dc.missing = 0; 1461f0ac6a5Smrg dc.serial = XNextRequest (dpy); 1471f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1481f0ac6a5Smrg dc.next = depthChecks; 1491f0ac6a5Smrg depthChecks = &dc; 1501f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1511f0ac6a5Smrg /* 1521f0ac6a5Smrg * I suspect this is not really thread safe, but Xlib doesn't 1531f0ac6a5Smrg * provide a lot of options here 1541f0ac6a5Smrg */ 1551f0ac6a5Smrg previousHandler = XSetErrorHandler (XRenderDepthCheckErrorHandler); 1561f0ac6a5Smrg /* 1571f0ac6a5Smrg * Try each missing depth and see if pixmap creation succeeds 1581f0ac6a5Smrg */ 1591f0ac6a5Smrg for (d = 1; d <= 32; d++) 1601f0ac6a5Smrg /* don't check depth 1 == Xcursor recurses... */ 1611f0ac6a5Smrg if ((missing & DEPTH_MASK(d)) && d != 1) 1621f0ac6a5Smrg { 1631f0ac6a5Smrg Pixmap p; 16453bb355aSmrg p = XCreatePixmap (dpy, RootWindow (dpy, s), 1, 1, (unsigned) d); 1651f0ac6a5Smrg XFreePixmap (dpy, p); 1661f0ac6a5Smrg } 1671f0ac6a5Smrg XSync (dpy, False); 1681f0ac6a5Smrg XSetErrorHandler (previousHandler); 1691f0ac6a5Smrg /* 1701f0ac6a5Smrg * Unhook from the list of depth check records 1711f0ac6a5Smrg */ 1721f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1731f0ac6a5Smrg for (dp = &depthChecks; *dp; dp = &(*dp)->next) 1741f0ac6a5Smrg { 1751f0ac6a5Smrg if (*dp == &dc) 1761f0ac6a5Smrg { 1771f0ac6a5Smrg *dp = dc.next; 1781f0ac6a5Smrg break; 1791f0ac6a5Smrg } 1801f0ac6a5Smrg } 1811f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1821f0ac6a5Smrg if (dc.missing) 1831f0ac6a5Smrg return False; 1841f0ac6a5Smrg } 1851f0ac6a5Smrg } 1861f0ac6a5Smrg return True; 1871f0ac6a5Smrg} 1881f0ac6a5Smrg 1891f0ac6a5Smrg/* 1901f0ac6a5Smrg * XRenderExtAddDisplay - add a display to this extension. (Replaces 1911f0ac6a5Smrg * XextAddDisplay) 1921f0ac6a5Smrg */ 1931f0ac6a5Smrgstatic XRenderExtDisplayInfo * 1941f0ac6a5SmrgXRenderExtAddDisplay (XRenderExtInfo *extinfo, 1951f0ac6a5Smrg Display *dpy, 1961f0ac6a5Smrg char *ext_name) 1971f0ac6a5Smrg{ 1981f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 1991f0ac6a5Smrg 20053bb355aSmrg dpyinfo = Xmalloc (sizeof (XRenderExtDisplayInfo)); 2011f0ac6a5Smrg if (!dpyinfo) return NULL; 2021f0ac6a5Smrg dpyinfo->display = dpy; 2031f0ac6a5Smrg dpyinfo->info = NULL; 2041f0ac6a5Smrg 2051f0ac6a5Smrg if (XRenderHasDepths (dpy)) 2061f0ac6a5Smrg dpyinfo->codes = XInitExtension (dpy, ext_name); 2071f0ac6a5Smrg else 2081f0ac6a5Smrg dpyinfo->codes = NULL; 2091f0ac6a5Smrg 2101f0ac6a5Smrg /* 2116fae4e5dSmrg * if the server has the extension, then we can initialize the 2121f0ac6a5Smrg * appropriate function vectors 2131f0ac6a5Smrg */ 2141f0ac6a5Smrg if (dpyinfo->codes) { 2156fae4e5dSmrg XESetCloseDisplay (dpy, dpyinfo->codes->extension, 2161f0ac6a5Smrg XRenderCloseDisplay); 2171f0ac6a5Smrg } else { 2181f0ac6a5Smrg /* The server doesn't have this extension. 2191f0ac6a5Smrg * Use a private Xlib-internal extension to hang the close_display 2201f0ac6a5Smrg * hook on so that the "cache" (extinfo->cur) is properly cleaned. 2211f0ac6a5Smrg * (XBUG 7955) 2221f0ac6a5Smrg */ 2231f0ac6a5Smrg XExtCodes *codes = XAddExtension(dpy); 2241f0ac6a5Smrg if (!codes) { 2251f0ac6a5Smrg XFree(dpyinfo); 2261f0ac6a5Smrg return NULL; 2271f0ac6a5Smrg } 2281f0ac6a5Smrg XESetCloseDisplay (dpy, codes->extension, XRenderCloseDisplay); 2291f0ac6a5Smrg } 2301f0ac6a5Smrg 2311f0ac6a5Smrg /* 2321f0ac6a5Smrg * now, chain it onto the list 2331f0ac6a5Smrg */ 2341f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 2351f0ac6a5Smrg dpyinfo->next = extinfo->head; 2361f0ac6a5Smrg extinfo->head = dpyinfo; 2371f0ac6a5Smrg extinfo->cur = dpyinfo; 2381f0ac6a5Smrg extinfo->ndisplays++; 2391f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2401f0ac6a5Smrg return dpyinfo; 2411f0ac6a5Smrg} 2421f0ac6a5Smrg 2431f0ac6a5Smrg 2441f0ac6a5Smrg/* 2451f0ac6a5Smrg * XRenderExtRemoveDisplay - remove the indicated display from the 2461f0ac6a5Smrg * extension object. (Replaces XextRemoveDisplay.) 2471f0ac6a5Smrg */ 2486fae4e5dSmrgstatic int 2491f0ac6a5SmrgXRenderExtRemoveDisplay (XRenderExtInfo *extinfo, Display *dpy) 2501f0ac6a5Smrg{ 2511f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo, *prev; 2521f0ac6a5Smrg 2531f0ac6a5Smrg /* 2541f0ac6a5Smrg * locate this display and its back link so that it can be removed 2551f0ac6a5Smrg */ 2561f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 2571f0ac6a5Smrg prev = NULL; 2581f0ac6a5Smrg for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 2591f0ac6a5Smrg if (dpyinfo->display == dpy) break; 2601f0ac6a5Smrg prev = dpyinfo; 2611f0ac6a5Smrg } 2621f0ac6a5Smrg if (!dpyinfo) { 2631f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2641f0ac6a5Smrg return 0; /* hmm, actually an error */ 2651f0ac6a5Smrg } 2661f0ac6a5Smrg 2671f0ac6a5Smrg /* 2681f0ac6a5Smrg * remove the display from the list; handles going to zero 2691f0ac6a5Smrg */ 2701f0ac6a5Smrg if (prev) 2711f0ac6a5Smrg prev->next = dpyinfo->next; 2721f0ac6a5Smrg else 2731f0ac6a5Smrg extinfo->head = dpyinfo->next; 2741f0ac6a5Smrg 2751f0ac6a5Smrg extinfo->ndisplays--; 2761f0ac6a5Smrg if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */ 2771f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2781f0ac6a5Smrg 27953bb355aSmrg Xfree (dpyinfo); 2801f0ac6a5Smrg return 1; 2811f0ac6a5Smrg} 2821f0ac6a5Smrg 2831f0ac6a5Smrg 2841f0ac6a5Smrg 2851f0ac6a5SmrgXRenderExtDisplayInfo * 2861f0ac6a5SmrgXRenderFindDisplay (Display *dpy) 2871f0ac6a5Smrg{ 2881f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 2891f0ac6a5Smrg 2901f0ac6a5Smrg dpyinfo = XRenderExtFindDisplay (&XRenderExtensionInfo, dpy); 2911f0ac6a5Smrg if (!dpyinfo) 2926fae4e5dSmrg dpyinfo = XRenderExtAddDisplay (&XRenderExtensionInfo, dpy, 2931f0ac6a5Smrg XRenderExtensionName); 2941f0ac6a5Smrg return dpyinfo; 2951f0ac6a5Smrg} 2961f0ac6a5Smrg 29741e04fc9Smrgstatic void 29841e04fc9SmrgXRenderFreeXRenderInfo (XRenderInfo *xri) 29941e04fc9Smrg{ 30041e04fc9Smrg Xfree(xri->format); 30141e04fc9Smrg Xfree(xri->screen); 30241e04fc9Smrg Xfree(xri->depth); 30341e04fc9Smrg Xfree(xri->visual); 30441e04fc9Smrg Xfree(xri); 30541e04fc9Smrg} 30641e04fc9Smrg 3071f0ac6a5Smrgstatic int 30853bb355aSmrgXRenderCloseDisplay (Display *dpy, XExtCodes *codes _X_UNUSED) 3091f0ac6a5Smrg{ 3101f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 31141e04fc9Smrg if (info && info->info) XRenderFreeXRenderInfo (info->info); 3126fae4e5dSmrg 3131f0ac6a5Smrg return XRenderExtRemoveDisplay (&XRenderExtensionInfo, dpy); 3141f0ac6a5Smrg} 3156fae4e5dSmrg 3161f0ac6a5Smrg/**************************************************************************** 3171f0ac6a5Smrg * * 3181f0ac6a5Smrg * Render public interfaces * 3191f0ac6a5Smrg * * 3201f0ac6a5Smrg ****************************************************************************/ 3211f0ac6a5Smrg 3221f0ac6a5SmrgBool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep) 3231f0ac6a5Smrg{ 3241f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3251f0ac6a5Smrg 3261f0ac6a5Smrg if (RenderHasExtension(info)) { 3271f0ac6a5Smrg *event_basep = info->codes->first_event; 3281f0ac6a5Smrg *error_basep = info->codes->first_error; 3291f0ac6a5Smrg return True; 3301f0ac6a5Smrg } else { 3311f0ac6a5Smrg return False; 3321f0ac6a5Smrg } 3331f0ac6a5Smrg} 3341f0ac6a5Smrg 3351f0ac6a5Smrg 3361f0ac6a5SmrgStatus XRenderQueryVersion (Display *dpy, 3371f0ac6a5Smrg int *major_versionp, 3381f0ac6a5Smrg int *minor_versionp) 3391f0ac6a5Smrg{ 3401f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3411f0ac6a5Smrg XRenderInfo *xri; 3421f0ac6a5Smrg 3431f0ac6a5Smrg if (!RenderHasExtension (info)) 3441f0ac6a5Smrg return 0; 3451f0ac6a5Smrg 3461f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 3471f0ac6a5Smrg return 0; 3486fae4e5dSmrg 3496fae4e5dSmrg xri = info->info; 3501f0ac6a5Smrg *major_versionp = xri->major_version; 3511f0ac6a5Smrg *minor_versionp = xri->minor_version; 3521f0ac6a5Smrg return 1; 3531f0ac6a5Smrg} 3541f0ac6a5Smrg 3551f0ac6a5Smrgstatic XRenderPictFormat * 3561f0ac6a5Smrg_XRenderFindFormat (XRenderInfo *xri, PictFormat format) 3571f0ac6a5Smrg{ 3581f0ac6a5Smrg int nf; 3596fae4e5dSmrg 3601f0ac6a5Smrg for (nf = 0; nf < xri->nformat; nf++) 3611f0ac6a5Smrg if (xri->format[nf].id == format) 3621f0ac6a5Smrg return &xri->format[nf]; 363e5410a46Smrg return NULL; 3641f0ac6a5Smrg} 3651f0ac6a5Smrg 3661f0ac6a5Smrgstatic Visual * 3671f0ac6a5Smrg_XRenderFindVisual (Display *dpy, VisualID vid) 3681f0ac6a5Smrg{ 3691f0ac6a5Smrg return _XVIDtoVisual (dpy, vid); 3701f0ac6a5Smrg} 3711f0ac6a5Smrg 3721f0ac6a5Smrgtypedef struct _renderVersionState { 3731f0ac6a5Smrg unsigned long version_seq; 3741f0ac6a5Smrg Bool error; 3751f0ac6a5Smrg int major_version; 3761f0ac6a5Smrg int minor_version; 3776fae4e5dSmrg 3781f0ac6a5Smrg} _XrenderVersionState; 3791f0ac6a5Smrg 3801f0ac6a5Smrgstatic Bool 3811f0ac6a5Smrg_XRenderVersionHandler (Display *dpy, 3821f0ac6a5Smrg xReply *rep, 3831f0ac6a5Smrg char *buf, 3841f0ac6a5Smrg int len, 3851f0ac6a5Smrg XPointer data) 3861f0ac6a5Smrg{ 3871f0ac6a5Smrg xRenderQueryVersionReply replbuf; 3881f0ac6a5Smrg xRenderQueryVersionReply *repl; 3891f0ac6a5Smrg _XrenderVersionState *state = (_XrenderVersionState *) data; 3901f0ac6a5Smrg 3911f0ac6a5Smrg if (dpy->last_request_read != state->version_seq) 3921f0ac6a5Smrg return False; 3931f0ac6a5Smrg if (rep->generic.type == X_Error) 3941f0ac6a5Smrg { 3951f0ac6a5Smrg state->error = True; 3961f0ac6a5Smrg return False; 3971f0ac6a5Smrg } 3981f0ac6a5Smrg repl = (xRenderQueryVersionReply *) 3991f0ac6a5Smrg _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, 4001f0ac6a5Smrg (SIZEOF(xRenderQueryVersionReply) - SIZEOF(xReply)) >> 2, 4011f0ac6a5Smrg True); 40253bb355aSmrg state->major_version = (int) repl->majorVersion; 40353bb355aSmrg state->minor_version = (int) repl->minorVersion; 4041f0ac6a5Smrg return True; 4051f0ac6a5Smrg} 4061f0ac6a5Smrg 4071f0ac6a5SmrgStatus 4081f0ac6a5SmrgXRenderQueryFormats (Display *dpy) 4091f0ac6a5Smrg{ 41053bb355aSmrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 4111f0ac6a5Smrg _XAsyncHandler async; 4121f0ac6a5Smrg _XrenderVersionState async_state; 4131f0ac6a5Smrg xRenderQueryVersionReq *vreq; 4141f0ac6a5Smrg xRenderQueryPictFormatsReply rep; 4151f0ac6a5Smrg xRenderQueryPictFormatsReq *req; 4161f0ac6a5Smrg XRenderInfo *xri; 4171f0ac6a5Smrg XRenderPictFormat *format; 4181f0ac6a5Smrg XRenderScreen *screen; 4191f0ac6a5Smrg XRenderDepth *depth; 4201f0ac6a5Smrg XRenderVisual *visual; 4211f0ac6a5Smrg xPictFormInfo *xFormat; 4221f0ac6a5Smrg xPictScreen *xScreen; 42353bb355aSmrg xPictDepth *xPDepth; 4241f0ac6a5Smrg xPictVisual *xVisual; 4251f0ac6a5Smrg CARD32 *xSubpixel; 4261f0ac6a5Smrg void *xData; 42753bb355aSmrg int ns, nd; 42853bb355aSmrg unsigned nf; 429190694daSmrg unsigned long rlength; 430190694daSmrg unsigned long nbytes; 4316fae4e5dSmrg 4321f0ac6a5Smrg RenderCheckExtension (dpy, info, 0); 4331f0ac6a5Smrg LockDisplay (dpy); 4341f0ac6a5Smrg if (info->info) 4351f0ac6a5Smrg { 4361f0ac6a5Smrg UnlockDisplay (dpy); 4371f0ac6a5Smrg return 1; 4381f0ac6a5Smrg } 4391f0ac6a5Smrg GetReq (RenderQueryVersion, vreq); 44053bb355aSmrg vreq->reqType = (CARD8) info->codes->major_opcode; 4411f0ac6a5Smrg vreq->renderReqType = X_RenderQueryVersion; 4421f0ac6a5Smrg vreq->majorVersion = RENDER_MAJOR; 4431f0ac6a5Smrg vreq->minorVersion = RENDER_MINOR; 4446fae4e5dSmrg 4451f0ac6a5Smrg async_state.version_seq = dpy->request; 4461f0ac6a5Smrg async_state.error = False; 4471f0ac6a5Smrg async.next = dpy->async_handlers; 4481f0ac6a5Smrg async.handler = _XRenderVersionHandler; 4491f0ac6a5Smrg async.data = (XPointer) &async_state; 4501f0ac6a5Smrg dpy->async_handlers = &async; 4516fae4e5dSmrg 4521f0ac6a5Smrg GetReq (RenderQueryPictFormats, req); 45353bb355aSmrg req->reqType = (CARD8) info->codes->major_opcode; 4541f0ac6a5Smrg req->renderReqType = X_RenderQueryPictFormats; 4556fae4e5dSmrg 4566fae4e5dSmrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 4571f0ac6a5Smrg { 4581f0ac6a5Smrg DeqAsyncHandler (dpy, &async); 4591f0ac6a5Smrg UnlockDisplay (dpy); 4601f0ac6a5Smrg SyncHandle (); 4611f0ac6a5Smrg return 0; 4621f0ac6a5Smrg } 4631f0ac6a5Smrg DeqAsyncHandler (dpy, &async); 4641f0ac6a5Smrg if (async_state.error) 4651f0ac6a5Smrg { 4661f0ac6a5Smrg UnlockDisplay(dpy); 4671f0ac6a5Smrg SyncHandle(); 4681f0ac6a5Smrg return 0; 4691f0ac6a5Smrg } 4701f0ac6a5Smrg /* 4711f0ac6a5Smrg * Check for the lack of sub-pixel data 4721f0ac6a5Smrg */ 4731f0ac6a5Smrg if (async_state.major_version == 0 && async_state.minor_version < 6) 4741f0ac6a5Smrg rep.numSubpixel = 0; 4756fae4e5dSmrg 476190694daSmrg if ((rep.numFormats < ((INT_MAX / 4) / sizeof (XRenderPictFormat))) && 477190694daSmrg (rep.numScreens < ((INT_MAX / 4) / sizeof (XRenderScreen))) && 478190694daSmrg (rep.numDepths < ((INT_MAX / 4) / sizeof (XRenderDepth))) && 479190694daSmrg (rep.numVisuals < ((INT_MAX / 4) / sizeof (XRenderVisual))) && 480190694daSmrg (rep.numSubpixel < ((INT_MAX / 4) / 4)) && 481190694daSmrg (rep.length < (INT_MAX >> 2)) ) { 48241e04fc9Smrg /* Zero-initialize so that pointers are NULL if there is a failure. */ 48341e04fc9Smrg xri = Xcalloc (1, sizeof (XRenderInfo)); 484190694daSmrg rlength = ((rep.numFormats * sizeof (xPictFormInfo)) + 485190694daSmrg (rep.numScreens * sizeof (xPictScreen)) + 486190694daSmrg (rep.numDepths * sizeof (xPictDepth)) + 487190694daSmrg (rep.numVisuals * sizeof (xPictVisual)) + 488190694daSmrg (rep.numSubpixel * 4)); 489190694daSmrg xData = Xmalloc (rlength); 490190694daSmrg nbytes = (unsigned long) rep.length << 2; 491190694daSmrg } else { 492190694daSmrg xri = NULL; 493190694daSmrg xData = NULL; 494190694daSmrg rlength = nbytes = 0; 495190694daSmrg } 4966fae4e5dSmrg 4971f0ac6a5Smrg if (!xri || !xData || nbytes < rlength) 4981f0ac6a5Smrg { 4991f0ac6a5Smrg if (xri) Xfree (xri); 5001f0ac6a5Smrg if (xData) Xfree (xData); 501cc1b55f9Smrg _XEatDataWords (dpy, rep.length); 5021f0ac6a5Smrg UnlockDisplay (dpy); 5031f0ac6a5Smrg SyncHandle (); 5041f0ac6a5Smrg return 0; 5051f0ac6a5Smrg } 5061f0ac6a5Smrg xri->major_version = async_state.major_version; 5071f0ac6a5Smrg xri->minor_version = async_state.minor_version; 50841e04fc9Smrg xri->format = Xcalloc(rep.numFormats, sizeof(XRenderPictFormat)); 50953bb355aSmrg xri->nformat = (int) rep.numFormats; 51041e04fc9Smrg xri->screen = Xcalloc(rep.numScreens, sizeof(XRenderScreen)); 51153bb355aSmrg xri->nscreen = (int) rep.numScreens; 51241e04fc9Smrg xri->depth = Xcalloc(rep.numDepths, sizeof(XRenderDepth)); 51353bb355aSmrg xri->ndepth = (int) rep.numDepths; 51441e04fc9Smrg xri->visual = Xcalloc(rep.numVisuals, sizeof(XRenderVisual)); 51553bb355aSmrg xri->nvisual = (int) rep.numVisuals; 51641e04fc9Smrg if (!xri->format || !xri->screen || !xri->depth || !xri->visual) 51741e04fc9Smrg { 51841e04fc9Smrg XRenderFreeXRenderInfo(xri); 51941e04fc9Smrg Xfree (xData); 52041e04fc9Smrg _XEatDataWords (dpy, rep.length); 52141e04fc9Smrg UnlockDisplay (dpy); 52241e04fc9Smrg SyncHandle (); 52341e04fc9Smrg return 0; 52441e04fc9Smrg } 52553bb355aSmrg _XRead (dpy, (char *) xData, (long) rlength); 5261f0ac6a5Smrg format = xri->format; 5271f0ac6a5Smrg xFormat = (xPictFormInfo *) xData; 5281f0ac6a5Smrg for (nf = 0; nf < rep.numFormats; nf++) 5291f0ac6a5Smrg { 5301f0ac6a5Smrg format->id = xFormat->id; 5311f0ac6a5Smrg format->type = xFormat->type; 5321f0ac6a5Smrg format->depth = xFormat->depth; 53353bb355aSmrg format->direct.red = (short) xFormat->direct.red; 53453bb355aSmrg format->direct.redMask = (short) xFormat->direct.redMask; 53553bb355aSmrg format->direct.green = (short) xFormat->direct.green; 53653bb355aSmrg format->direct.greenMask = (short) xFormat->direct.greenMask; 53753bb355aSmrg format->direct.blue = (short) xFormat->direct.blue; 53853bb355aSmrg format->direct.blueMask = (short) xFormat->direct.blueMask; 53953bb355aSmrg format->direct.alpha = (short) xFormat->direct.alpha; 54053bb355aSmrg format->direct.alphaMask = (short) xFormat->direct.alphaMask; 5411f0ac6a5Smrg format->colormap = xFormat->colormap; 5421f0ac6a5Smrg format++; 5431f0ac6a5Smrg xFormat++; 5441f0ac6a5Smrg } 5451f0ac6a5Smrg xScreen = (xPictScreen *) xFormat; 5461f0ac6a5Smrg screen = xri->screen; 5471f0ac6a5Smrg depth = xri->depth; 5481f0ac6a5Smrg visual = xri->visual; 5491f0ac6a5Smrg for (ns = 0; ns < xri->nscreen; ns++) 5501f0ac6a5Smrg { 5511f0ac6a5Smrg screen->depths = depth; 55253bb355aSmrg screen->ndepths = (int) xScreen->nDepth; 5531f0ac6a5Smrg screen->fallback = _XRenderFindFormat (xri, xScreen->fallback); 5541f0ac6a5Smrg screen->subpixel = SubPixelUnknown; 55553bb355aSmrg xPDepth = (xPictDepth *) (xScreen + 1); 556f1c62215Smrg if (screen->ndepths > rep.numDepths) { 55741e04fc9Smrg XRenderFreeXRenderInfo(xri); 558f1c62215Smrg Xfree (xData); 559f1c62215Smrg _XEatDataWords (dpy, rep.length); 560f1c62215Smrg UnlockDisplay (dpy); 561f1c62215Smrg SyncHandle (); 562f1c62215Smrg return 0; 563f1c62215Smrg } 56453bb355aSmrg rep.numDepths -= (CARD32) screen->ndepths; 5651f0ac6a5Smrg for (nd = 0; nd < screen->ndepths; nd++) 5661f0ac6a5Smrg { 56753bb355aSmrg int nv; 56853bb355aSmrg 56953bb355aSmrg depth->depth = xPDepth->depth; 57053bb355aSmrg depth->nvisuals = xPDepth->nPictVisuals; 5711f0ac6a5Smrg depth->visuals = visual; 57253bb355aSmrg xVisual = (xPictVisual *) (xPDepth + 1); 573f1c62215Smrg if (depth->nvisuals > rep.numVisuals) { 57441e04fc9Smrg XRenderFreeXRenderInfo (xri); 575f1c62215Smrg Xfree (xData); 576f1c62215Smrg _XEatDataWords (dpy, rep.length); 577f1c62215Smrg UnlockDisplay (dpy); 578f1c62215Smrg SyncHandle (); 579f1c62215Smrg return 0; 580f1c62215Smrg } 58153bb355aSmrg rep.numVisuals -= (CARD32) depth->nvisuals; 5821f0ac6a5Smrg for (nv = 0; nv < depth->nvisuals; nv++) 5831f0ac6a5Smrg { 5841f0ac6a5Smrg visual->visual = _XRenderFindVisual (dpy, xVisual->visual); 5851f0ac6a5Smrg visual->format = _XRenderFindFormat (xri, xVisual->format); 5861f0ac6a5Smrg visual++; 5871f0ac6a5Smrg xVisual++; 5881f0ac6a5Smrg } 5891f0ac6a5Smrg depth++; 59053bb355aSmrg xPDepth = (xPictDepth *) xVisual; 5911f0ac6a5Smrg } 5921f0ac6a5Smrg screen++; 59353bb355aSmrg xScreen = (xPictScreen *) xPDepth; 5941f0ac6a5Smrg } 5951f0ac6a5Smrg xSubpixel = (CARD32 *) xScreen; 5961f0ac6a5Smrg screen = xri->screen; 5971f0ac6a5Smrg for (ns = 0; ns < rep.numSubpixel; ns++) 5981f0ac6a5Smrg { 59953bb355aSmrg screen->subpixel = (int) *xSubpixel; 6001f0ac6a5Smrg xSubpixel++; 6011f0ac6a5Smrg screen++; 6021f0ac6a5Smrg } 6031f0ac6a5Smrg info->info = xri; 6041f0ac6a5Smrg /* 6051f0ac6a5Smrg * Skip any extra data 6061f0ac6a5Smrg */ 6071f0ac6a5Smrg if (nbytes > rlength) 6081f0ac6a5Smrg _XEatData (dpy, (unsigned long) (nbytes - rlength)); 6096fae4e5dSmrg 6101f0ac6a5Smrg UnlockDisplay (dpy); 6111f0ac6a5Smrg SyncHandle (); 6121f0ac6a5Smrg Xfree (xData); 6131f0ac6a5Smrg return 1; 6141f0ac6a5Smrg} 6151f0ac6a5Smrg 6161f0ac6a5Smrgint 6171f0ac6a5SmrgXRenderQuerySubpixelOrder (Display *dpy, int screen) 6181f0ac6a5Smrg{ 6191f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6201f0ac6a5Smrg XRenderInfo *xri; 6211f0ac6a5Smrg 6221f0ac6a5Smrg if (!RenderHasExtension (info)) 6231f0ac6a5Smrg return SubPixelUnknown; 6241f0ac6a5Smrg 6251f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 6261f0ac6a5Smrg return SubPixelUnknown; 6271f0ac6a5Smrg 6281f0ac6a5Smrg xri = info->info; 6291f0ac6a5Smrg return xri->screen[screen].subpixel; 6301f0ac6a5Smrg} 6311f0ac6a5Smrg 6321f0ac6a5SmrgBool 6331f0ac6a5SmrgXRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel) 6341f0ac6a5Smrg{ 6351f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6361f0ac6a5Smrg XRenderInfo *xri; 6371f0ac6a5Smrg 6381f0ac6a5Smrg if (!RenderHasExtension (info)) 6391f0ac6a5Smrg return False; 6401f0ac6a5Smrg 6411f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 6421f0ac6a5Smrg return False; 6431f0ac6a5Smrg 6441f0ac6a5Smrg xri = info->info; 6451f0ac6a5Smrg xri->screen[screen].subpixel = subpixel; 6461f0ac6a5Smrg return True; 6471f0ac6a5Smrg} 6481f0ac6a5Smrg 6491f0ac6a5SmrgXRenderPictFormat * 6501f0ac6a5SmrgXRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual) 6511f0ac6a5Smrg{ 6521f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6531f0ac6a5Smrg int nv; 6541f0ac6a5Smrg XRenderInfo *xri; 6551f0ac6a5Smrg XRenderVisual *xrv; 656e5410a46Smrg 657e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 6581f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 659e5410a46Smrg return NULL; 6601f0ac6a5Smrg xri = info->info; 6611f0ac6a5Smrg for (nv = 0, xrv = xri->visual; nv < xri->nvisual; nv++, xrv++) 6621f0ac6a5Smrg if (xrv->visual == visual) 6631f0ac6a5Smrg return xrv->format; 664e5410a46Smrg return NULL; 6651f0ac6a5Smrg} 6661f0ac6a5Smrg 6671f0ac6a5SmrgXRenderPictFormat * 6681f0ac6a5SmrgXRenderFindFormat (Display *dpy, 6691f0ac6a5Smrg unsigned long mask, 6701f0ac6a5Smrg _Xconst XRenderPictFormat *template, 6711f0ac6a5Smrg int count) 6721f0ac6a5Smrg{ 6731f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6741f0ac6a5Smrg int nf; 6751f0ac6a5Smrg XRenderInfo *xri; 676e5410a46Smrg 677e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 6781f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 679e5410a46Smrg return NULL; 6801f0ac6a5Smrg xri = info->info; 6811f0ac6a5Smrg for (nf = 0; nf < xri->nformat; nf++) 6821f0ac6a5Smrg { 6831f0ac6a5Smrg if (mask & PictFormatID) 6841f0ac6a5Smrg if (template->id != xri->format[nf].id) 6851f0ac6a5Smrg continue; 6861f0ac6a5Smrg if (mask & PictFormatType) 6871f0ac6a5Smrg if (template->type != xri->format[nf].type) 6881f0ac6a5Smrg continue; 6891f0ac6a5Smrg if (mask & PictFormatDepth) 6901f0ac6a5Smrg if (template->depth != xri->format[nf].depth) 6911f0ac6a5Smrg continue; 6921f0ac6a5Smrg if (mask & PictFormatRed) 6931f0ac6a5Smrg if (template->direct.red != xri->format[nf].direct.red) 6941f0ac6a5Smrg continue; 6951f0ac6a5Smrg if (mask & PictFormatRedMask) 6961f0ac6a5Smrg if (template->direct.redMask != xri->format[nf].direct.redMask) 6971f0ac6a5Smrg continue; 6981f0ac6a5Smrg if (mask & PictFormatGreen) 6991f0ac6a5Smrg if (template->direct.green != xri->format[nf].direct.green) 7001f0ac6a5Smrg continue; 7011f0ac6a5Smrg if (mask & PictFormatGreenMask) 7021f0ac6a5Smrg if (template->direct.greenMask != xri->format[nf].direct.greenMask) 7031f0ac6a5Smrg continue; 7041f0ac6a5Smrg if (mask & PictFormatBlue) 7051f0ac6a5Smrg if (template->direct.blue != xri->format[nf].direct.blue) 7061f0ac6a5Smrg continue; 7071f0ac6a5Smrg if (mask & PictFormatBlueMask) 7081f0ac6a5Smrg if (template->direct.blueMask != xri->format[nf].direct.blueMask) 7091f0ac6a5Smrg continue; 7101f0ac6a5Smrg if (mask & PictFormatAlpha) 7111f0ac6a5Smrg if (template->direct.alpha != xri->format[nf].direct.alpha) 7121f0ac6a5Smrg continue; 7131f0ac6a5Smrg if (mask & PictFormatAlphaMask) 7141f0ac6a5Smrg if (template->direct.alphaMask != xri->format[nf].direct.alphaMask) 7151f0ac6a5Smrg continue; 7161f0ac6a5Smrg if (mask & PictFormatColormap) 7171f0ac6a5Smrg if (template->colormap != xri->format[nf].colormap) 7181f0ac6a5Smrg continue; 7191f0ac6a5Smrg if (count-- == 0) 7201f0ac6a5Smrg return &xri->format[nf]; 7211f0ac6a5Smrg } 722e5410a46Smrg return NULL; 7231f0ac6a5Smrg} 7241f0ac6a5Smrg 7251f0ac6a5SmrgXRenderPictFormat * 7261f0ac6a5SmrgXRenderFindStandardFormat (Display *dpy, 7271f0ac6a5Smrg int format) 7281f0ac6a5Smrg{ 7291f0ac6a5Smrg static struct { 7301f0ac6a5Smrg XRenderPictFormat templ; 7311f0ac6a5Smrg unsigned long mask; 7321f0ac6a5Smrg } standardFormats[PictStandardNUM] = { 7331f0ac6a5Smrg /* PictStandardARGB32 */ 7341f0ac6a5Smrg { 7351f0ac6a5Smrg { 7361f0ac6a5Smrg 0, /* id */ 7371f0ac6a5Smrg PictTypeDirect, /* type */ 7381f0ac6a5Smrg 32, /* depth */ 7391f0ac6a5Smrg { /* direct */ 7401f0ac6a5Smrg 16, /* direct.red */ 7411f0ac6a5Smrg 0xff, /* direct.redMask */ 7421f0ac6a5Smrg 8, /* direct.green */ 7431f0ac6a5Smrg 0xff, /* direct.greenMask */ 7441f0ac6a5Smrg 0, /* direct.blue */ 7451f0ac6a5Smrg 0xff, /* direct.blueMask */ 7461f0ac6a5Smrg 24, /* direct.alpha */ 7471f0ac6a5Smrg 0xff, /* direct.alphaMask */ 7481f0ac6a5Smrg }, 7491f0ac6a5Smrg 0, /* colormap */ 7501f0ac6a5Smrg }, 7516fae4e5dSmrg PictFormatType | 7521f0ac6a5Smrg PictFormatDepth | 7531f0ac6a5Smrg PictFormatRed | 7541f0ac6a5Smrg PictFormatRedMask | 7551f0ac6a5Smrg PictFormatGreen | 7561f0ac6a5Smrg PictFormatGreenMask | 7571f0ac6a5Smrg PictFormatBlue | 7581f0ac6a5Smrg PictFormatBlueMask | 7591f0ac6a5Smrg PictFormatAlpha | 7601f0ac6a5Smrg PictFormatAlphaMask, 7611f0ac6a5Smrg }, 7621f0ac6a5Smrg /* PictStandardRGB24 */ 7631f0ac6a5Smrg { 7641f0ac6a5Smrg { 7651f0ac6a5Smrg 0, /* id */ 7661f0ac6a5Smrg PictTypeDirect, /* type */ 7671f0ac6a5Smrg 24, /* depth */ 7681f0ac6a5Smrg { /* direct */ 7691f0ac6a5Smrg 16, /* direct.red */ 7701f0ac6a5Smrg 0xff, /* direct.redMask */ 7711f0ac6a5Smrg 8, /* direct.green */ 7721f0ac6a5Smrg 0xff, /* direct.greenMask */ 7731f0ac6a5Smrg 0, /* direct.blue */ 7741f0ac6a5Smrg 0xff, /* direct.blueMask */ 7751f0ac6a5Smrg 0, /* direct.alpha */ 7761f0ac6a5Smrg 0x00, /* direct.alphaMask */ 7771f0ac6a5Smrg }, 7781f0ac6a5Smrg 0, /* colormap */ 7791f0ac6a5Smrg }, 7806fae4e5dSmrg PictFormatType | 7811f0ac6a5Smrg PictFormatDepth | 7821f0ac6a5Smrg PictFormatRed | 7831f0ac6a5Smrg PictFormatRedMask | 7841f0ac6a5Smrg PictFormatGreen | 7851f0ac6a5Smrg PictFormatGreenMask | 7861f0ac6a5Smrg PictFormatBlue | 7871f0ac6a5Smrg PictFormatBlueMask | 7881f0ac6a5Smrg PictFormatAlphaMask, 7891f0ac6a5Smrg }, 7901f0ac6a5Smrg /* PictStandardA8 */ 7911f0ac6a5Smrg { 7921f0ac6a5Smrg { 7931f0ac6a5Smrg 0, /* id */ 7941f0ac6a5Smrg PictTypeDirect, /* type */ 7951f0ac6a5Smrg 8, /* depth */ 7961f0ac6a5Smrg { /* direct */ 7971f0ac6a5Smrg 0, /* direct.red */ 7981f0ac6a5Smrg 0x00, /* direct.redMask */ 7991f0ac6a5Smrg 0, /* direct.green */ 8001f0ac6a5Smrg 0x00, /* direct.greenMask */ 8011f0ac6a5Smrg 0, /* direct.blue */ 8021f0ac6a5Smrg 0x00, /* direct.blueMask */ 8031f0ac6a5Smrg 0, /* direct.alpha */ 8041f0ac6a5Smrg 0xff, /* direct.alphaMask */ 8051f0ac6a5Smrg }, 8061f0ac6a5Smrg 0, /* colormap */ 8071f0ac6a5Smrg }, 8086fae4e5dSmrg PictFormatType | 8091f0ac6a5Smrg PictFormatDepth | 8101f0ac6a5Smrg PictFormatRedMask | 8111f0ac6a5Smrg PictFormatGreenMask | 8121f0ac6a5Smrg PictFormatBlueMask | 8131f0ac6a5Smrg PictFormatAlpha | 8141f0ac6a5Smrg PictFormatAlphaMask, 8151f0ac6a5Smrg }, 8161f0ac6a5Smrg /* PictStandardA4 */ 8171f0ac6a5Smrg { 8181f0ac6a5Smrg { 8191f0ac6a5Smrg 0, /* id */ 8201f0ac6a5Smrg PictTypeDirect, /* type */ 8211f0ac6a5Smrg 4, /* depth */ 8221f0ac6a5Smrg { /* direct */ 8231f0ac6a5Smrg 0, /* direct.red */ 8241f0ac6a5Smrg 0x00, /* direct.redMask */ 8251f0ac6a5Smrg 0, /* direct.green */ 8261f0ac6a5Smrg 0x00, /* direct.greenMask */ 8271f0ac6a5Smrg 0, /* direct.blue */ 8281f0ac6a5Smrg 0x00, /* direct.blueMask */ 8291f0ac6a5Smrg 0, /* direct.alpha */ 8301f0ac6a5Smrg 0x0f, /* direct.alphaMask */ 8311f0ac6a5Smrg }, 8321f0ac6a5Smrg 0, /* colormap */ 8331f0ac6a5Smrg }, 8346fae4e5dSmrg PictFormatType | 8351f0ac6a5Smrg PictFormatDepth | 8361f0ac6a5Smrg PictFormatRedMask | 8371f0ac6a5Smrg PictFormatGreenMask | 8381f0ac6a5Smrg PictFormatBlueMask | 8391f0ac6a5Smrg PictFormatAlpha | 8401f0ac6a5Smrg PictFormatAlphaMask, 8411f0ac6a5Smrg }, 8421f0ac6a5Smrg /* PictStandardA1 */ 8431f0ac6a5Smrg { 8441f0ac6a5Smrg { 8451f0ac6a5Smrg 0, /* id */ 8461f0ac6a5Smrg PictTypeDirect, /* type */ 8471f0ac6a5Smrg 1, /* depth */ 8481f0ac6a5Smrg { /* direct */ 8491f0ac6a5Smrg 0, /* direct.red */ 8501f0ac6a5Smrg 0x00, /* direct.redMask */ 8511f0ac6a5Smrg 0, /* direct.green */ 8521f0ac6a5Smrg 0x00, /* direct.greenMask */ 8531f0ac6a5Smrg 0, /* direct.blue */ 8541f0ac6a5Smrg 0x00, /* direct.blueMask */ 8551f0ac6a5Smrg 0, /* direct.alpha */ 8561f0ac6a5Smrg 0x01, /* direct.alphaMask */ 8571f0ac6a5Smrg }, 8581f0ac6a5Smrg 0, /* colormap */ 8591f0ac6a5Smrg }, 8606fae4e5dSmrg PictFormatType | 8611f0ac6a5Smrg PictFormatDepth | 8621f0ac6a5Smrg PictFormatRedMask | 8631f0ac6a5Smrg PictFormatGreenMask | 8641f0ac6a5Smrg PictFormatBlueMask | 8651f0ac6a5Smrg PictFormatAlpha | 8661f0ac6a5Smrg PictFormatAlphaMask, 8671f0ac6a5Smrg }, 8681f0ac6a5Smrg }; 8691f0ac6a5Smrg 8701f0ac6a5Smrg if (0 <= format && format < PictStandardNUM) 8716fae4e5dSmrg return XRenderFindFormat (dpy, 8721f0ac6a5Smrg standardFormats[format].mask, 8731f0ac6a5Smrg &standardFormats[format].templ, 8741f0ac6a5Smrg 0); 875e5410a46Smrg return NULL; 8761f0ac6a5Smrg} 8771f0ac6a5Smrg 8781f0ac6a5SmrgXIndexValue * 8791f0ac6a5SmrgXRenderQueryPictIndexValues(Display *dpy, 8801f0ac6a5Smrg _Xconst XRenderPictFormat *format, 8811f0ac6a5Smrg int *num) 8821f0ac6a5Smrg{ 88353bb355aSmrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 8841f0ac6a5Smrg xRenderQueryPictIndexValuesReq *req; 8851f0ac6a5Smrg xRenderQueryPictIndexValuesReply rep; 8861f0ac6a5Smrg XIndexValue *values; 88753bb355aSmrg unsigned int nbytes, nread, i; 8881f0ac6a5Smrg 889e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 8901f0ac6a5Smrg 8911f0ac6a5Smrg LockDisplay (dpy); 8921f0ac6a5Smrg GetReq (RenderQueryPictIndexValues, req); 89353bb355aSmrg req->reqType = (CARD8) info->codes->major_opcode; 8941f0ac6a5Smrg req->renderReqType = X_RenderQueryPictIndexValues; 89553bb355aSmrg req->format = (CARD32) format->id; 8961f0ac6a5Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 8971f0ac6a5Smrg { 8981f0ac6a5Smrg UnlockDisplay (dpy); 8991f0ac6a5Smrg SyncHandle (); 900e5410a46Smrg return NULL; 9011f0ac6a5Smrg } 9021f0ac6a5Smrg 903190694daSmrg if ((rep.length < (INT_MAX >> 2)) && 904190694daSmrg (rep.numIndexValues < (INT_MAX / sizeof (XIndexValue)))) { 90553bb355aSmrg unsigned int rlength; 906190694daSmrg /* request data length */ 907190694daSmrg nbytes = rep.length << 2; 908190694daSmrg /* bytes of actual data in the request */ 909190694daSmrg nread = rep.numIndexValues * SIZEOF (xIndexValue); 910190694daSmrg /* size of array returned to application */ 91153bb355aSmrg rlength = (unsigned) ((unsigned long) rep.numIndexValues * sizeof (XIndexValue)); 912190694daSmrg 913190694daSmrg /* allocate returned data */ 914190694daSmrg values = Xmalloc (rlength); 915190694daSmrg } else { 91653bb355aSmrg nbytes = nread = 0; 917190694daSmrg values = NULL; 918190694daSmrg } 9191f0ac6a5Smrg 9201f0ac6a5Smrg if (!values) 9211f0ac6a5Smrg { 922cc1b55f9Smrg _XEatDataWords (dpy, rep.length); 9231f0ac6a5Smrg UnlockDisplay (dpy); 9241f0ac6a5Smrg SyncHandle (); 925e5410a46Smrg return NULL; 9261f0ac6a5Smrg } 9271f0ac6a5Smrg 9281f0ac6a5Smrg /* read the values one at a time and convert */ 92953bb355aSmrg *num = (int) rep.numIndexValues; 93053bb355aSmrg for (i = 0; i < rep.numIndexValues; i++) 9311f0ac6a5Smrg { 9321f0ac6a5Smrg xIndexValue value; 9336fae4e5dSmrg 9341f0ac6a5Smrg _XRead (dpy, (char *) &value, SIZEOF (xIndexValue)); 9351f0ac6a5Smrg values[i].pixel = value.pixel; 9361f0ac6a5Smrg values[i].red = value.red; 9371f0ac6a5Smrg values[i].green = value.green; 9381f0ac6a5Smrg values[i].blue = value.blue; 9391f0ac6a5Smrg values[i].alpha = value.alpha; 9401f0ac6a5Smrg } 9411f0ac6a5Smrg /* skip any padding */ 9421f0ac6a5Smrg if(nbytes > nread) 9431f0ac6a5Smrg { 9441f0ac6a5Smrg _XEatData (dpy, (unsigned long) (nbytes - nread)); 9451f0ac6a5Smrg } 9461f0ac6a5Smrg UnlockDisplay (dpy); 9471f0ac6a5Smrg SyncHandle (); 9481f0ac6a5Smrg return values; 9491f0ac6a5Smrg} 950