190b17f1bSmrg/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
290b17f1bSmrg/**************************************************************************
390b17f1bSmrg
490b17f1bSmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
590b17f1bSmrgCopyright 2000 VA Linux Systems, Inc.
690b17f1bSmrgAll Rights Reserved.
790b17f1bSmrg
890b17f1bSmrgPermission is hereby granted, free of charge, to any person obtaining a
990b17f1bSmrgcopy of this software and associated documentation files (the
1090b17f1bSmrg"Software"), to deal in the Software without restriction, including
1190b17f1bSmrgwithout limitation the rights to use, copy, modify, merge, publish,
1290b17f1bSmrgdistribute, sub license, and/or sell copies of the Software, and to
1390b17f1bSmrgpermit persons to whom the Software is furnished to do so, subject to
1490b17f1bSmrgthe following conditions:
1590b17f1bSmrg
1690b17f1bSmrgThe above copyright notice and this permission notice (including the
1790b17f1bSmrgnext paragraph) shall be included in all copies or substantial portions
1890b17f1bSmrgof the Software.
1990b17f1bSmrg
2090b17f1bSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2190b17f1bSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2290b17f1bSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2390b17f1bSmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
2490b17f1bSmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2590b17f1bSmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2690b17f1bSmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2790b17f1bSmrg
2890b17f1bSmrg**************************************************************************/
2990b17f1bSmrg
3090b17f1bSmrg/*
3190b17f1bSmrg * Authors:
3290b17f1bSmrg *   Kevin E. Martin <martin@valinux.com>
3390b17f1bSmrg *   Jens Owen <jens@tungstengraphics.com>
3490b17f1bSmrg *   Rickard E. (Rik) Faith <faith@valinux.com>
3590b17f1bSmrg *
3690b17f1bSmrg */
3790b17f1bSmrg
3890b17f1bSmrg/* THIS IS NOT AN X CONSORTIUM STANDARD */
3990b17f1bSmrg
4090b17f1bSmrg#define NEED_REPLIES
4190b17f1bSmrg#include <X11/Xlibint.h>
4290b17f1bSmrg#include <X11/extensions/Xext.h>
4390b17f1bSmrg#include <X11/extensions/extutil.h>
4490b17f1bSmrg#include "xf86dristr.h"
4590b17f1bSmrg#include <limits.h>
4690b17f1bSmrg
4790b17f1bSmrgstatic XExtensionInfo _xf86dri_info_data;
4890b17f1bSmrgstatic XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
4990b17f1bSmrgstatic char xf86dri_extension_name[] = XF86DRINAME;
5090b17f1bSmrg
5190b17f1bSmrg#define uniDRICheckExtension(dpy,i,val) \
5290b17f1bSmrg  XextCheckExtension (dpy, i, xf86dri_extension_name, val)
5390b17f1bSmrg
5490b17f1bSmrg/*****************************************************************************
5590b17f1bSmrg *                                                                           *
5690b17f1bSmrg *			   private utility routines                          *
5790b17f1bSmrg *                                                                           *
5890b17f1bSmrg *****************************************************************************/
5990b17f1bSmrg
6090b17f1bSmrgstatic int close_display(Display * dpy, XExtCodes * extCodes);
6190b17f1bSmrgstatic /* const */ XExtensionHooks xf86dri_extension_hooks = {
6290b17f1bSmrg    NULL,			       /* create_gc */
6390b17f1bSmrg    NULL,			       /* copy_gc */
6490b17f1bSmrg    NULL,			       /* flush_gc */
6590b17f1bSmrg    NULL,			       /* free_gc */
6690b17f1bSmrg    NULL,			       /* create_font */
6790b17f1bSmrg    NULL,			       /* free_font */
6890b17f1bSmrg    close_display,		       /* close_display */
6990b17f1bSmrg    NULL,			       /* wire_to_event */
7090b17f1bSmrg    NULL,			       /* event_to_wire */
7190b17f1bSmrg    NULL,			       /* error */
7290b17f1bSmrg    NULL,			       /* error_string */
7390b17f1bSmrg};
7490b17f1bSmrg
7590b17f1bSmrgstatic
7690b17f1bSmrgXEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
7790b17f1bSmrg    xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL)
7890b17f1bSmrg
7990b17f1bSmrg    static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
8090b17f1bSmrg
8190b17f1bSmrg/*****************************************************************************
8290b17f1bSmrg *                                                                           *
8390b17f1bSmrg *		    public XFree86-DRI Extension routines                    *
8490b17f1bSmrg *                                                                           *
8590b17f1bSmrg *****************************************************************************/
8690b17f1bSmrg#if 0
8790b17f1bSmrg#include <stdio.h>
8890b17f1bSmrg#define TRACE(msg)  fprintf(stderr,"uniDRI%s\n", msg);
8990b17f1bSmrg#else
9090b17f1bSmrg#define TRACE(msg)
9190b17f1bSmrg#endif
9290b17f1bSmrg    Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
9390b17f1bSmrg    Display *dpy;
9490b17f1bSmrg    int *event_basep, *error_basep;
9590b17f1bSmrg{
9690b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
9790b17f1bSmrg
9890b17f1bSmrg    TRACE("QueryExtension...");
9990b17f1bSmrg    if (XextHasExtension(info)) {
10090b17f1bSmrg	*event_basep = info->codes->first_event;
10190b17f1bSmrg	*error_basep = info->codes->first_error;
10290b17f1bSmrg	TRACE("QueryExtension... return True");
10390b17f1bSmrg	return True;
10490b17f1bSmrg    } else {
10590b17f1bSmrg	TRACE("QueryExtension... return False");
10690b17f1bSmrg	return False;
10790b17f1bSmrg    }
10890b17f1bSmrg}
10990b17f1bSmrg
11090b17f1bSmrgBool
11190b17f1bSmrguniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
11290b17f1bSmrg    Display *dpy;
11390b17f1bSmrg    int *majorVersion;
11490b17f1bSmrg    int *minorVersion;
11590b17f1bSmrg    int *patchVersion;
11690b17f1bSmrg{
11790b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
11890b17f1bSmrg    xXF86DRIQueryVersionReply rep;
11990b17f1bSmrg    xXF86DRIQueryVersionReq *req;
12090b17f1bSmrg
12190b17f1bSmrg    TRACE("QueryVersion...");
12290b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
12390b17f1bSmrg
12490b17f1bSmrg    LockDisplay(dpy);
12590b17f1bSmrg    GetReq(XF86DRIQueryVersion, req);
12690b17f1bSmrg    req->reqType = info->codes->major_opcode;
12790b17f1bSmrg    req->driReqType = X_XF86DRIQueryVersion;
12890b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
12990b17f1bSmrg	UnlockDisplay(dpy);
13090b17f1bSmrg	SyncHandle();
13190b17f1bSmrg	TRACE("QueryVersion... return False");
13290b17f1bSmrg	return False;
13390b17f1bSmrg    }
13490b17f1bSmrg    *majorVersion = rep.majorVersion;
13590b17f1bSmrg    *minorVersion = rep.minorVersion;
13690b17f1bSmrg    *patchVersion = rep.patchVersion;
13790b17f1bSmrg    UnlockDisplay(dpy);
13890b17f1bSmrg    SyncHandle();
13990b17f1bSmrg    TRACE("QueryVersion... return True");
14090b17f1bSmrg    return True;
14190b17f1bSmrg}
14290b17f1bSmrg
14390b17f1bSmrgBool
14490b17f1bSmrguniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
14590b17f1bSmrg    Display *dpy;
14690b17f1bSmrg    int screen;
14790b17f1bSmrg    Bool *isCapable;
14890b17f1bSmrg{
14990b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
15090b17f1bSmrg    xXF86DRIQueryDirectRenderingCapableReply rep;
15190b17f1bSmrg    xXF86DRIQueryDirectRenderingCapableReq *req;
15290b17f1bSmrg
15390b17f1bSmrg    TRACE("QueryDirectRenderingCapable...");
15490b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
15590b17f1bSmrg
15690b17f1bSmrg    LockDisplay(dpy);
15790b17f1bSmrg    GetReq(XF86DRIQueryDirectRenderingCapable, req);
15890b17f1bSmrg    req->reqType = info->codes->major_opcode;
15990b17f1bSmrg    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
16090b17f1bSmrg    req->screen = screen;
16190b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
16290b17f1bSmrg	UnlockDisplay(dpy);
16390b17f1bSmrg	SyncHandle();
16490b17f1bSmrg	TRACE("QueryDirectRenderingCapable... return False");
16590b17f1bSmrg	return False;
16690b17f1bSmrg    }
16790b17f1bSmrg    *isCapable = rep.isCapable;
16890b17f1bSmrg    UnlockDisplay(dpy);
16990b17f1bSmrg    SyncHandle();
17090b17f1bSmrg    TRACE("QueryDirectRenderingCapable... return True");
17190b17f1bSmrg    return True;
17290b17f1bSmrg}
17390b17f1bSmrg
17490b17f1bSmrgBool
17590b17f1bSmrguniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
17690b17f1bSmrg    Display *dpy;
17790b17f1bSmrg    int screen;
17890b17f1bSmrg    drm_handle_t *hSAREA;
17990b17f1bSmrg    char **busIdString;
18090b17f1bSmrg{
18190b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
18290b17f1bSmrg    xXF86DRIOpenConnectionReply rep;
18390b17f1bSmrg    xXF86DRIOpenConnectionReq *req;
18490b17f1bSmrg
18590b17f1bSmrg    TRACE("OpenConnection...");
18690b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
18790b17f1bSmrg
18890b17f1bSmrg    LockDisplay(dpy);
18990b17f1bSmrg    GetReq(XF86DRIOpenConnection, req);
19090b17f1bSmrg    req->reqType = info->codes->major_opcode;
19190b17f1bSmrg    req->driReqType = X_XF86DRIOpenConnection;
19290b17f1bSmrg    req->screen = screen;
19390b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
19490b17f1bSmrg	UnlockDisplay(dpy);
19590b17f1bSmrg	SyncHandle();
19690b17f1bSmrg	TRACE("OpenConnection... return False");
19790b17f1bSmrg	return False;
19890b17f1bSmrg    }
19990b17f1bSmrg
20090b17f1bSmrg    *hSAREA = rep.hSAREALow;
20190b17f1bSmrg#ifdef LONG64
20290b17f1bSmrg    if (sizeof(drm_handle_t) == 8) {
20390b17f1bSmrg	*hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
20490b17f1bSmrg    }
20590b17f1bSmrg#endif
20690b17f1bSmrg    if (rep.length) {
20790b17f1bSmrg	if (rep.busIdStringLength < INT_MAX)
20890b17f1bSmrg	    *busIdString = Xcalloc(rep.busIdStringLength + 1, 1);
20990b17f1bSmrg	else
21090b17f1bSmrg	    *busIdString = NULL;
21190b17f1bSmrg	if (*busIdString == NULL) {
21290b17f1bSmrg	    _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
21390b17f1bSmrg	    UnlockDisplay(dpy);
21490b17f1bSmrg	    SyncHandle();
21590b17f1bSmrg	    TRACE("OpenConnection... return False");
21690b17f1bSmrg	    return False;
21790b17f1bSmrg	}
21890b17f1bSmrg	_XReadPad(dpy, *busIdString, rep.busIdStringLength);
21990b17f1bSmrg    } else {
22090b17f1bSmrg	*busIdString = NULL;
22190b17f1bSmrg    }
22290b17f1bSmrg    UnlockDisplay(dpy);
22390b17f1bSmrg    SyncHandle();
22490b17f1bSmrg    TRACE("OpenConnection... return True");
22590b17f1bSmrg    return True;
22690b17f1bSmrg}
22790b17f1bSmrg
22890b17f1bSmrgBool
22990b17f1bSmrguniDRIAuthConnection(dpy, screen, magic)
23090b17f1bSmrg    Display *dpy;
23190b17f1bSmrg    int screen;
23290b17f1bSmrg    drm_magic_t magic;
23390b17f1bSmrg{
23490b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
23590b17f1bSmrg    xXF86DRIAuthConnectionReq *req;
23690b17f1bSmrg    xXF86DRIAuthConnectionReply rep;
23790b17f1bSmrg
23890b17f1bSmrg    TRACE("AuthConnection...");
23990b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
24090b17f1bSmrg
24190b17f1bSmrg    LockDisplay(dpy);
24290b17f1bSmrg    GetReq(XF86DRIAuthConnection, req);
24390b17f1bSmrg    req->reqType = info->codes->major_opcode;
24490b17f1bSmrg    req->driReqType = X_XF86DRIAuthConnection;
24590b17f1bSmrg    req->screen = screen;
24690b17f1bSmrg    req->magic = magic;
24790b17f1bSmrg    rep.authenticated = 0;
24890b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
24990b17f1bSmrg	UnlockDisplay(dpy);
25090b17f1bSmrg	SyncHandle();
25190b17f1bSmrg	TRACE("AuthConnection... return False");
25290b17f1bSmrg	return False;
25390b17f1bSmrg    }
25490b17f1bSmrg    UnlockDisplay(dpy);
25590b17f1bSmrg    SyncHandle();
25690b17f1bSmrg    TRACE("AuthConnection... return True");
25790b17f1bSmrg    return True;
25890b17f1bSmrg}
25990b17f1bSmrg
26090b17f1bSmrgBool
26190b17f1bSmrguniDRICloseConnection(dpy, screen)
26290b17f1bSmrg    Display *dpy;
26390b17f1bSmrg    int screen;
26490b17f1bSmrg{
26590b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
26690b17f1bSmrg    xXF86DRICloseConnectionReq *req;
26790b17f1bSmrg
26890b17f1bSmrg    TRACE("CloseConnection...");
26990b17f1bSmrg
27090b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
27190b17f1bSmrg
27290b17f1bSmrg    LockDisplay(dpy);
27390b17f1bSmrg    GetReq(XF86DRICloseConnection, req);
27490b17f1bSmrg    req->reqType = info->codes->major_opcode;
27590b17f1bSmrg    req->driReqType = X_XF86DRICloseConnection;
27690b17f1bSmrg    req->screen = screen;
27790b17f1bSmrg    UnlockDisplay(dpy);
27890b17f1bSmrg    SyncHandle();
27990b17f1bSmrg    TRACE("CloseConnection... return True");
28090b17f1bSmrg    return True;
28190b17f1bSmrg}
28290b17f1bSmrg
28390b17f1bSmrgBool
28490b17f1bSmrguniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
28590b17f1bSmrg    ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
28690b17f1bSmrg    Display *dpy;
28790b17f1bSmrg    int screen;
28890b17f1bSmrg    int *ddxDriverMajorVersion;
28990b17f1bSmrg    int *ddxDriverMinorVersion;
29090b17f1bSmrg    int *ddxDriverPatchVersion;
29190b17f1bSmrg    char **clientDriverName;
29290b17f1bSmrg{
29390b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
29490b17f1bSmrg    xXF86DRIGetClientDriverNameReply rep;
29590b17f1bSmrg    xXF86DRIGetClientDriverNameReq *req;
29690b17f1bSmrg
29790b17f1bSmrg    TRACE("GetClientDriverName...");
29890b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
29990b17f1bSmrg
30090b17f1bSmrg    LockDisplay(dpy);
30190b17f1bSmrg    GetReq(XF86DRIGetClientDriverName, req);
30290b17f1bSmrg    req->reqType = info->codes->major_opcode;
30390b17f1bSmrg    req->driReqType = X_XF86DRIGetClientDriverName;
30490b17f1bSmrg    req->screen = screen;
30590b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
30690b17f1bSmrg	UnlockDisplay(dpy);
30790b17f1bSmrg	SyncHandle();
30890b17f1bSmrg	TRACE("GetClientDriverName... return False");
30990b17f1bSmrg	return False;
31090b17f1bSmrg    }
31190b17f1bSmrg
31290b17f1bSmrg    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
31390b17f1bSmrg    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
31490b17f1bSmrg    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
31590b17f1bSmrg
31690b17f1bSmrg    if (rep.length) {
31790b17f1bSmrg	if (rep.clientDriverNameLength < INT_MAX)
31890b17f1bSmrg	    *clientDriverName = Xcalloc(rep.clientDriverNameLength + 1, 1);
31990b17f1bSmrg	else
32090b17f1bSmrg	    *clientDriverName = NULL;
32190b17f1bSmrg	if (*clientDriverName == NULL) {
32290b17f1bSmrg	    _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
32390b17f1bSmrg	    UnlockDisplay(dpy);
32490b17f1bSmrg	    SyncHandle();
32590b17f1bSmrg	    TRACE("GetClientDriverName... return False");
32690b17f1bSmrg	    return False;
32790b17f1bSmrg	}
32890b17f1bSmrg	_XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
32990b17f1bSmrg    } else {
33090b17f1bSmrg	*clientDriverName = NULL;
33190b17f1bSmrg    }
33290b17f1bSmrg    UnlockDisplay(dpy);
33390b17f1bSmrg    SyncHandle();
33490b17f1bSmrg    TRACE("GetClientDriverName... return True");
33590b17f1bSmrg    return True;
33690b17f1bSmrg}
33790b17f1bSmrg
33890b17f1bSmrgBool
33990b17f1bSmrguniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
34090b17f1bSmrg    Display *dpy;
34190b17f1bSmrg    int screen;
34290b17f1bSmrg    int configID;
34390b17f1bSmrg    XID *context;
34490b17f1bSmrg    drm_context_t *hHWContext;
34590b17f1bSmrg{
34690b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
34790b17f1bSmrg    xXF86DRICreateContextReply rep;
34890b17f1bSmrg    xXF86DRICreateContextReq *req;
34990b17f1bSmrg
35090b17f1bSmrg    TRACE("CreateContext...");
35190b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
35290b17f1bSmrg
35390b17f1bSmrg    LockDisplay(dpy);
35490b17f1bSmrg    GetReq(XF86DRICreateContext, req);
35590b17f1bSmrg    req->reqType = info->codes->major_opcode;
35690b17f1bSmrg    req->driReqType = X_XF86DRICreateContext;
35790b17f1bSmrg    req->visual = configID;
35890b17f1bSmrg    req->screen = screen;
35990b17f1bSmrg    *context = XAllocID(dpy);
36090b17f1bSmrg    req->context = *context;
36190b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
36290b17f1bSmrg	UnlockDisplay(dpy);
36390b17f1bSmrg	SyncHandle();
36490b17f1bSmrg	TRACE("CreateContext... return False");
36590b17f1bSmrg	return False;
36690b17f1bSmrg    }
36790b17f1bSmrg    *hHWContext = rep.hHWContext;
36890b17f1bSmrg    UnlockDisplay(dpy);
36990b17f1bSmrg    SyncHandle();
37090b17f1bSmrg    TRACE("CreateContext... return True");
37190b17f1bSmrg    return True;
37290b17f1bSmrg}
37390b17f1bSmrg
37490b17f1bSmrgBool
37590b17f1bSmrguniDRICreateContext(dpy, screen, visual, context, hHWContext)
37690b17f1bSmrg    Display *dpy;
37790b17f1bSmrg    int screen;
37890b17f1bSmrg    Visual *visual;
37990b17f1bSmrg    XID *context;
38090b17f1bSmrg    drm_context_t *hHWContext;
38190b17f1bSmrg{
38290b17f1bSmrg    return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
38390b17f1bSmrg	context, hHWContext);
38490b17f1bSmrg}
38590b17f1bSmrg
38690b17f1bSmrgBool
38790b17f1bSmrguniDRIDestroyContext(Display * ndpy, int screen, XID context)
38890b17f1bSmrg{
38990b17f1bSmrg    Display *const dpy = (Display *) ndpy;
39090b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
39190b17f1bSmrg    xXF86DRIDestroyContextReq *req;
39290b17f1bSmrg
39390b17f1bSmrg    TRACE("DestroyContext...");
39490b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
39590b17f1bSmrg
39690b17f1bSmrg    LockDisplay(dpy);
39790b17f1bSmrg    GetReq(XF86DRIDestroyContext, req);
39890b17f1bSmrg    req->reqType = info->codes->major_opcode;
39990b17f1bSmrg    req->driReqType = X_XF86DRIDestroyContext;
40090b17f1bSmrg    req->screen = screen;
40190b17f1bSmrg    req->context = context;
40290b17f1bSmrg    UnlockDisplay(dpy);
40390b17f1bSmrg    SyncHandle();
40490b17f1bSmrg    TRACE("DestroyContext... return True");
40590b17f1bSmrg    return True;
40690b17f1bSmrg}
40790b17f1bSmrg
40890b17f1bSmrgBool
40990b17f1bSmrguniDRICreateDrawable(Display * ndpy, int screen,
41090b17f1bSmrg    Drawable drawable, drm_drawable_t * hHWDrawable)
41190b17f1bSmrg{
41290b17f1bSmrg    Display *const dpy = (Display *) ndpy;
41390b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
41490b17f1bSmrg    xXF86DRICreateDrawableReply rep;
41590b17f1bSmrg    xXF86DRICreateDrawableReq *req;
41690b17f1bSmrg
41790b17f1bSmrg    TRACE("CreateDrawable...");
41890b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
41990b17f1bSmrg
42090b17f1bSmrg    LockDisplay(dpy);
42190b17f1bSmrg    GetReq(XF86DRICreateDrawable, req);
42290b17f1bSmrg    req->reqType = info->codes->major_opcode;
42390b17f1bSmrg    req->driReqType = X_XF86DRICreateDrawable;
42490b17f1bSmrg    req->screen = screen;
42590b17f1bSmrg    req->drawable = drawable;
42690b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
42790b17f1bSmrg	UnlockDisplay(dpy);
42890b17f1bSmrg	SyncHandle();
42990b17f1bSmrg	TRACE("CreateDrawable... return False");
43090b17f1bSmrg	return False;
43190b17f1bSmrg    }
43290b17f1bSmrg    *hHWDrawable = rep.hHWDrawable;
43390b17f1bSmrg    UnlockDisplay(dpy);
43490b17f1bSmrg    SyncHandle();
43590b17f1bSmrg    TRACE("CreateDrawable... return True");
43690b17f1bSmrg    return True;
43790b17f1bSmrg}
43890b17f1bSmrg
43990b17f1bSmrgBool
44090b17f1bSmrguniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
44190b17f1bSmrg{
44290b17f1bSmrg    Display *const dpy = (Display *) ndpy;
44390b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
44490b17f1bSmrg    xXF86DRIDestroyDrawableReq *req;
44590b17f1bSmrg
44690b17f1bSmrg    TRACE("DestroyDrawable...");
44790b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
44890b17f1bSmrg
44990b17f1bSmrg    LockDisplay(dpy);
45090b17f1bSmrg    GetReq(XF86DRIDestroyDrawable, req);
45190b17f1bSmrg    req->reqType = info->codes->major_opcode;
45290b17f1bSmrg    req->driReqType = X_XF86DRIDestroyDrawable;
45390b17f1bSmrg    req->screen = screen;
45490b17f1bSmrg    req->drawable = drawable;
45590b17f1bSmrg    UnlockDisplay(dpy);
45690b17f1bSmrg    SyncHandle();
45790b17f1bSmrg    TRACE("DestroyDrawable... return True");
45890b17f1bSmrg    return True;
45990b17f1bSmrg}
46090b17f1bSmrg
46190b17f1bSmrgBool
46290b17f1bSmrguniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
46390b17f1bSmrg    unsigned int *index, unsigned int *stamp,
46490b17f1bSmrg    int *X, int *Y, int *W, int *H,
46590b17f1bSmrg    int *numClipRects, drm_clip_rect_t ** pClipRects,
46690b17f1bSmrg    int *backX, int *backY,
46790b17f1bSmrg    int *numBackClipRects, drm_clip_rect_t ** pBackClipRects)
46890b17f1bSmrg{
46990b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
47090b17f1bSmrg    xXF86DRIGetDrawableInfoReply rep;
47190b17f1bSmrg    xXF86DRIGetDrawableInfoReq *req;
47290b17f1bSmrg    int total_rects;
47390b17f1bSmrg
47490b17f1bSmrg    TRACE("GetDrawableInfo...");
47590b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
47690b17f1bSmrg
47790b17f1bSmrg    LockDisplay(dpy);
47890b17f1bSmrg    GetReq(XF86DRIGetDrawableInfo, req);
47990b17f1bSmrg    req->reqType = info->codes->major_opcode;
48090b17f1bSmrg    req->driReqType = X_XF86DRIGetDrawableInfo;
48190b17f1bSmrg    req->screen = screen;
48290b17f1bSmrg    req->drawable = drawable;
48390b17f1bSmrg
48490b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
48590b17f1bSmrg	UnlockDisplay(dpy);
48690b17f1bSmrg	SyncHandle();
48790b17f1bSmrg	TRACE("GetDrawableInfo... return False");
48890b17f1bSmrg	return False;
48990b17f1bSmrg    }
49090b17f1bSmrg    *index = rep.drawableTableIndex;
49190b17f1bSmrg    *stamp = rep.drawableTableStamp;
49290b17f1bSmrg    *X = (int)rep.drawableX;
49390b17f1bSmrg    *Y = (int)rep.drawableY;
49490b17f1bSmrg    *W = (int)rep.drawableWidth;
49590b17f1bSmrg    *H = (int)rep.drawableHeight;
49690b17f1bSmrg    *numClipRects = rep.numClipRects;
49790b17f1bSmrg    total_rects = *numClipRects;
49890b17f1bSmrg
49990b17f1bSmrg    *backX = rep.backX;
50090b17f1bSmrg    *backY = rep.backY;
50190b17f1bSmrg    *numBackClipRects = rep.numBackClipRects;
50290b17f1bSmrg    total_rects += *numBackClipRects;
50390b17f1bSmrg
50490b17f1bSmrg#if 0
50590b17f1bSmrg    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
50690b17f1bSmrg     * backwards compatibility (Because of the >> 2 shift) but the fix
50790b17f1bSmrg     * enables multi-threaded apps to work.
50890b17f1bSmrg     */
50990b17f1bSmrg    if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
51090b17f1bSmrg			SIZEOF(xGenericReply) +
51190b17f1bSmrg			total_rects * sizeof(drm_clip_rect_t)) +
51290b17f1bSmrg		    3) & ~3) >> 2)) {
51390b17f1bSmrg	_XEatData(dpy, rep.length);
51490b17f1bSmrg	UnlockDisplay(dpy);
51590b17f1bSmrg	SyncHandle();
51690b17f1bSmrg	TRACE("GetDrawableInfo... return False");
51790b17f1bSmrg	return False;
51890b17f1bSmrg    }
51990b17f1bSmrg#endif
52090b17f1bSmrg
52190b17f1bSmrg    if (*numClipRects) {
52290b17f1bSmrg	int len = sizeof(drm_clip_rect_t) * (*numClipRects);
52390b17f1bSmrg
52490b17f1bSmrg	*pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
52590b17f1bSmrg	if (*pClipRects)
52690b17f1bSmrg	    _XRead(dpy, (char *)*pClipRects, len);
52790b17f1bSmrg    } else {
52890b17f1bSmrg	*pClipRects = NULL;
52990b17f1bSmrg    }
53090b17f1bSmrg
53190b17f1bSmrg    if (*numBackClipRects) {
53290b17f1bSmrg	int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
53390b17f1bSmrg
53490b17f1bSmrg	*pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
53590b17f1bSmrg	if (*pBackClipRects)
53690b17f1bSmrg	    _XRead(dpy, (char *)*pBackClipRects, len);
53790b17f1bSmrg    } else {
53890b17f1bSmrg	*pBackClipRects = NULL;
53990b17f1bSmrg    }
54090b17f1bSmrg
54190b17f1bSmrg    UnlockDisplay(dpy);
54290b17f1bSmrg    SyncHandle();
54390b17f1bSmrg    TRACE("GetDrawableInfo... return True");
54490b17f1bSmrg    return True;
54590b17f1bSmrg}
54690b17f1bSmrg
54790b17f1bSmrgBool
54890b17f1bSmrguniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
54990b17f1bSmrg    fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
55090b17f1bSmrg    Display *dpy;
55190b17f1bSmrg    int screen;
55290b17f1bSmrg    drm_handle_t *hFrameBuffer;
55390b17f1bSmrg    int *fbOrigin;
55490b17f1bSmrg    int *fbSize;
55590b17f1bSmrg    int *fbStride;
55690b17f1bSmrg    int *devPrivateSize;
55790b17f1bSmrg    void **pDevPrivate;
55890b17f1bSmrg{
55990b17f1bSmrg    XExtDisplayInfo *info = find_display(dpy);
56090b17f1bSmrg    xXF86DRIGetDeviceInfoReply rep;
56190b17f1bSmrg    xXF86DRIGetDeviceInfoReq *req;
56290b17f1bSmrg
56390b17f1bSmrg    TRACE("GetDeviceInfo...");
56490b17f1bSmrg    uniDRICheckExtension(dpy, info, False);
56590b17f1bSmrg
56690b17f1bSmrg    LockDisplay(dpy);
56790b17f1bSmrg    GetReq(XF86DRIGetDeviceInfo, req);
56890b17f1bSmrg    req->reqType = info->codes->major_opcode;
56990b17f1bSmrg    req->driReqType = X_XF86DRIGetDeviceInfo;
57090b17f1bSmrg    req->screen = screen;
57190b17f1bSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
57290b17f1bSmrg	UnlockDisplay(dpy);
57390b17f1bSmrg	SyncHandle();
57490b17f1bSmrg	TRACE("GetDeviceInfo... return False");
57590b17f1bSmrg	return False;
57690b17f1bSmrg    }
57790b17f1bSmrg
57890b17f1bSmrg    *hFrameBuffer = rep.hFrameBufferLow;
57990b17f1bSmrg#ifdef LONG64
58090b17f1bSmrg    if (sizeof(drm_handle_t) == 8) {
58190b17f1bSmrg	*hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
58290b17f1bSmrg    }
58390b17f1bSmrg#endif
58490b17f1bSmrg
58590b17f1bSmrg    *fbOrigin = rep.framebufferOrigin;
58690b17f1bSmrg    *fbSize = rep.framebufferSize;
58790b17f1bSmrg    *fbStride = rep.framebufferStride;
58890b17f1bSmrg    *devPrivateSize = rep.devPrivateSize;
58990b17f1bSmrg
59090b17f1bSmrg    if (rep.length) {
59190b17f1bSmrg	if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
59290b17f1bSmrg	    _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
59390b17f1bSmrg	    UnlockDisplay(dpy);
59490b17f1bSmrg	    SyncHandle();
59590b17f1bSmrg	    TRACE("GetDeviceInfo... return False");
59690b17f1bSmrg	    return False;
59790b17f1bSmrg	}
59890b17f1bSmrg	_XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
59990b17f1bSmrg    } else {
60090b17f1bSmrg	*pDevPrivate = NULL;
60190b17f1bSmrg    }
60290b17f1bSmrg
60390b17f1bSmrg    UnlockDisplay(dpy);
60490b17f1bSmrg    SyncHandle();
60590b17f1bSmrg    TRACE("GetDeviceInfo... return True");
60690b17f1bSmrg    return True;
60790b17f1bSmrg}
608