Xrender.c revision e5410a46
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 191f0ac6a5Smrg * 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" 291f0ac6a5Smrg 301f0ac6a5SmrgXRenderExtInfo XRenderExtensionInfo; 311f0ac6a5Smrgchar XRenderExtensionName[] = RENDER_NAME; 321f0ac6a5Smrg 331f0ac6a5Smrgstatic int XRenderCloseDisplay (Display *dpy, XExtCodes *codes); 341f0ac6a5Smrg 351f0ac6a5Smrg/* 361f0ac6a5Smrg * XRenderExtFindDisplay - look for a display in this extension; keeps a 371f0ac6a5Smrg * cache of the most-recently used for efficiency. (Replaces 381f0ac6a5Smrg * XextFindDisplay.) 391f0ac6a5Smrg */ 401f0ac6a5Smrgstatic XRenderExtDisplayInfo * 411f0ac6a5SmrgXRenderExtFindDisplay (XRenderExtInfo *extinfo, 421f0ac6a5Smrg Display *dpy) 431f0ac6a5Smrg{ 441f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 451f0ac6a5Smrg 461f0ac6a5Smrg /* 471f0ac6a5Smrg * see if this was the most recently accessed display 481f0ac6a5Smrg */ 491f0ac6a5Smrg if ((dpyinfo = extinfo->cur) && dpyinfo->display == dpy) 501f0ac6a5Smrg return dpyinfo; 511f0ac6a5Smrg 521f0ac6a5Smrg /* 531f0ac6a5Smrg * look for display in list 541f0ac6a5Smrg */ 551f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 561f0ac6a5Smrg for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 571f0ac6a5Smrg if (dpyinfo->display == dpy) { 581f0ac6a5Smrg extinfo->cur = dpyinfo; /* cache most recently used */ 591f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 601f0ac6a5Smrg return dpyinfo; 611f0ac6a5Smrg } 621f0ac6a5Smrg } 631f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 641f0ac6a5Smrg 651f0ac6a5Smrg return NULL; 661f0ac6a5Smrg} 671f0ac6a5Smrg 681f0ac6a5Smrg/* 691f0ac6a5Smrg * If the server is missing support for any of the required depths on 701f0ac6a5Smrg * any screen, tell the application that Render is not present. 711f0ac6a5Smrg */ 721f0ac6a5Smrg 731f0ac6a5Smrg#define DEPTH_MASK(d) (1 << ((d) - 1)) 741f0ac6a5Smrg 751f0ac6a5Smrg/* 761f0ac6a5Smrg * Render requires support for depth 1, 4, 8, 24 and 32 pixmaps 771f0ac6a5Smrg */ 781f0ac6a5Smrg 791f0ac6a5Smrg#define REQUIRED_DEPTHS (DEPTH_MASK(1) | \ 801f0ac6a5Smrg DEPTH_MASK(4) | \ 811f0ac6a5Smrg DEPTH_MASK(8) | \ 821f0ac6a5Smrg DEPTH_MASK(24) | \ 831f0ac6a5Smrg DEPTH_MASK(32)) 841f0ac6a5Smrg 851f0ac6a5Smrgtypedef struct _DepthCheckRec { 861f0ac6a5Smrg struct _DepthCheckRec *next; 871f0ac6a5Smrg Display *dpy; 881f0ac6a5Smrg CARD32 missing; 891f0ac6a5Smrg unsigned long serial; 901f0ac6a5Smrg} DepthCheckRec, *DepthCheckPtr; 911f0ac6a5Smrg 921f0ac6a5Smrgstatic DepthCheckPtr depthChecks; 931f0ac6a5Smrg 941f0ac6a5Smrgstatic int 951f0ac6a5SmrgXRenderDepthCheckErrorHandler (Display *dpy, XErrorEvent *evt) 961f0ac6a5Smrg{ 971f0ac6a5Smrg if (evt->request_code == X_CreatePixmap && evt->error_code == BadValue) 981f0ac6a5Smrg { 991f0ac6a5Smrg DepthCheckPtr d; 1001f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1011f0ac6a5Smrg for (d = depthChecks; d; d = d->next) 1021f0ac6a5Smrg if (d->dpy == dpy) 1031f0ac6a5Smrg { 1041f0ac6a5Smrg if ((long) (evt->serial - d->serial) >= 0) 1051f0ac6a5Smrg d->missing |= DEPTH_MASK(evt->resourceid); 1061f0ac6a5Smrg break; 1071f0ac6a5Smrg } 1081f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1091f0ac6a5Smrg } 1101f0ac6a5Smrg return 0; 1111f0ac6a5Smrg} 1121f0ac6a5Smrg 1131f0ac6a5Smrgstatic Bool 1141f0ac6a5SmrgXRenderHasDepths (Display *dpy) 1151f0ac6a5Smrg{ 1161f0ac6a5Smrg int s; 1171f0ac6a5Smrg 1181f0ac6a5Smrg for (s = 0; s < ScreenCount (dpy); s++) 1191f0ac6a5Smrg { 1201f0ac6a5Smrg CARD32 depths = 0; 1211f0ac6a5Smrg CARD32 missing; 1221f0ac6a5Smrg Screen *scr = ScreenOfDisplay (dpy, s); 1231f0ac6a5Smrg int d; 1241f0ac6a5Smrg 1251f0ac6a5Smrg for (d = 0; d < scr->ndepths; d++) 1261f0ac6a5Smrg depths |= DEPTH_MASK(scr->depths[d].depth); 1271f0ac6a5Smrg missing = ~depths & REQUIRED_DEPTHS; 1281f0ac6a5Smrg if (missing) 1291f0ac6a5Smrg { 1301f0ac6a5Smrg DepthCheckRec dc, **dp; 1311f0ac6a5Smrg XErrorHandler previousHandler; 1321f0ac6a5Smrg 1331f0ac6a5Smrg /* 1341f0ac6a5Smrg * Ok, this is ugly. It should be sufficient at this 1351f0ac6a5Smrg * point to just return False, but Xinerama is broken at 1361f0ac6a5Smrg * this point and only advertises depths which have an 1371f0ac6a5Smrg * associated visual. Of course, the other depths still 1381f0ac6a5Smrg * work, but the only way to find out is to try them. 1391f0ac6a5Smrg */ 1401f0ac6a5Smrg dc.dpy = dpy; 1411f0ac6a5Smrg dc.missing = 0; 1421f0ac6a5Smrg dc.serial = XNextRequest (dpy); 1431f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1441f0ac6a5Smrg dc.next = depthChecks; 1451f0ac6a5Smrg depthChecks = &dc; 1461f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1471f0ac6a5Smrg /* 1481f0ac6a5Smrg * I suspect this is not really thread safe, but Xlib doesn't 1491f0ac6a5Smrg * provide a lot of options here 1501f0ac6a5Smrg */ 1511f0ac6a5Smrg previousHandler = XSetErrorHandler (XRenderDepthCheckErrorHandler); 1521f0ac6a5Smrg /* 1531f0ac6a5Smrg * Try each missing depth and see if pixmap creation succeeds 1541f0ac6a5Smrg */ 1551f0ac6a5Smrg for (d = 1; d <= 32; d++) 1561f0ac6a5Smrg /* don't check depth 1 == Xcursor recurses... */ 1571f0ac6a5Smrg if ((missing & DEPTH_MASK(d)) && d != 1) 1581f0ac6a5Smrg { 1591f0ac6a5Smrg Pixmap p; 1601f0ac6a5Smrg p = XCreatePixmap (dpy, RootWindow (dpy, s), 1, 1, d); 1611f0ac6a5Smrg XFreePixmap (dpy, p); 1621f0ac6a5Smrg } 1631f0ac6a5Smrg XSync (dpy, False); 1641f0ac6a5Smrg XSetErrorHandler (previousHandler); 1651f0ac6a5Smrg /* 1661f0ac6a5Smrg * Unhook from the list of depth check records 1671f0ac6a5Smrg */ 1681f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 1691f0ac6a5Smrg for (dp = &depthChecks; *dp; dp = &(*dp)->next) 1701f0ac6a5Smrg { 1711f0ac6a5Smrg if (*dp == &dc) 1721f0ac6a5Smrg { 1731f0ac6a5Smrg *dp = dc.next; 1741f0ac6a5Smrg break; 1751f0ac6a5Smrg } 1761f0ac6a5Smrg } 1771f0ac6a5Smrg _XUnlockMutex (_Xglobal_lock); 1781f0ac6a5Smrg if (dc.missing) 1791f0ac6a5Smrg return False; 1801f0ac6a5Smrg } 1811f0ac6a5Smrg } 1821f0ac6a5Smrg return True; 1831f0ac6a5Smrg} 1841f0ac6a5Smrg 1851f0ac6a5Smrg/* 1861f0ac6a5Smrg * XRenderExtAddDisplay - add a display to this extension. (Replaces 1871f0ac6a5Smrg * XextAddDisplay) 1881f0ac6a5Smrg */ 1891f0ac6a5Smrgstatic XRenderExtDisplayInfo * 1901f0ac6a5SmrgXRenderExtAddDisplay (XRenderExtInfo *extinfo, 1911f0ac6a5Smrg Display *dpy, 1921f0ac6a5Smrg char *ext_name) 1931f0ac6a5Smrg{ 1941f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 1951f0ac6a5Smrg 1961f0ac6a5Smrg dpyinfo = (XRenderExtDisplayInfo *) Xmalloc (sizeof (XRenderExtDisplayInfo)); 1971f0ac6a5Smrg if (!dpyinfo) return NULL; 1981f0ac6a5Smrg dpyinfo->display = dpy; 1991f0ac6a5Smrg dpyinfo->info = NULL; 2001f0ac6a5Smrg 2011f0ac6a5Smrg if (XRenderHasDepths (dpy)) 2021f0ac6a5Smrg dpyinfo->codes = XInitExtension (dpy, ext_name); 2031f0ac6a5Smrg else 2041f0ac6a5Smrg dpyinfo->codes = NULL; 2051f0ac6a5Smrg 2061f0ac6a5Smrg /* 2071f0ac6a5Smrg * if the server has the extension, then we can initialize the 2081f0ac6a5Smrg * appropriate function vectors 2091f0ac6a5Smrg */ 2101f0ac6a5Smrg if (dpyinfo->codes) { 2111f0ac6a5Smrg XESetCloseDisplay (dpy, dpyinfo->codes->extension, 2121f0ac6a5Smrg XRenderCloseDisplay); 2131f0ac6a5Smrg } else { 2141f0ac6a5Smrg /* The server doesn't have this extension. 2151f0ac6a5Smrg * Use a private Xlib-internal extension to hang the close_display 2161f0ac6a5Smrg * hook on so that the "cache" (extinfo->cur) is properly cleaned. 2171f0ac6a5Smrg * (XBUG 7955) 2181f0ac6a5Smrg */ 2191f0ac6a5Smrg XExtCodes *codes = XAddExtension(dpy); 2201f0ac6a5Smrg if (!codes) { 2211f0ac6a5Smrg XFree(dpyinfo); 2221f0ac6a5Smrg return NULL; 2231f0ac6a5Smrg } 2241f0ac6a5Smrg XESetCloseDisplay (dpy, codes->extension, XRenderCloseDisplay); 2251f0ac6a5Smrg } 2261f0ac6a5Smrg 2271f0ac6a5Smrg /* 2281f0ac6a5Smrg * now, chain it onto the list 2291f0ac6a5Smrg */ 2301f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 2311f0ac6a5Smrg dpyinfo->next = extinfo->head; 2321f0ac6a5Smrg extinfo->head = dpyinfo; 2331f0ac6a5Smrg extinfo->cur = dpyinfo; 2341f0ac6a5Smrg extinfo->ndisplays++; 2351f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2361f0ac6a5Smrg return dpyinfo; 2371f0ac6a5Smrg} 2381f0ac6a5Smrg 2391f0ac6a5Smrg 2401f0ac6a5Smrg/* 2411f0ac6a5Smrg * XRenderExtRemoveDisplay - remove the indicated display from the 2421f0ac6a5Smrg * extension object. (Replaces XextRemoveDisplay.) 2431f0ac6a5Smrg */ 2441f0ac6a5Smrgstatic int 2451f0ac6a5SmrgXRenderExtRemoveDisplay (XRenderExtInfo *extinfo, Display *dpy) 2461f0ac6a5Smrg{ 2471f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo, *prev; 2481f0ac6a5Smrg 2491f0ac6a5Smrg /* 2501f0ac6a5Smrg * locate this display and its back link so that it can be removed 2511f0ac6a5Smrg */ 2521f0ac6a5Smrg _XLockMutex(_Xglobal_lock); 2531f0ac6a5Smrg prev = NULL; 2541f0ac6a5Smrg for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 2551f0ac6a5Smrg if (dpyinfo->display == dpy) break; 2561f0ac6a5Smrg prev = dpyinfo; 2571f0ac6a5Smrg } 2581f0ac6a5Smrg if (!dpyinfo) { 2591f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2601f0ac6a5Smrg return 0; /* hmm, actually an error */ 2611f0ac6a5Smrg } 2621f0ac6a5Smrg 2631f0ac6a5Smrg /* 2641f0ac6a5Smrg * remove the display from the list; handles going to zero 2651f0ac6a5Smrg */ 2661f0ac6a5Smrg if (prev) 2671f0ac6a5Smrg prev->next = dpyinfo->next; 2681f0ac6a5Smrg else 2691f0ac6a5Smrg extinfo->head = dpyinfo->next; 2701f0ac6a5Smrg 2711f0ac6a5Smrg extinfo->ndisplays--; 2721f0ac6a5Smrg if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */ 2731f0ac6a5Smrg _XUnlockMutex(_Xglobal_lock); 2741f0ac6a5Smrg 2751f0ac6a5Smrg Xfree ((char *) dpyinfo); 2761f0ac6a5Smrg return 1; 2771f0ac6a5Smrg} 2781f0ac6a5Smrg 2791f0ac6a5Smrg 2801f0ac6a5Smrg 2811f0ac6a5SmrgXRenderExtDisplayInfo * 2821f0ac6a5SmrgXRenderFindDisplay (Display *dpy) 2831f0ac6a5Smrg{ 2841f0ac6a5Smrg XRenderExtDisplayInfo *dpyinfo; 2851f0ac6a5Smrg 2861f0ac6a5Smrg dpyinfo = XRenderExtFindDisplay (&XRenderExtensionInfo, dpy); 2871f0ac6a5Smrg if (!dpyinfo) 2881f0ac6a5Smrg dpyinfo = XRenderExtAddDisplay (&XRenderExtensionInfo, dpy, 2891f0ac6a5Smrg XRenderExtensionName); 2901f0ac6a5Smrg return dpyinfo; 2911f0ac6a5Smrg} 2921f0ac6a5Smrg 2931f0ac6a5Smrgstatic int 2941f0ac6a5SmrgXRenderCloseDisplay (Display *dpy, XExtCodes *codes) 2951f0ac6a5Smrg{ 2961f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 2971f0ac6a5Smrg if (info && info->info) XFree (info->info); 2981f0ac6a5Smrg 2991f0ac6a5Smrg return XRenderExtRemoveDisplay (&XRenderExtensionInfo, dpy); 3001f0ac6a5Smrg} 3011f0ac6a5Smrg 3021f0ac6a5Smrg/**************************************************************************** 3031f0ac6a5Smrg * * 3041f0ac6a5Smrg * Render public interfaces * 3051f0ac6a5Smrg * * 3061f0ac6a5Smrg ****************************************************************************/ 3071f0ac6a5Smrg 3081f0ac6a5SmrgBool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep) 3091f0ac6a5Smrg{ 3101f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3111f0ac6a5Smrg 3121f0ac6a5Smrg if (RenderHasExtension(info)) { 3131f0ac6a5Smrg *event_basep = info->codes->first_event; 3141f0ac6a5Smrg *error_basep = info->codes->first_error; 3151f0ac6a5Smrg return True; 3161f0ac6a5Smrg } else { 3171f0ac6a5Smrg return False; 3181f0ac6a5Smrg } 3191f0ac6a5Smrg} 3201f0ac6a5Smrg 3211f0ac6a5Smrg 3221f0ac6a5SmrgStatus XRenderQueryVersion (Display *dpy, 3231f0ac6a5Smrg int *major_versionp, 3241f0ac6a5Smrg int *minor_versionp) 3251f0ac6a5Smrg{ 3261f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3271f0ac6a5Smrg XRenderInfo *xri; 3281f0ac6a5Smrg 3291f0ac6a5Smrg if (!RenderHasExtension (info)) 3301f0ac6a5Smrg return 0; 3311f0ac6a5Smrg 3321f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 3331f0ac6a5Smrg return 0; 3341f0ac6a5Smrg 3351f0ac6a5Smrg xri = info->info; 3361f0ac6a5Smrg *major_versionp = xri->major_version; 3371f0ac6a5Smrg *minor_versionp = xri->minor_version; 3381f0ac6a5Smrg return 1; 3391f0ac6a5Smrg} 3401f0ac6a5Smrg 3411f0ac6a5Smrgstatic XRenderPictFormat * 3421f0ac6a5Smrg_XRenderFindFormat (XRenderInfo *xri, PictFormat format) 3431f0ac6a5Smrg{ 3441f0ac6a5Smrg int nf; 3451f0ac6a5Smrg 3461f0ac6a5Smrg for (nf = 0; nf < xri->nformat; nf++) 3471f0ac6a5Smrg if (xri->format[nf].id == format) 3481f0ac6a5Smrg return &xri->format[nf]; 349e5410a46Smrg return NULL; 3501f0ac6a5Smrg} 3511f0ac6a5Smrg 3521f0ac6a5Smrgstatic Visual * 3531f0ac6a5Smrg_XRenderFindVisual (Display *dpy, VisualID vid) 3541f0ac6a5Smrg{ 3551f0ac6a5Smrg return _XVIDtoVisual (dpy, vid); 3561f0ac6a5Smrg} 3571f0ac6a5Smrg 3581f0ac6a5Smrgtypedef struct _renderVersionState { 3591f0ac6a5Smrg unsigned long version_seq; 3601f0ac6a5Smrg Bool error; 3611f0ac6a5Smrg int major_version; 3621f0ac6a5Smrg int minor_version; 3631f0ac6a5Smrg 3641f0ac6a5Smrg} _XrenderVersionState; 3651f0ac6a5Smrg 3661f0ac6a5Smrgstatic Bool 3671f0ac6a5Smrg_XRenderVersionHandler (Display *dpy, 3681f0ac6a5Smrg xReply *rep, 3691f0ac6a5Smrg char *buf, 3701f0ac6a5Smrg int len, 3711f0ac6a5Smrg XPointer data) 3721f0ac6a5Smrg{ 3731f0ac6a5Smrg xRenderQueryVersionReply replbuf; 3741f0ac6a5Smrg xRenderQueryVersionReply *repl; 3751f0ac6a5Smrg _XrenderVersionState *state = (_XrenderVersionState *) data; 3761f0ac6a5Smrg 3771f0ac6a5Smrg if (dpy->last_request_read != state->version_seq) 3781f0ac6a5Smrg return False; 3791f0ac6a5Smrg if (rep->generic.type == X_Error) 3801f0ac6a5Smrg { 3811f0ac6a5Smrg state->error = True; 3821f0ac6a5Smrg return False; 3831f0ac6a5Smrg } 3841f0ac6a5Smrg repl = (xRenderQueryVersionReply *) 3851f0ac6a5Smrg _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, 3861f0ac6a5Smrg (SIZEOF(xRenderQueryVersionReply) - SIZEOF(xReply)) >> 2, 3871f0ac6a5Smrg True); 3881f0ac6a5Smrg state->major_version = repl->majorVersion; 3891f0ac6a5Smrg state->minor_version = repl->minorVersion; 3901f0ac6a5Smrg return True; 3911f0ac6a5Smrg} 3921f0ac6a5Smrg 3931f0ac6a5SmrgStatus 3941f0ac6a5SmrgXRenderQueryFormats (Display *dpy) 3951f0ac6a5Smrg{ 3961f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 3971f0ac6a5Smrg _XAsyncHandler async; 3981f0ac6a5Smrg _XrenderVersionState async_state; 3991f0ac6a5Smrg xRenderQueryVersionReq *vreq; 4001f0ac6a5Smrg xRenderQueryPictFormatsReply rep; 4011f0ac6a5Smrg xRenderQueryPictFormatsReq *req; 4021f0ac6a5Smrg XRenderInfo *xri; 4031f0ac6a5Smrg XRenderPictFormat *format; 4041f0ac6a5Smrg XRenderScreen *screen; 4051f0ac6a5Smrg XRenderDepth *depth; 4061f0ac6a5Smrg XRenderVisual *visual; 4071f0ac6a5Smrg xPictFormInfo *xFormat; 4081f0ac6a5Smrg xPictScreen *xScreen; 4091f0ac6a5Smrg xPictDepth *xDepth; 4101f0ac6a5Smrg xPictVisual *xVisual; 4111f0ac6a5Smrg CARD32 *xSubpixel; 4121f0ac6a5Smrg void *xData; 4131f0ac6a5Smrg int nf, ns, nd, nv; 4141f0ac6a5Smrg int rlength; 4151f0ac6a5Smrg int nbytes; 4161f0ac6a5Smrg 4171f0ac6a5Smrg RenderCheckExtension (dpy, info, 0); 4181f0ac6a5Smrg LockDisplay (dpy); 4191f0ac6a5Smrg if (info->info) 4201f0ac6a5Smrg { 4211f0ac6a5Smrg UnlockDisplay (dpy); 4221f0ac6a5Smrg return 1; 4231f0ac6a5Smrg } 4241f0ac6a5Smrg GetReq (RenderQueryVersion, vreq); 4251f0ac6a5Smrg vreq->reqType = info->codes->major_opcode; 4261f0ac6a5Smrg vreq->renderReqType = X_RenderQueryVersion; 4271f0ac6a5Smrg vreq->majorVersion = RENDER_MAJOR; 4281f0ac6a5Smrg vreq->minorVersion = RENDER_MINOR; 4291f0ac6a5Smrg 4301f0ac6a5Smrg async_state.version_seq = dpy->request; 4311f0ac6a5Smrg async_state.error = False; 4321f0ac6a5Smrg async.next = dpy->async_handlers; 4331f0ac6a5Smrg async.handler = _XRenderVersionHandler; 4341f0ac6a5Smrg async.data = (XPointer) &async_state; 4351f0ac6a5Smrg dpy->async_handlers = &async; 4361f0ac6a5Smrg 4371f0ac6a5Smrg GetReq (RenderQueryPictFormats, req); 4381f0ac6a5Smrg req->reqType = info->codes->major_opcode; 4391f0ac6a5Smrg req->renderReqType = X_RenderQueryPictFormats; 4401f0ac6a5Smrg 4411f0ac6a5Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 4421f0ac6a5Smrg { 4431f0ac6a5Smrg DeqAsyncHandler (dpy, &async); 4441f0ac6a5Smrg UnlockDisplay (dpy); 4451f0ac6a5Smrg SyncHandle (); 4461f0ac6a5Smrg return 0; 4471f0ac6a5Smrg } 4481f0ac6a5Smrg DeqAsyncHandler (dpy, &async); 4491f0ac6a5Smrg if (async_state.error) 4501f0ac6a5Smrg { 4511f0ac6a5Smrg UnlockDisplay(dpy); 4521f0ac6a5Smrg SyncHandle(); 4531f0ac6a5Smrg return 0; 4541f0ac6a5Smrg } 4551f0ac6a5Smrg /* 4561f0ac6a5Smrg * Check for the lack of sub-pixel data 4571f0ac6a5Smrg */ 4581f0ac6a5Smrg if (async_state.major_version == 0 && async_state.minor_version < 6) 4591f0ac6a5Smrg rep.numSubpixel = 0; 4601f0ac6a5Smrg 4611f0ac6a5Smrg xri = (XRenderInfo *) Xmalloc (sizeof (XRenderInfo) + 4621f0ac6a5Smrg rep.numFormats * sizeof (XRenderPictFormat) + 4631f0ac6a5Smrg rep.numScreens * sizeof (XRenderScreen) + 4641f0ac6a5Smrg rep.numDepths * sizeof (XRenderDepth) + 4651f0ac6a5Smrg rep.numVisuals * sizeof (XRenderVisual)); 4661f0ac6a5Smrg rlength = (rep.numFormats * sizeof (xPictFormInfo) + 4671f0ac6a5Smrg rep.numScreens * sizeof (xPictScreen) + 4681f0ac6a5Smrg rep.numDepths * sizeof (xPictDepth) + 4691f0ac6a5Smrg rep.numVisuals * sizeof (xPictVisual) + 4701f0ac6a5Smrg rep.numSubpixel * 4); 4711f0ac6a5Smrg xData = (void *) Xmalloc (rlength); 4721f0ac6a5Smrg nbytes = (int) rep.length << 2; 4731f0ac6a5Smrg 4741f0ac6a5Smrg if (!xri || !xData || nbytes < rlength) 4751f0ac6a5Smrg { 4761f0ac6a5Smrg if (xri) Xfree (xri); 4771f0ac6a5Smrg if (xData) Xfree (xData); 4781f0ac6a5Smrg _XEatData (dpy, nbytes); 4791f0ac6a5Smrg UnlockDisplay (dpy); 4801f0ac6a5Smrg SyncHandle (); 4811f0ac6a5Smrg return 0; 4821f0ac6a5Smrg } 4831f0ac6a5Smrg xri->major_version = async_state.major_version; 4841f0ac6a5Smrg xri->minor_version = async_state.minor_version; 4851f0ac6a5Smrg xri->format = (XRenderPictFormat *) (xri + 1); 4861f0ac6a5Smrg xri->nformat = rep.numFormats; 4871f0ac6a5Smrg xri->screen = (XRenderScreen *) (xri->format + rep.numFormats); 4881f0ac6a5Smrg xri->nscreen = rep.numScreens; 4891f0ac6a5Smrg xri->depth = (XRenderDepth *) (xri->screen + rep.numScreens); 4901f0ac6a5Smrg xri->ndepth = rep.numDepths; 4911f0ac6a5Smrg xri->visual = (XRenderVisual *) (xri->depth + rep.numDepths); 4921f0ac6a5Smrg xri->nvisual = rep.numVisuals; 4931f0ac6a5Smrg _XRead (dpy, (char *) xData, rlength); 4941f0ac6a5Smrg format = xri->format; 4951f0ac6a5Smrg xFormat = (xPictFormInfo *) xData; 4961f0ac6a5Smrg for (nf = 0; nf < rep.numFormats; nf++) 4971f0ac6a5Smrg { 4981f0ac6a5Smrg format->id = xFormat->id; 4991f0ac6a5Smrg format->type = xFormat->type; 5001f0ac6a5Smrg format->depth = xFormat->depth; 5011f0ac6a5Smrg format->direct.red = xFormat->direct.red; 5021f0ac6a5Smrg format->direct.redMask = xFormat->direct.redMask; 5031f0ac6a5Smrg format->direct.green = xFormat->direct.green; 5041f0ac6a5Smrg format->direct.greenMask = xFormat->direct.greenMask; 5051f0ac6a5Smrg format->direct.blue = xFormat->direct.blue; 5061f0ac6a5Smrg format->direct.blueMask = xFormat->direct.blueMask; 5071f0ac6a5Smrg format->direct.alpha = xFormat->direct.alpha; 5081f0ac6a5Smrg format->direct.alphaMask = xFormat->direct.alphaMask; 5091f0ac6a5Smrg format->colormap = xFormat->colormap; 5101f0ac6a5Smrg format++; 5111f0ac6a5Smrg xFormat++; 5121f0ac6a5Smrg } 5131f0ac6a5Smrg xScreen = (xPictScreen *) xFormat; 5141f0ac6a5Smrg screen = xri->screen; 5151f0ac6a5Smrg depth = xri->depth; 5161f0ac6a5Smrg visual = xri->visual; 5171f0ac6a5Smrg for (ns = 0; ns < xri->nscreen; ns++) 5181f0ac6a5Smrg { 5191f0ac6a5Smrg screen->depths = depth; 5201f0ac6a5Smrg screen->ndepths = xScreen->nDepth; 5211f0ac6a5Smrg screen->fallback = _XRenderFindFormat (xri, xScreen->fallback); 5221f0ac6a5Smrg screen->subpixel = SubPixelUnknown; 5231f0ac6a5Smrg xDepth = (xPictDepth *) (xScreen + 1); 5241f0ac6a5Smrg for (nd = 0; nd < screen->ndepths; nd++) 5251f0ac6a5Smrg { 5261f0ac6a5Smrg depth->depth = xDepth->depth; 5271f0ac6a5Smrg depth->nvisuals = xDepth->nPictVisuals; 5281f0ac6a5Smrg depth->visuals = visual; 5291f0ac6a5Smrg xVisual = (xPictVisual *) (xDepth + 1); 5301f0ac6a5Smrg for (nv = 0; nv < depth->nvisuals; nv++) 5311f0ac6a5Smrg { 5321f0ac6a5Smrg visual->visual = _XRenderFindVisual (dpy, xVisual->visual); 5331f0ac6a5Smrg visual->format = _XRenderFindFormat (xri, xVisual->format); 5341f0ac6a5Smrg visual++; 5351f0ac6a5Smrg xVisual++; 5361f0ac6a5Smrg } 5371f0ac6a5Smrg depth++; 5381f0ac6a5Smrg xDepth = (xPictDepth *) xVisual; 5391f0ac6a5Smrg } 5401f0ac6a5Smrg screen++; 5411f0ac6a5Smrg xScreen = (xPictScreen *) xDepth; 5421f0ac6a5Smrg } 5431f0ac6a5Smrg xSubpixel = (CARD32 *) xScreen; 5441f0ac6a5Smrg screen = xri->screen; 5451f0ac6a5Smrg for (ns = 0; ns < rep.numSubpixel; ns++) 5461f0ac6a5Smrg { 5471f0ac6a5Smrg screen->subpixel = *xSubpixel; 5481f0ac6a5Smrg xSubpixel++; 5491f0ac6a5Smrg screen++; 5501f0ac6a5Smrg } 5511f0ac6a5Smrg info->info = xri; 5521f0ac6a5Smrg /* 5531f0ac6a5Smrg * Skip any extra data 5541f0ac6a5Smrg */ 5551f0ac6a5Smrg if (nbytes > rlength) 5561f0ac6a5Smrg _XEatData (dpy, (unsigned long) (nbytes - rlength)); 5571f0ac6a5Smrg 5581f0ac6a5Smrg UnlockDisplay (dpy); 5591f0ac6a5Smrg SyncHandle (); 5601f0ac6a5Smrg Xfree (xData); 5611f0ac6a5Smrg return 1; 5621f0ac6a5Smrg} 5631f0ac6a5Smrg 5641f0ac6a5Smrgint 5651f0ac6a5SmrgXRenderQuerySubpixelOrder (Display *dpy, int screen) 5661f0ac6a5Smrg{ 5671f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 5681f0ac6a5Smrg XRenderInfo *xri; 5691f0ac6a5Smrg 5701f0ac6a5Smrg if (!RenderHasExtension (info)) 5711f0ac6a5Smrg return SubPixelUnknown; 5721f0ac6a5Smrg 5731f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 5741f0ac6a5Smrg return SubPixelUnknown; 5751f0ac6a5Smrg 5761f0ac6a5Smrg xri = info->info; 5771f0ac6a5Smrg return xri->screen[screen].subpixel; 5781f0ac6a5Smrg} 5791f0ac6a5Smrg 5801f0ac6a5SmrgBool 5811f0ac6a5SmrgXRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel) 5821f0ac6a5Smrg{ 5831f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 5841f0ac6a5Smrg XRenderInfo *xri; 5851f0ac6a5Smrg 5861f0ac6a5Smrg if (!RenderHasExtension (info)) 5871f0ac6a5Smrg return False; 5881f0ac6a5Smrg 5891f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 5901f0ac6a5Smrg return False; 5911f0ac6a5Smrg 5921f0ac6a5Smrg xri = info->info; 5931f0ac6a5Smrg xri->screen[screen].subpixel = subpixel; 5941f0ac6a5Smrg return True; 5951f0ac6a5Smrg} 5961f0ac6a5Smrg 5971f0ac6a5SmrgXRenderPictFormat * 5981f0ac6a5SmrgXRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual) 5991f0ac6a5Smrg{ 6001f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6011f0ac6a5Smrg int nv; 6021f0ac6a5Smrg XRenderInfo *xri; 6031f0ac6a5Smrg XRenderVisual *xrv; 604e5410a46Smrg 605e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 6061f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 607e5410a46Smrg return NULL; 6081f0ac6a5Smrg xri = info->info; 6091f0ac6a5Smrg for (nv = 0, xrv = xri->visual; nv < xri->nvisual; nv++, xrv++) 6101f0ac6a5Smrg if (xrv->visual == visual) 6111f0ac6a5Smrg return xrv->format; 612e5410a46Smrg return NULL; 6131f0ac6a5Smrg} 6141f0ac6a5Smrg 6151f0ac6a5SmrgXRenderPictFormat * 6161f0ac6a5SmrgXRenderFindFormat (Display *dpy, 6171f0ac6a5Smrg unsigned long mask, 6181f0ac6a5Smrg _Xconst XRenderPictFormat *template, 6191f0ac6a5Smrg int count) 6201f0ac6a5Smrg{ 6211f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 6221f0ac6a5Smrg int nf; 6231f0ac6a5Smrg XRenderInfo *xri; 624e5410a46Smrg 625e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 6261f0ac6a5Smrg if (!XRenderQueryFormats (dpy)) 627e5410a46Smrg return NULL; 6281f0ac6a5Smrg xri = info->info; 6291f0ac6a5Smrg for (nf = 0; nf < xri->nformat; nf++) 6301f0ac6a5Smrg { 6311f0ac6a5Smrg if (mask & PictFormatID) 6321f0ac6a5Smrg if (template->id != xri->format[nf].id) 6331f0ac6a5Smrg continue; 6341f0ac6a5Smrg if (mask & PictFormatType) 6351f0ac6a5Smrg if (template->type != xri->format[nf].type) 6361f0ac6a5Smrg continue; 6371f0ac6a5Smrg if (mask & PictFormatDepth) 6381f0ac6a5Smrg if (template->depth != xri->format[nf].depth) 6391f0ac6a5Smrg continue; 6401f0ac6a5Smrg if (mask & PictFormatRed) 6411f0ac6a5Smrg if (template->direct.red != xri->format[nf].direct.red) 6421f0ac6a5Smrg continue; 6431f0ac6a5Smrg if (mask & PictFormatRedMask) 6441f0ac6a5Smrg if (template->direct.redMask != xri->format[nf].direct.redMask) 6451f0ac6a5Smrg continue; 6461f0ac6a5Smrg if (mask & PictFormatGreen) 6471f0ac6a5Smrg if (template->direct.green != xri->format[nf].direct.green) 6481f0ac6a5Smrg continue; 6491f0ac6a5Smrg if (mask & PictFormatGreenMask) 6501f0ac6a5Smrg if (template->direct.greenMask != xri->format[nf].direct.greenMask) 6511f0ac6a5Smrg continue; 6521f0ac6a5Smrg if (mask & PictFormatBlue) 6531f0ac6a5Smrg if (template->direct.blue != xri->format[nf].direct.blue) 6541f0ac6a5Smrg continue; 6551f0ac6a5Smrg if (mask & PictFormatBlueMask) 6561f0ac6a5Smrg if (template->direct.blueMask != xri->format[nf].direct.blueMask) 6571f0ac6a5Smrg continue; 6581f0ac6a5Smrg if (mask & PictFormatAlpha) 6591f0ac6a5Smrg if (template->direct.alpha != xri->format[nf].direct.alpha) 6601f0ac6a5Smrg continue; 6611f0ac6a5Smrg if (mask & PictFormatAlphaMask) 6621f0ac6a5Smrg if (template->direct.alphaMask != xri->format[nf].direct.alphaMask) 6631f0ac6a5Smrg continue; 6641f0ac6a5Smrg if (mask & PictFormatColormap) 6651f0ac6a5Smrg if (template->colormap != xri->format[nf].colormap) 6661f0ac6a5Smrg continue; 6671f0ac6a5Smrg if (count-- == 0) 6681f0ac6a5Smrg return &xri->format[nf]; 6691f0ac6a5Smrg } 670e5410a46Smrg return NULL; 6711f0ac6a5Smrg} 6721f0ac6a5Smrg 6731f0ac6a5SmrgXRenderPictFormat * 6741f0ac6a5SmrgXRenderFindStandardFormat (Display *dpy, 6751f0ac6a5Smrg int format) 6761f0ac6a5Smrg{ 6771f0ac6a5Smrg static struct { 6781f0ac6a5Smrg XRenderPictFormat templ; 6791f0ac6a5Smrg unsigned long mask; 6801f0ac6a5Smrg } standardFormats[PictStandardNUM] = { 6811f0ac6a5Smrg /* PictStandardARGB32 */ 6821f0ac6a5Smrg { 6831f0ac6a5Smrg { 6841f0ac6a5Smrg 0, /* id */ 6851f0ac6a5Smrg PictTypeDirect, /* type */ 6861f0ac6a5Smrg 32, /* depth */ 6871f0ac6a5Smrg { /* direct */ 6881f0ac6a5Smrg 16, /* direct.red */ 6891f0ac6a5Smrg 0xff, /* direct.redMask */ 6901f0ac6a5Smrg 8, /* direct.green */ 6911f0ac6a5Smrg 0xff, /* direct.greenMask */ 6921f0ac6a5Smrg 0, /* direct.blue */ 6931f0ac6a5Smrg 0xff, /* direct.blueMask */ 6941f0ac6a5Smrg 24, /* direct.alpha */ 6951f0ac6a5Smrg 0xff, /* direct.alphaMask */ 6961f0ac6a5Smrg }, 6971f0ac6a5Smrg 0, /* colormap */ 6981f0ac6a5Smrg }, 6991f0ac6a5Smrg PictFormatType | 7001f0ac6a5Smrg PictFormatDepth | 7011f0ac6a5Smrg PictFormatRed | 7021f0ac6a5Smrg PictFormatRedMask | 7031f0ac6a5Smrg PictFormatGreen | 7041f0ac6a5Smrg PictFormatGreenMask | 7051f0ac6a5Smrg PictFormatBlue | 7061f0ac6a5Smrg PictFormatBlueMask | 7071f0ac6a5Smrg PictFormatAlpha | 7081f0ac6a5Smrg PictFormatAlphaMask, 7091f0ac6a5Smrg }, 7101f0ac6a5Smrg /* PictStandardRGB24 */ 7111f0ac6a5Smrg { 7121f0ac6a5Smrg { 7131f0ac6a5Smrg 0, /* id */ 7141f0ac6a5Smrg PictTypeDirect, /* type */ 7151f0ac6a5Smrg 24, /* depth */ 7161f0ac6a5Smrg { /* direct */ 7171f0ac6a5Smrg 16, /* direct.red */ 7181f0ac6a5Smrg 0xff, /* direct.redMask */ 7191f0ac6a5Smrg 8, /* direct.green */ 7201f0ac6a5Smrg 0xff, /* direct.greenMask */ 7211f0ac6a5Smrg 0, /* direct.blue */ 7221f0ac6a5Smrg 0xff, /* direct.blueMask */ 7231f0ac6a5Smrg 0, /* direct.alpha */ 7241f0ac6a5Smrg 0x00, /* direct.alphaMask */ 7251f0ac6a5Smrg }, 7261f0ac6a5Smrg 0, /* colormap */ 7271f0ac6a5Smrg }, 7281f0ac6a5Smrg PictFormatType | 7291f0ac6a5Smrg PictFormatDepth | 7301f0ac6a5Smrg PictFormatRed | 7311f0ac6a5Smrg PictFormatRedMask | 7321f0ac6a5Smrg PictFormatGreen | 7331f0ac6a5Smrg PictFormatGreenMask | 7341f0ac6a5Smrg PictFormatBlue | 7351f0ac6a5Smrg PictFormatBlueMask | 7361f0ac6a5Smrg PictFormatAlphaMask, 7371f0ac6a5Smrg }, 7381f0ac6a5Smrg /* PictStandardA8 */ 7391f0ac6a5Smrg { 7401f0ac6a5Smrg { 7411f0ac6a5Smrg 0, /* id */ 7421f0ac6a5Smrg PictTypeDirect, /* type */ 7431f0ac6a5Smrg 8, /* depth */ 7441f0ac6a5Smrg { /* direct */ 7451f0ac6a5Smrg 0, /* direct.red */ 7461f0ac6a5Smrg 0x00, /* direct.redMask */ 7471f0ac6a5Smrg 0, /* direct.green */ 7481f0ac6a5Smrg 0x00, /* direct.greenMask */ 7491f0ac6a5Smrg 0, /* direct.blue */ 7501f0ac6a5Smrg 0x00, /* direct.blueMask */ 7511f0ac6a5Smrg 0, /* direct.alpha */ 7521f0ac6a5Smrg 0xff, /* direct.alphaMask */ 7531f0ac6a5Smrg }, 7541f0ac6a5Smrg 0, /* colormap */ 7551f0ac6a5Smrg }, 7561f0ac6a5Smrg PictFormatType | 7571f0ac6a5Smrg PictFormatDepth | 7581f0ac6a5Smrg PictFormatRedMask | 7591f0ac6a5Smrg PictFormatGreenMask | 7601f0ac6a5Smrg PictFormatBlueMask | 7611f0ac6a5Smrg PictFormatAlpha | 7621f0ac6a5Smrg PictFormatAlphaMask, 7631f0ac6a5Smrg }, 7641f0ac6a5Smrg /* PictStandardA4 */ 7651f0ac6a5Smrg { 7661f0ac6a5Smrg { 7671f0ac6a5Smrg 0, /* id */ 7681f0ac6a5Smrg PictTypeDirect, /* type */ 7691f0ac6a5Smrg 4, /* depth */ 7701f0ac6a5Smrg { /* direct */ 7711f0ac6a5Smrg 0, /* direct.red */ 7721f0ac6a5Smrg 0x00, /* direct.redMask */ 7731f0ac6a5Smrg 0, /* direct.green */ 7741f0ac6a5Smrg 0x00, /* direct.greenMask */ 7751f0ac6a5Smrg 0, /* direct.blue */ 7761f0ac6a5Smrg 0x00, /* direct.blueMask */ 7771f0ac6a5Smrg 0, /* direct.alpha */ 7781f0ac6a5Smrg 0x0f, /* direct.alphaMask */ 7791f0ac6a5Smrg }, 7801f0ac6a5Smrg 0, /* colormap */ 7811f0ac6a5Smrg }, 7821f0ac6a5Smrg PictFormatType | 7831f0ac6a5Smrg PictFormatDepth | 7841f0ac6a5Smrg PictFormatRedMask | 7851f0ac6a5Smrg PictFormatGreenMask | 7861f0ac6a5Smrg PictFormatBlueMask | 7871f0ac6a5Smrg PictFormatAlpha | 7881f0ac6a5Smrg PictFormatAlphaMask, 7891f0ac6a5Smrg }, 7901f0ac6a5Smrg /* PictStandardA1 */ 7911f0ac6a5Smrg { 7921f0ac6a5Smrg { 7931f0ac6a5Smrg 0, /* id */ 7941f0ac6a5Smrg PictTypeDirect, /* type */ 7951f0ac6a5Smrg 1, /* 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 0x01, /* direct.alphaMask */ 8051f0ac6a5Smrg }, 8061f0ac6a5Smrg 0, /* colormap */ 8071f0ac6a5Smrg }, 8081f0ac6a5Smrg PictFormatType | 8091f0ac6a5Smrg PictFormatDepth | 8101f0ac6a5Smrg PictFormatRedMask | 8111f0ac6a5Smrg PictFormatGreenMask | 8121f0ac6a5Smrg PictFormatBlueMask | 8131f0ac6a5Smrg PictFormatAlpha | 8141f0ac6a5Smrg PictFormatAlphaMask, 8151f0ac6a5Smrg }, 8161f0ac6a5Smrg }; 8171f0ac6a5Smrg 8181f0ac6a5Smrg if (0 <= format && format < PictStandardNUM) 8191f0ac6a5Smrg return XRenderFindFormat (dpy, 8201f0ac6a5Smrg standardFormats[format].mask, 8211f0ac6a5Smrg &standardFormats[format].templ, 8221f0ac6a5Smrg 0); 823e5410a46Smrg return NULL; 8241f0ac6a5Smrg} 8251f0ac6a5Smrg 8261f0ac6a5SmrgXIndexValue * 8271f0ac6a5SmrgXRenderQueryPictIndexValues(Display *dpy, 8281f0ac6a5Smrg _Xconst XRenderPictFormat *format, 8291f0ac6a5Smrg int *num) 8301f0ac6a5Smrg{ 8311f0ac6a5Smrg XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 8321f0ac6a5Smrg xRenderQueryPictIndexValuesReq *req; 8331f0ac6a5Smrg xRenderQueryPictIndexValuesReply rep; 8341f0ac6a5Smrg XIndexValue *values; 8351f0ac6a5Smrg int nbytes, nread, rlength, i; 8361f0ac6a5Smrg 837e5410a46Smrg RenderCheckExtension (dpy, info, NULL); 8381f0ac6a5Smrg 8391f0ac6a5Smrg LockDisplay (dpy); 8401f0ac6a5Smrg GetReq (RenderQueryPictIndexValues, req); 8411f0ac6a5Smrg req->reqType = info->codes->major_opcode; 8421f0ac6a5Smrg req->renderReqType = X_RenderQueryPictIndexValues; 8431f0ac6a5Smrg req->format = format->id; 8441f0ac6a5Smrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 8451f0ac6a5Smrg { 8461f0ac6a5Smrg UnlockDisplay (dpy); 8471f0ac6a5Smrg SyncHandle (); 848e5410a46Smrg return NULL; 8491f0ac6a5Smrg } 8501f0ac6a5Smrg 8511f0ac6a5Smrg /* request data length */ 8521f0ac6a5Smrg nbytes = (long)rep.length << 2; 8531f0ac6a5Smrg /* bytes of actual data in the request */ 8541f0ac6a5Smrg nread = rep.numIndexValues * SIZEOF (xIndexValue); 8551f0ac6a5Smrg /* size of array returned to application */ 8561f0ac6a5Smrg rlength = rep.numIndexValues * sizeof (XIndexValue); 8571f0ac6a5Smrg 8581f0ac6a5Smrg /* allocate returned data */ 8591f0ac6a5Smrg values = (XIndexValue *)Xmalloc (rlength); 8601f0ac6a5Smrg if (!values) 8611f0ac6a5Smrg { 8621f0ac6a5Smrg _XEatData (dpy, nbytes); 8631f0ac6a5Smrg UnlockDisplay (dpy); 8641f0ac6a5Smrg SyncHandle (); 865e5410a46Smrg return NULL; 8661f0ac6a5Smrg } 8671f0ac6a5Smrg 8681f0ac6a5Smrg /* read the values one at a time and convert */ 8691f0ac6a5Smrg *num = rep.numIndexValues; 8701f0ac6a5Smrg for(i = 0; i < rep.numIndexValues; i++) 8711f0ac6a5Smrg { 8721f0ac6a5Smrg xIndexValue value; 8731f0ac6a5Smrg 8741f0ac6a5Smrg _XRead (dpy, (char *) &value, SIZEOF (xIndexValue)); 8751f0ac6a5Smrg values[i].pixel = value.pixel; 8761f0ac6a5Smrg values[i].red = value.red; 8771f0ac6a5Smrg values[i].green = value.green; 8781f0ac6a5Smrg values[i].blue = value.blue; 8791f0ac6a5Smrg values[i].alpha = value.alpha; 8801f0ac6a5Smrg } 8811f0ac6a5Smrg /* skip any padding */ 8821f0ac6a5Smrg if(nbytes > nread) 8831f0ac6a5Smrg { 8841f0ac6a5Smrg _XEatData (dpy, (unsigned long) (nbytes - nread)); 8851f0ac6a5Smrg } 8861f0ac6a5Smrg UnlockDisplay (dpy); 8871f0ac6a5Smrg SyncHandle (); 8881f0ac6a5Smrg return values; 8891f0ac6a5Smrg} 890