Xrender.c revision 190694da
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; 1011f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1021f0ac6a5Smrg for (d = depthChecks; d; d = d->next) 1031f0ac6a5Smrg if (d->dpy == dpy) 1041f0ac6a5Smrg { 1051f0ac6a5Smrg if ((long) (evt->serial - d->serial) >= 0) 1061f0ac6a5Smrg d->missing |= DEPTH_MASK(evt->resourceid); 1071f0ac6a5Smrg break; 1081f0ac6a5Smrg } 1091f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1101f0ac6a5Smrg } 1111f0ac6a5Smrg return 0; 1121f0ac6a5Smrg} 1131f0ac6a5Smrg 1141f0ac6a5Smrgstatic Bool 1151f0ac6a5SmrgXRenderHasDepths (Display *dpy) 1161f0ac6a5Smrg{ 1171f0ac6a5Smrg int s; 1181f0ac6a5Smrg 1191f0ac6a5Smrg for (s = 0; s < ScreenCount (dpy); s++) 1201f0ac6a5Smrg { 1211f0ac6a5Smrg CARD32 depths = 0; 1221f0ac6a5Smrg CARD32 missing; 1231f0ac6a5Smrg Screen *scr = ScreenOfDisplay (dpy, s); 1241f0ac6a5Smrg int d; 1251f0ac6a5Smrg 1261f0ac6a5Smrg for (d = 0; d < scr->ndepths; d++) 1271f0ac6a5Smrg depths |= DEPTH_MASK(scr->depths[d].depth); 1281f0ac6a5Smrg missing = ~depths & REQUIRED_DEPTHS; 1291f0ac6a5Smrg if (missing) 1301f0ac6a5Smrg { 1311f0ac6a5Smrg DepthCheckRec dc, **dp; 1321f0ac6a5Smrg XErrorHandler previousHandler; 1331f0ac6a5Smrg 1341f0ac6a5Smrg /* 1351f0ac6a5Smrg * Ok, this is ugly. It should be sufficient at this 1361f0ac6a5Smrg * point to just return False, but Xinerama is broken at 1371f0ac6a5Smrg * this point and only advertises depths which have an 1381f0ac6a5Smrg * associated visual. Of course, the other depths still 1391f0ac6a5Smrg * work, but the only way to find out is to try them. 1401f0ac6a5Smrg */ 1411f0ac6a5Smrg dc.dpy = dpy; 1421f0ac6a5Smrg dc.missing = 0; 1431f0ac6a5Smrg dc.serial = XNextRequest (dpy); 1441f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1451f0ac6a5Smrg dc.next = depthChecks; 1461f0ac6a5Smrg depthChecks = &dc; 1471f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1481f0ac6a5Smrg /* 1491f0ac6a5Smrg * I suspect this is not really thread safe, but Xlib doesn't 1501f0ac6a5Smrg * provide a lot of options here 1511f0ac6a5Smrg */ 1521f0ac6a5Smrg previousHandler = XSetErrorHandler (XRenderDepthCheckErrorHandler); 1531f0ac6a5Smrg /* 1541f0ac6a5Smrg * Try each missing depth and see if pixmap creation succeeds 1551f0ac6a5Smrg */ 1561f0ac6a5Smrg for (d = 1; d <= 32; d++) 1571f0ac6a5Smrg /* don't check depth 1 == Xcursor recurses... */ 1581f0ac6a5Smrg if ((missing & DEPTH_MASK(d)) && d != 1) 1591f0ac6a5Smrg { 1601f0ac6a5Smrg Pixmap p; 1611f0ac6a5Smrg p = XCreatePixmap (dpy, RootWindow (dpy, s), 1, 1, d); 1621f0ac6a5Smrg XFreePixmap (dpy, p); 1631f0ac6a5Smrg } 1641f0ac6a5Smrg XSync (dpy, False); 1651f0ac6a5Smrg XSetErrorHandler (previousHandler); 1661f0ac6a5Smrg /* 1671f0ac6a5Smrg * Unhook from the list of depth check records 1681f0ac6a5Smrg */ 1691f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1701f0ac6a5Smrg for (dp = &depthChecks; *dp; dp = &(*dp)->next) 1711f0ac6a5Smrg { 1721f0ac6a5Smrg if (*dp == &dc) 1731f0ac6a5Smrg { 1741f0ac6a5Smrg *dp = dc.next; 1751f0ac6a5Smrg break; 1761f0ac6a5Smrg } 1771f0ac6a5Smrg } 1781f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1791f0ac6a5Smrg if (dc.missing) 1801f0ac6a5Smrg return False; 1811f0ac6a5Smrg } 1821f0ac6a5Smrg } 1831f0ac6a5Smrg return True; 1841f0ac6a5Smrg} 1851f0ac6a5Smrg 1861f0ac6a5Smrg/* 1871f0ac6a5Smrg * XRenderExtAddDisplay - add a display to this extension. (Replaces 1881f0ac6a5Smrg * XextAddDisplay) 1891f0ac6a5Smrg */ 1901f0ac6a5Smrgstatic XRenderExtDisplayInfo * 1911f0ac6a5SmrgXRenderExtAddDisplay (XRenderExtInfo *extinfo, 1921f0ac6a5Smrg Display *dpy, 1931f0ac6a5Smrg char *ext_name) 1941f0ac6a5Smrg{ 1951f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 1961f0ac6a5Smrg 1971f0ac6a5Smrg dpyinfo = (XRenderExtDisplayInfo *) Xmalloc (sizeof (XRenderExtDisplayInfo)); 1981f0ac6a5Smrg if (!dpyinfo) return NULL; 1991f0ac6a5Smrg dpyinfo->display = dpy; 2001f0ac6a5Smrg dpyinfo->info = NULL; 2011f0ac6a5Smrg 2021f0ac6a5Smrg if (XRenderHasDepths (dpy)) 2031f0ac6a5Smrg dpyinfo->codes = XInitExtension (dpy, ext_name); 2041f0ac6a5Smrg else 2051f0ac6a5Smrg dpyinfo->codes = NULL; 2061f0ac6a5Smrg 2071f0ac6a5Smrg /* 2086fae4e5dSmrg * if the server has the extension, then we can initialize the 2091f0ac6a5Smrg * appropriate function vectors 2101f0ac6a5Smrg */ 2111f0ac6a5Smrg if (dpyinfo->codes) { 2126fae4e5dSmrg XESetCloseDisplay (dpy, dpyinfo->codes->extension, 2131f0ac6a5Smrg XRenderCloseDisplay); 2141f0ac6a5Smrg } else { 2151f0ac6a5Smrg /* The server doesn't have this extension. 2161f0ac6a5Smrg * Use a private Xlib-internal extension to hang the close_display 2171f0ac6a5Smrg * hook on so that the "cache" (extinfo->cur) is properly cleaned. 2181f0ac6a5Smrg * (XBUG 7955) 2191f0ac6a5Smrg */ 2201f0ac6a5Smrg XExtCodes *codes = XAddExtension(dpy); 2211f0ac6a5Smrg if (!codes) { 2221f0ac6a5Smrg XFree(dpyinfo); 2231f0ac6a5Smrg return NULL; 2241f0ac6a5Smrg } 2251f0ac6a5Smrg XESetCloseDisplay (dpy, codes->extension, XRenderCloseDisplay); 2261f0ac6a5Smrg } 2271f0ac6a5Smrg 2281f0ac6a5Smrg /* 2291f0ac6a5Smrg * now, chain it onto the list 2301f0ac6a5Smrg */ 2311f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 2321f0ac6a5Smrg dpyinfo->next = extinfo->head; 2331f0ac6a5Smrg extinfo->head = dpyinfo; 2341f0ac6a5Smrg extinfo->cur = dpyinfo; 2351f0ac6a5Smrg extinfo->ndisplays++; 2361f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2371f0ac6a5Smrg return dpyinfo; 2381f0ac6a5Smrg} 2391f0ac6a5Smrg 2401f0ac6a5Smrg 2411f0ac6a5Smrg/* 2421f0ac6a5Smrg * XRenderExtRemoveDisplay - remove the indicated display from the 2431f0ac6a5Smrg * extension object. (Replaces XextRemoveDisplay.) 2441f0ac6a5Smrg */ 2456fae4e5dSmrgstatic int 2461f0ac6a5SmrgXRenderExtRemoveDisplay (XRenderExtInfo *extinfo, Display *dpy) 2471f0ac6a5Smrg{ 2481f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo, *prev; 2491f0ac6a5Smrg 2501f0ac6a5Smrg /* 2511f0ac6a5Smrg * locate this display and its back link so that it can be removed 2521f0ac6a5Smrg */ 2531f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 2541f0ac6a5Smrg prev = NULL; 2551f0ac6a5Smrg for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 2561f0ac6a5Smrg if (dpyinfo->display == dpy) break; 2571f0ac6a5Smrg prev = dpyinfo; 2581f0ac6a5Smrg } 2591f0ac6a5Smrg if (!dpyinfo) { 2601f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2611f0ac6a5Smrg return 0; /* hmm, actually an error */ 2621f0ac6a5Smrg } 2631f0ac6a5Smrg 2641f0ac6a5Smrg /* 2651f0ac6a5Smrg * remove the display from the list; handles going to zero 2661f0ac6a5Smrg */ 2671f0ac6a5Smrg if (prev) 2681f0ac6a5Smrg prev->next = dpyinfo->next; 2691f0ac6a5Smrg else 2701f0ac6a5Smrg extinfo->head = dpyinfo->next; 2711f0ac6a5Smrg 2721f0ac6a5Smrg extinfo->ndisplays--; 2731f0ac6a5Smrg if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */ 2741f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2751f0ac6a5Smrg 2761f0ac6a5Smrg Xfree ((char *) dpyinfo); 2771f0ac6a5Smrg return 1; 2781f0ac6a5Smrg} 2791f0ac6a5Smrg 2801f0ac6a5Smrg 2811f0ac6a5Smrg 2821f0ac6a5SmrgXRenderExtDisplayInfo * 2831f0ac6a5SmrgXRenderFindDisplay (Display *dpy) 2841f0ac6a5Smrg{ 2851f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 2861f0ac6a5Smrg 2871f0ac6a5Smrg dpyinfo = XRenderExtFindDisplay (&XRenderExtensionInfo, dpy); 2881f0ac6a5Smrg if (!dpyinfo) 2896fae4e5dSmrg dpyinfo = XRenderExtAddDisplay (&XRenderExtensionInfo, dpy, 2901f0ac6a5Smrg XRenderExtensionName); 2911f0ac6a5Smrg return dpyinfo; 2921f0ac6a5Smrg} 2931f0ac6a5Smrg 2941f0ac6a5Smrgstatic int 2951f0ac6a5SmrgXRenderCloseDisplay (Display *dpy, XExtCodes *codes) 2961f0ac6a5Smrg{ 2971f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 2981f0ac6a5Smrg if (info && info->info) XFree (info->info); 2996fae4e5dSmrg 3001f0ac6a5Smrg return XRenderExtRemoveDisplay (&XRenderExtensionInfo, dpy); 3011f0ac6a5Smrg} 3026fae4e5dSmrg 3031f0ac6a5Smrg/**************************************************************************** 3041f0ac6a5Smrg * * 3051f0ac6a5Smrg * Render public interfaces * 3061f0ac6a5Smrg * * 3071f0ac6a5Smrg ****************************************************************************/ 3081f0ac6a5Smrg 3091f0ac6a5SmrgBool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep) 3101f0ac6a5Smrg{ 3111f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3121f0ac6a5Smrg 3131f0ac6a5Smrg if (RenderHasExtension(info)) { 3141f0ac6a5Smrg *event_basep = info->codes->first_event; 3151f0ac6a5Smrg *error_basep = info->codes->first_error; 3161f0ac6a5Smrg return True; 3171f0ac6a5Smrg } else { 3181f0ac6a5Smrg return False; 3191f0ac6a5Smrg } 3201f0ac6a5Smrg} 3211f0ac6a5Smrg 3221f0ac6a5Smrg 3231f0ac6a5SmrgStatus XRenderQueryVersion (Display *dpy, 3241f0ac6a5Smrg int *major_versionp, 3251f0ac6a5Smrg int *minor_versionp) 3261f0ac6a5Smrg{ 3271f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3281f0ac6a5Smrg XRenderInfo *xri; 3291f0ac6a5Smrg 3301f0ac6a5Smrg if (!RenderHasExtension (info)) 3311f0ac6a5Smrg return 0; 3321f0ac6a5Smrg 3331f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 3341f0ac6a5Smrg return 0; 3356fae4e5dSmrg 3366fae4e5dSmrg xri = info->info; 3371f0ac6a5Smrg *major_versionp = xri->major_version; 3381f0ac6a5Smrg *minor_versionp = xri->minor_version; 3391f0ac6a5Smrg return 1; 3401f0ac6a5Smrg} 3411f0ac6a5Smrg 3421f0ac6a5Smrgstatic XRenderPictFormat * 3431f0ac6a5Smrg_XRenderFindFormat (XRenderInfo *xri, PictFormat format) 3441f0ac6a5Smrg{ 3451f0ac6a5Smrg int nf; 3466fae4e5dSmrg 3471f0ac6a5Smrg for (nf = 0; nf < xri->nformat; nf++) 3481f0ac6a5Smrg if (xri->format[nf].id == format) 3491f0ac6a5Smrg return &xri->format[nf]; 350e5410a46Smrg return NULL; 3511f0ac6a5Smrg} 3521f0ac6a5Smrg 3531f0ac6a5Smrgstatic Visual * 3541f0ac6a5Smrg_XRenderFindVisual (Display *dpy, VisualID vid) 3551f0ac6a5Smrg{ 3561f0ac6a5Smrg return _XVIDtoVisual (dpy, vid); 3571f0ac6a5Smrg} 3581f0ac6a5Smrg 3591f0ac6a5Smrgtypedef struct _renderVersionState { 3601f0ac6a5Smrg unsigned long version_seq; 3611f0ac6a5Smrg Bool error; 3621f0ac6a5Smrg int major_version; 3631f0ac6a5Smrg int minor_version; 3646fae4e5dSmrg 3651f0ac6a5Smrg} _XrenderVersionState; 3661f0ac6a5Smrg 3671f0ac6a5Smrgstatic Bool 3681f0ac6a5Smrg_XRenderVersionHandler (Display *dpy, 3691f0ac6a5Smrg xReply *rep, 3701f0ac6a5Smrg char *buf, 3711f0ac6a5Smrg int len, 3721f0ac6a5Smrg XPointer data) 3731f0ac6a5Smrg{ 3741f0ac6a5Smrg xRenderQueryVersionReply replbuf; 3751f0ac6a5Smrg xRenderQueryVersionReply *repl; 3761f0ac6a5Smrg _XrenderVersionState *state = (_XrenderVersionState *) data; 3771f0ac6a5Smrg 3781f0ac6a5Smrg if (dpy->last_request_read != state->version_seq) 3791f0ac6a5Smrg return False; 3801f0ac6a5Smrg if (rep->generic.type == X_Error) 3811f0ac6a5Smrg { 3821f0ac6a5Smrg state->error = True; 3831f0ac6a5Smrg return False; 3841f0ac6a5Smrg } 3851f0ac6a5Smrg repl = (xRenderQueryVersionReply *) 3861f0ac6a5Smrg _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, 3871f0ac6a5Smrg (SIZEOF(xRenderQueryVersionReply) - SIZEOF(xReply)) >> 2, 3881f0ac6a5Smrg True); 3891f0ac6a5Smrg state->major_version = repl->majorVersion; 3901f0ac6a5Smrg state->minor_version = repl->minorVersion; 3911f0ac6a5Smrg return True; 3921f0ac6a5Smrg} 3931f0ac6a5Smrg 3941f0ac6a5SmrgStatus 3951f0ac6a5SmrgXRenderQueryFormats (Display *dpy) 3961f0ac6a5Smrg{ 3971f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3981f0ac6a5Smrg _XAsyncHandler async; 3991f0ac6a5Smrg _XrenderVersionState async_state; 4001f0ac6a5Smrg xRenderQueryVersionReq *vreq; 4011f0ac6a5Smrg xRenderQueryPictFormatsReply rep; 4021f0ac6a5Smrg xRenderQueryPictFormatsReq *req; 4031f0ac6a5Smrg XRenderInfo *xri; 4041f0ac6a5Smrg XRenderPictFormat *format; 4051f0ac6a5Smrg XRenderScreen *screen; 4061f0ac6a5Smrg XRenderDepth *depth; 4071f0ac6a5Smrg XRenderVisual *visual; 4081f0ac6a5Smrg xPictFormInfo *xFormat; 4091f0ac6a5Smrg xPictScreen *xScreen; 4101f0ac6a5Smrg xPictDepth *xDepth; 4111f0ac6a5Smrg xPictVisual *xVisual; 4121f0ac6a5Smrg CARD32 *xSubpixel; 4131f0ac6a5Smrg void *xData; 4141f0ac6a5Smrg int nf, ns, nd, nv; 415190694daSmrg unsigned long rlength; 416190694daSmrg unsigned long nbytes; 4176fae4e5dSmrg 4181f0ac6a5Smrg RenderCheckExtension (dpy, info, 0); 4191f0ac6a5Smrg LockDisplay (dpy); 4201f0ac6a5Smrg if (info->info) 4211f0ac6a5Smrg { 4221f0ac6a5Smrg UnlockDisplay (dpy); 4231f0ac6a5Smrg return 1; 4241f0ac6a5Smrg } 4251f0ac6a5Smrg GetReq (RenderQueryVersion, vreq); 4261f0ac6a5Smrg vreq->reqType = info->codes->major_opcode; 4271f0ac6a5Smrg vreq->renderReqType = X_RenderQueryVersion; 4281f0ac6a5Smrg vreq->majorVersion = RENDER_MAJOR; 4291f0ac6a5Smrg vreq->minorVersion = RENDER_MINOR; 4306fae4e5dSmrg 4311f0ac6a5Smrg async_state.version_seq = dpy->request; 4321f0ac6a5Smrg async_state.error = False; 4331f0ac6a5Smrg async.next = dpy->async_handlers; 4341f0ac6a5Smrg async.handler = _XRenderVersionHandler; 4351f0ac6a5Smrg async.data = (XPointer) &async_state; 4361f0ac6a5Smrg dpy->async_handlers = &async; 4376fae4e5dSmrg 4381f0ac6a5Smrg GetReq (RenderQueryPictFormats, req); 4391f0ac6a5Smrg req->reqType = info->codes->major_opcode; 4401f0ac6a5Smrg req->renderReqType = X_RenderQueryPictFormats; 4416fae4e5dSmrg 4426fae4e5dSmrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 4431f0ac6a5Smrg { 4441f0ac6a5Smrg DeqAsyncHandler (dpy, &async); 4451f0ac6a5Smrg UnlockDisplay (dpy); 4461f0ac6a5Smrg SyncHandle (); 4471f0ac6a5Smrg return 0; 4481f0ac6a5Smrg } 4491f0ac6a5Smrg DeqAsyncHandler (dpy, &async); 4501f0ac6a5Smrg if (async_state.error) 4511f0ac6a5Smrg { 4521f0ac6a5Smrg UnlockDisplay(dpy); 4531f0ac6a5Smrg SyncHandle(); 4541f0ac6a5Smrg return 0; 4551f0ac6a5Smrg } 4561f0ac6a5Smrg /* 4571f0ac6a5Smrg * Check for the lack of sub-pixel data 4581f0ac6a5Smrg */ 4591f0ac6a5Smrg if (async_state.major_version == 0 && async_state.minor_version < 6) 4601f0ac6a5Smrg rep.numSubpixel = 0; 4616fae4e5dSmrg 462190694daSmrg if ((rep.numFormats < ((INT_MAX / 4) / sizeof (XRenderPictFormat))) && 463190694daSmrg (rep.numScreens < ((INT_MAX / 4) / sizeof (XRenderScreen))) && 464190694daSmrg (rep.numDepths < ((INT_MAX / 4) / sizeof (XRenderDepth))) && 465190694daSmrg (rep.numVisuals < ((INT_MAX / 4) / sizeof (XRenderVisual))) && 466190694daSmrg (rep.numSubpixel < ((INT_MAX / 4) / 4)) && 467190694daSmrg (rep.length < (INT_MAX >> 2)) ) { 468190694daSmrg xri = Xmalloc (sizeof (XRenderInfo) + 469190694daSmrg (rep.numFormats * sizeof (XRenderPictFormat)) + 470190694daSmrg (rep.numScreens * sizeof (XRenderScreen)) + 471190694daSmrg (rep.numDepths * sizeof (XRenderDepth)) + 472190694daSmrg (rep.numVisuals * sizeof (XRenderVisual))); 473190694daSmrg rlength = ((rep.numFormats * sizeof (xPictFormInfo)) + 474190694daSmrg (rep.numScreens * sizeof (xPictScreen)) + 475190694daSmrg (rep.numDepths * sizeof (xPictDepth)) + 476190694daSmrg (rep.numVisuals * sizeof (xPictVisual)) + 477190694daSmrg (rep.numSubpixel * 4)); 478190694daSmrg xData = Xmalloc (rlength); 479190694daSmrg nbytes = (unsigned long) rep.length << 2; 480190694daSmrg } else { 481190694daSmrg xri = NULL; 482190694daSmrg xData = NULL; 483190694daSmrg rlength = nbytes = 0; 484190694daSmrg } 4856fae4e5dSmrg 4861f0ac6a5Smrg if (!xri || !xData || nbytes < rlength) 4871f0ac6a5Smrg { 4881f0ac6a5Smrg if (xri) Xfree (xri); 4891f0ac6a5Smrg if (xData) Xfree (xData); 4901f0ac6a5Smrg _XEatData (dpy, nbytes); 4911f0ac6a5Smrg UnlockDisplay (dpy); 4921f0ac6a5Smrg SyncHandle (); 4931f0ac6a5Smrg return 0; 4941f0ac6a5Smrg } 4951f0ac6a5Smrg xri->major_version = async_state.major_version; 4961f0ac6a5Smrg xri->minor_version = async_state.minor_version; 4971f0ac6a5Smrg xri->format = (XRenderPictFormat *) (xri + 1); 4981f0ac6a5Smrg xri->nformat = rep.numFormats; 4991f0ac6a5Smrg xri->screen = (XRenderScreen *) (xri->format + rep.numFormats); 5001f0ac6a5Smrg xri->nscreen = rep.numScreens; 5011f0ac6a5Smrg xri->depth = (XRenderDepth *) (xri->screen + rep.numScreens); 5021f0ac6a5Smrg xri->ndepth = rep.numDepths; 5031f0ac6a5Smrg xri->visual = (XRenderVisual *) (xri->depth + rep.numDepths); 5041f0ac6a5Smrg xri->nvisual = rep.numVisuals; 5051f0ac6a5Smrg _XRead (dpy, (char *) xData, rlength); 5061f0ac6a5Smrg format = xri->format; 5071f0ac6a5Smrg xFormat = (xPictFormInfo *) xData; 5081f0ac6a5Smrg for (nf = 0; nf < rep.numFormats; nf++) 5091f0ac6a5Smrg { 5101f0ac6a5Smrg format->id = xFormat->id; 5111f0ac6a5Smrg format->type = xFormat->type; 5121f0ac6a5Smrg format->depth = xFormat->depth; 5131f0ac6a5Smrg format->direct.red = xFormat->direct.red; 5141f0ac6a5Smrg format->direct.redMask = xFormat->direct.redMask; 5151f0ac6a5Smrg format->direct.green = xFormat->direct.green; 5161f0ac6a5Smrg format->direct.greenMask = xFormat->direct.greenMask; 5171f0ac6a5Smrg format->direct.blue = xFormat->direct.blue; 5181f0ac6a5Smrg format->direct.blueMask = xFormat->direct.blueMask; 5191f0ac6a5Smrg format->direct.alpha = xFormat->direct.alpha; 5201f0ac6a5Smrg format->direct.alphaMask = xFormat->direct.alphaMask; 5211f0ac6a5Smrg format->colormap = xFormat->colormap; 5221f0ac6a5Smrg format++; 5231f0ac6a5Smrg xFormat++; 5241f0ac6a5Smrg } 5251f0ac6a5Smrg xScreen = (xPictScreen *) xFormat; 5261f0ac6a5Smrg screen = xri->screen; 5271f0ac6a5Smrg depth = xri->depth; 5281f0ac6a5Smrg visual = xri->visual; 5291f0ac6a5Smrg for (ns = 0; ns < xri->nscreen; ns++) 5301f0ac6a5Smrg { 5311f0ac6a5Smrg screen->depths = depth; 5321f0ac6a5Smrg screen->ndepths = xScreen->nDepth; 5331f0ac6a5Smrg screen->fallback = _XRenderFindFormat (xri, xScreen->fallback); 5341f0ac6a5Smrg screen->subpixel = SubPixelUnknown; 5351f0ac6a5Smrg xDepth = (xPictDepth *) (xScreen + 1); 5361f0ac6a5Smrg for (nd = 0; nd < screen->ndepths; nd++) 5371f0ac6a5Smrg { 5381f0ac6a5Smrg depth->depth = xDepth->depth; 5391f0ac6a5Smrg depth->nvisuals = xDepth->nPictVisuals; 5401f0ac6a5Smrg depth->visuals = visual; 5411f0ac6a5Smrg xVisual = (xPictVisual *) (xDepth + 1); 5421f0ac6a5Smrg for (nv = 0; nv < depth->nvisuals; nv++) 5431f0ac6a5Smrg { 5441f0ac6a5Smrg visual->visual = _XRenderFindVisual (dpy, xVisual->visual); 5451f0ac6a5Smrg visual->format = _XRenderFindFormat (xri, xVisual->format); 5461f0ac6a5Smrg visual++; 5471f0ac6a5Smrg xVisual++; 5481f0ac6a5Smrg } 5491f0ac6a5Smrg depth++; 5501f0ac6a5Smrg xDepth = (xPictDepth *) xVisual; 5511f0ac6a5Smrg } 5521f0ac6a5Smrg screen++; 5536fae4e5dSmrg xScreen = (xPictScreen *) xDepth; 5541f0ac6a5Smrg } 5551f0ac6a5Smrg xSubpixel = (CARD32 *) xScreen; 5561f0ac6a5Smrg screen = xri->screen; 5571f0ac6a5Smrg for (ns = 0; ns < rep.numSubpixel; ns++) 5581f0ac6a5Smrg { 5591f0ac6a5Smrg screen->subpixel = *xSubpixel; 5601f0ac6a5Smrg xSubpixel++; 5611f0ac6a5Smrg screen++; 5621f0ac6a5Smrg } 5631f0ac6a5Smrg info->info = xri; 5641f0ac6a5Smrg /* 5651f0ac6a5Smrg * Skip any extra data 5661f0ac6a5Smrg */ 5671f0ac6a5Smrg if (nbytes > rlength) 5681f0ac6a5Smrg _XEatData (dpy, (unsigned long) (nbytes - rlength)); 5696fae4e5dSmrg 5701f0ac6a5Smrg UnlockDisplay (dpy); 5711f0ac6a5Smrg SyncHandle (); 5721f0ac6a5Smrg Xfree (xData); 5731f0ac6a5Smrg return 1; 5741f0ac6a5Smrg} 5751f0ac6a5Smrg 5761f0ac6a5Smrgint 5771f0ac6a5SmrgXRenderQuerySubpixelOrder (Display *dpy, int screen) 5781f0ac6a5Smrg{ 5791f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 5801f0ac6a5Smrg XRenderInfo *xri; 5811f0ac6a5Smrg 5821f0ac6a5Smrg if (!RenderHasExtension (info)) 5831f0ac6a5Smrg return SubPixelUnknown; 5841f0ac6a5Smrg 5851f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 5861f0ac6a5Smrg return SubPixelUnknown; 5871f0ac6a5Smrg 5881f0ac6a5Smrg xri = info->info; 5891f0ac6a5Smrg return xri->screen[screen].subpixel; 5901f0ac6a5Smrg} 5911f0ac6a5Smrg 5921f0ac6a5SmrgBool 5931f0ac6a5SmrgXRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel) 5941f0ac6a5Smrg{ 5951f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 5961f0ac6a5Smrg XRenderInfo *xri; 5971f0ac6a5Smrg 5981f0ac6a5Smrg if (!RenderHasExtension (info)) 5991f0ac6a5Smrg return False; 6001f0ac6a5Smrg 6011f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 6021f0ac6a5Smrg return False; 6031f0ac6a5Smrg 6041f0ac6a5Smrg xri = info->info; 6051f0ac6a5Smrg xri->screen[screen].subpixel = subpixel; 6061f0ac6a5Smrg return True; 6071f0ac6a5Smrg} 6081f0ac6a5Smrg 6091f0ac6a5SmrgXRenderPictFormat * 6101f0ac6a5SmrgXRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual) 6111f0ac6a5Smrg{ 6121f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6131f0ac6a5Smrg int nv; 6141f0ac6a5Smrg XRenderInfo *xri; 6151f0ac6a5Smrg XRenderVisual *xrv; 616e5410a46Smrg 617e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 6181f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 619e5410a46Smrg return NULL; 6201f0ac6a5Smrg xri = info->info; 6211f0ac6a5Smrg for (nv = 0, xrv = xri->visual; nv < xri->nvisual; nv++, xrv++) 6221f0ac6a5Smrg if (xrv->visual == visual) 6231f0ac6a5Smrg return xrv->format; 624e5410a46Smrg return NULL; 6251f0ac6a5Smrg} 6261f0ac6a5Smrg 6271f0ac6a5SmrgXRenderPictFormat * 6281f0ac6a5SmrgXRenderFindFormat (Display *dpy, 6291f0ac6a5Smrg unsigned long mask, 6301f0ac6a5Smrg _Xconst XRenderPictFormat *template, 6311f0ac6a5Smrg int count) 6321f0ac6a5Smrg{ 6331f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6341f0ac6a5Smrg int nf; 6351f0ac6a5Smrg XRenderInfo *xri; 636e5410a46Smrg 637e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 6381f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 639e5410a46Smrg return NULL; 6401f0ac6a5Smrg xri = info->info; 6411f0ac6a5Smrg for (nf = 0; nf < xri->nformat; nf++) 6421f0ac6a5Smrg { 6431f0ac6a5Smrg if (mask & PictFormatID) 6441f0ac6a5Smrg if (template->id != xri->format[nf].id) 6451f0ac6a5Smrg continue; 6461f0ac6a5Smrg if (mask & PictFormatType) 6471f0ac6a5Smrg if (template->type != xri->format[nf].type) 6481f0ac6a5Smrg continue; 6491f0ac6a5Smrg if (mask & PictFormatDepth) 6501f0ac6a5Smrg if (template->depth != xri->format[nf].depth) 6511f0ac6a5Smrg continue; 6521f0ac6a5Smrg if (mask & PictFormatRed) 6531f0ac6a5Smrg if (template->direct.red != xri->format[nf].direct.red) 6541f0ac6a5Smrg continue; 6551f0ac6a5Smrg if (mask & PictFormatRedMask) 6561f0ac6a5Smrg if (template->direct.redMask != xri->format[nf].direct.redMask) 6571f0ac6a5Smrg continue; 6581f0ac6a5Smrg if (mask & PictFormatGreen) 6591f0ac6a5Smrg if (template->direct.green != xri->format[nf].direct.green) 6601f0ac6a5Smrg continue; 6611f0ac6a5Smrg if (mask & PictFormatGreenMask) 6621f0ac6a5Smrg if (template->direct.greenMask != xri->format[nf].direct.greenMask) 6631f0ac6a5Smrg continue; 6641f0ac6a5Smrg if (mask & PictFormatBlue) 6651f0ac6a5Smrg if (template->direct.blue != xri->format[nf].direct.blue) 6661f0ac6a5Smrg continue; 6671f0ac6a5Smrg if (mask & PictFormatBlueMask) 6681f0ac6a5Smrg if (template->direct.blueMask != xri->format[nf].direct.blueMask) 6691f0ac6a5Smrg continue; 6701f0ac6a5Smrg if (mask & PictFormatAlpha) 6711f0ac6a5Smrg if (template->direct.alpha != xri->format[nf].direct.alpha) 6721f0ac6a5Smrg continue; 6731f0ac6a5Smrg if (mask & PictFormatAlphaMask) 6741f0ac6a5Smrg if (template->direct.alphaMask != xri->format[nf].direct.alphaMask) 6751f0ac6a5Smrg continue; 6761f0ac6a5Smrg if (mask & PictFormatColormap) 6771f0ac6a5Smrg if (template->colormap != xri->format[nf].colormap) 6781f0ac6a5Smrg continue; 6791f0ac6a5Smrg if (count-- == 0) 6801f0ac6a5Smrg return &xri->format[nf]; 6811f0ac6a5Smrg } 682e5410a46Smrg return NULL; 6831f0ac6a5Smrg} 6841f0ac6a5Smrg 6851f0ac6a5SmrgXRenderPictFormat * 6861f0ac6a5SmrgXRenderFindStandardFormat (Display *dpy, 6871f0ac6a5Smrg int format) 6881f0ac6a5Smrg{ 6891f0ac6a5Smrg static struct { 6901f0ac6a5Smrg XRenderPictFormat templ; 6911f0ac6a5Smrg unsigned long mask; 6921f0ac6a5Smrg } standardFormats[PictStandardNUM] = { 6931f0ac6a5Smrg /* PictStandardARGB32 */ 6941f0ac6a5Smrg { 6951f0ac6a5Smrg { 6961f0ac6a5Smrg 0, /* id */ 6971f0ac6a5Smrg PictTypeDirect, /* type */ 6981f0ac6a5Smrg 32, /* depth */ 6991f0ac6a5Smrg { /* direct */ 7001f0ac6a5Smrg 16, /* direct.red */ 7011f0ac6a5Smrg 0xff, /* direct.redMask */ 7021f0ac6a5Smrg 8, /* direct.green */ 7031f0ac6a5Smrg 0xff, /* direct.greenMask */ 7041f0ac6a5Smrg 0, /* direct.blue */ 7051f0ac6a5Smrg 0xff, /* direct.blueMask */ 7061f0ac6a5Smrg 24, /* direct.alpha */ 7071f0ac6a5Smrg 0xff, /* direct.alphaMask */ 7081f0ac6a5Smrg }, 7091f0ac6a5Smrg 0, /* colormap */ 7101f0ac6a5Smrg }, 7116fae4e5dSmrg PictFormatType | 7121f0ac6a5Smrg PictFormatDepth | 7131f0ac6a5Smrg PictFormatRed | 7141f0ac6a5Smrg PictFormatRedMask | 7151f0ac6a5Smrg PictFormatGreen | 7161f0ac6a5Smrg PictFormatGreenMask | 7171f0ac6a5Smrg PictFormatBlue | 7181f0ac6a5Smrg PictFormatBlueMask | 7191f0ac6a5Smrg PictFormatAlpha | 7201f0ac6a5Smrg PictFormatAlphaMask, 7211f0ac6a5Smrg }, 7221f0ac6a5Smrg /* PictStandardRGB24 */ 7231f0ac6a5Smrg { 7241f0ac6a5Smrg { 7251f0ac6a5Smrg 0, /* id */ 7261f0ac6a5Smrg PictTypeDirect, /* type */ 7271f0ac6a5Smrg 24, /* depth */ 7281f0ac6a5Smrg { /* direct */ 7291f0ac6a5Smrg 16, /* direct.red */ 7301f0ac6a5Smrg 0xff, /* direct.redMask */ 7311f0ac6a5Smrg 8, /* direct.green */ 7321f0ac6a5Smrg 0xff, /* direct.greenMask */ 7331f0ac6a5Smrg 0, /* direct.blue */ 7341f0ac6a5Smrg 0xff, /* direct.blueMask */ 7351f0ac6a5Smrg 0, /* direct.alpha */ 7361f0ac6a5Smrg 0x00, /* direct.alphaMask */ 7371f0ac6a5Smrg }, 7381f0ac6a5Smrg 0, /* colormap */ 7391f0ac6a5Smrg }, 7406fae4e5dSmrg PictFormatType | 7411f0ac6a5Smrg PictFormatDepth | 7421f0ac6a5Smrg PictFormatRed | 7431f0ac6a5Smrg PictFormatRedMask | 7441f0ac6a5Smrg PictFormatGreen | 7451f0ac6a5Smrg PictFormatGreenMask | 7461f0ac6a5Smrg PictFormatBlue | 7471f0ac6a5Smrg PictFormatBlueMask | 7481f0ac6a5Smrg PictFormatAlphaMask, 7491f0ac6a5Smrg }, 7501f0ac6a5Smrg /* PictStandardA8 */ 7511f0ac6a5Smrg { 7521f0ac6a5Smrg { 7531f0ac6a5Smrg 0, /* id */ 7541f0ac6a5Smrg PictTypeDirect, /* type */ 7551f0ac6a5Smrg 8, /* depth */ 7561f0ac6a5Smrg { /* direct */ 7571f0ac6a5Smrg 0, /* direct.red */ 7581f0ac6a5Smrg 0x00, /* direct.redMask */ 7591f0ac6a5Smrg 0, /* direct.green */ 7601f0ac6a5Smrg 0x00, /* direct.greenMask */ 7611f0ac6a5Smrg 0, /* direct.blue */ 7621f0ac6a5Smrg 0x00, /* direct.blueMask */ 7631f0ac6a5Smrg 0, /* direct.alpha */ 7641f0ac6a5Smrg 0xff, /* direct.alphaMask */ 7651f0ac6a5Smrg }, 7661f0ac6a5Smrg 0, /* colormap */ 7671f0ac6a5Smrg }, 7686fae4e5dSmrg PictFormatType | 7691f0ac6a5Smrg PictFormatDepth | 7701f0ac6a5Smrg PictFormatRedMask | 7711f0ac6a5Smrg PictFormatGreenMask | 7721f0ac6a5Smrg PictFormatBlueMask | 7731f0ac6a5Smrg PictFormatAlpha | 7741f0ac6a5Smrg PictFormatAlphaMask, 7751f0ac6a5Smrg }, 7761f0ac6a5Smrg /* PictStandardA4 */ 7771f0ac6a5Smrg { 7781f0ac6a5Smrg { 7791f0ac6a5Smrg 0, /* id */ 7801f0ac6a5Smrg PictTypeDirect, /* type */ 7811f0ac6a5Smrg 4, /* depth */ 7821f0ac6a5Smrg { /* direct */ 7831f0ac6a5Smrg 0, /* direct.red */ 7841f0ac6a5Smrg 0x00, /* direct.redMask */ 7851f0ac6a5Smrg 0, /* direct.green */ 7861f0ac6a5Smrg 0x00, /* direct.greenMask */ 7871f0ac6a5Smrg 0, /* direct.blue */ 7881f0ac6a5Smrg 0x00, /* direct.blueMask */ 7891f0ac6a5Smrg 0, /* direct.alpha */ 7901f0ac6a5Smrg 0x0f, /* direct.alphaMask */ 7911f0ac6a5Smrg }, 7921f0ac6a5Smrg 0, /* colormap */ 7931f0ac6a5Smrg }, 7946fae4e5dSmrg PictFormatType | 7951f0ac6a5Smrg PictFormatDepth | 7961f0ac6a5Smrg PictFormatRedMask | 7971f0ac6a5Smrg PictFormatGreenMask | 7981f0ac6a5Smrg PictFormatBlueMask | 7991f0ac6a5Smrg PictFormatAlpha | 8001f0ac6a5Smrg PictFormatAlphaMask, 8011f0ac6a5Smrg }, 8021f0ac6a5Smrg /* PictStandardA1 */ 8031f0ac6a5Smrg { 8041f0ac6a5Smrg { 8051f0ac6a5Smrg 0, /* id */ 8061f0ac6a5Smrg PictTypeDirect, /* type */ 8071f0ac6a5Smrg 1, /* depth */ 8081f0ac6a5Smrg { /* direct */ 8091f0ac6a5Smrg 0, /* direct.red */ 8101f0ac6a5Smrg 0x00, /* direct.redMask */ 8111f0ac6a5Smrg 0, /* direct.green */ 8121f0ac6a5Smrg 0x00, /* direct.greenMask */ 8131f0ac6a5Smrg 0, /* direct.blue */ 8141f0ac6a5Smrg 0x00, /* direct.blueMask */ 8151f0ac6a5Smrg 0, /* direct.alpha */ 8161f0ac6a5Smrg 0x01, /* direct.alphaMask */ 8171f0ac6a5Smrg }, 8181f0ac6a5Smrg 0, /* colormap */ 8191f0ac6a5Smrg }, 8206fae4e5dSmrg PictFormatType | 8211f0ac6a5Smrg PictFormatDepth | 8221f0ac6a5Smrg PictFormatRedMask | 8231f0ac6a5Smrg PictFormatGreenMask | 8241f0ac6a5Smrg PictFormatBlueMask | 8251f0ac6a5Smrg PictFormatAlpha | 8261f0ac6a5Smrg PictFormatAlphaMask, 8271f0ac6a5Smrg }, 8281f0ac6a5Smrg }; 8291f0ac6a5Smrg 8301f0ac6a5Smrg if (0 <= format && format < PictStandardNUM) 8316fae4e5dSmrg return XRenderFindFormat (dpy, 8321f0ac6a5Smrg standardFormats[format].mask, 8331f0ac6a5Smrg &standardFormats[format].templ, 8341f0ac6a5Smrg 0); 835e5410a46Smrg return NULL; 8361f0ac6a5Smrg} 8371f0ac6a5Smrg 8381f0ac6a5SmrgXIndexValue * 8391f0ac6a5SmrgXRenderQueryPictIndexValues(Display *dpy, 8401f0ac6a5Smrg _Xconst XRenderPictFormat *format, 8411f0ac6a5Smrg int *num) 8421f0ac6a5Smrg{ 8431f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 8441f0ac6a5Smrg xRenderQueryPictIndexValuesReq *req; 8451f0ac6a5Smrg xRenderQueryPictIndexValuesReply rep; 8461f0ac6a5Smrg XIndexValue *values; 847190694daSmrg unsigned int nbytes, nread, rlength, i; 8481f0ac6a5Smrg 849e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 8501f0ac6a5Smrg 8511f0ac6a5Smrg LockDisplay (dpy); 8521f0ac6a5Smrg GetReq (RenderQueryPictIndexValues, req); 8531f0ac6a5Smrg req->reqType = info->codes->major_opcode; 8541f0ac6a5Smrg req->renderReqType = X_RenderQueryPictIndexValues; 8551f0ac6a5Smrg req->format = format->id; 8561f0ac6a5Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 8571f0ac6a5Smrg { 8581f0ac6a5Smrg UnlockDisplay (dpy); 8591f0ac6a5Smrg SyncHandle (); 860e5410a46Smrg return NULL; 8611f0ac6a5Smrg } 8621f0ac6a5Smrg 863190694daSmrg if ((rep.length < (INT_MAX >> 2)) && 864190694daSmrg (rep.numIndexValues < (INT_MAX / sizeof (XIndexValue)))) { 865190694daSmrg /* request data length */ 866190694daSmrg nbytes = rep.length << 2; 867190694daSmrg /* bytes of actual data in the request */ 868190694daSmrg nread = rep.numIndexValues * SIZEOF (xIndexValue); 869190694daSmrg /* size of array returned to application */ 870190694daSmrg rlength = rep.numIndexValues * sizeof (XIndexValue); 871190694daSmrg 872190694daSmrg /* allocate returned data */ 873190694daSmrg values = Xmalloc (rlength); 874190694daSmrg } else { 875190694daSmrg nbytes = nread = rlength = 0; 876190694daSmrg values = NULL; 877190694daSmrg } 8781f0ac6a5Smrg 8791f0ac6a5Smrg if (!values) 8801f0ac6a5Smrg { 8811f0ac6a5Smrg _XEatData (dpy, nbytes); 8821f0ac6a5Smrg UnlockDisplay (dpy); 8831f0ac6a5Smrg SyncHandle (); 884e5410a46Smrg return NULL; 8851f0ac6a5Smrg } 8861f0ac6a5Smrg 8871f0ac6a5Smrg /* read the values one at a time and convert */ 8881f0ac6a5Smrg *num = rep.numIndexValues; 8891f0ac6a5Smrg for(i = 0; i < rep.numIndexValues; i++) 8901f0ac6a5Smrg { 8911f0ac6a5Smrg xIndexValue value; 8926fae4e5dSmrg 8931f0ac6a5Smrg _XRead (dpy, (char *) &value, SIZEOF (xIndexValue)); 8941f0ac6a5Smrg values[i].pixel = value.pixel; 8951f0ac6a5Smrg values[i].red = value.red; 8961f0ac6a5Smrg values[i].green = value.green; 8971f0ac6a5Smrg values[i].blue = value.blue; 8981f0ac6a5Smrg values[i].alpha = value.alpha; 8991f0ac6a5Smrg } 9001f0ac6a5Smrg /* skip any padding */ 9011f0ac6a5Smrg if(nbytes > nread) 9021f0ac6a5Smrg { 9031f0ac6a5Smrg _XEatData (dpy, (unsigned long) (nbytes - nread)); 9041f0ac6a5Smrg } 9051f0ac6a5Smrg UnlockDisplay (dpy); 9061f0ac6a5Smrg SyncHandle (); 9071f0ac6a5Smrg return values; 9081f0ac6a5Smrg} 909