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