summaryrefslogtreecommitdiff
path: root/bsd-core/drm_bufs.c
AgeCommit message (Expand)Author
2007-08-15Fix dev->agp->base initialization on BSD, and fix addmap range check on Linux.Eric Anholt
2007-08-15BSD: Replace brief description in each file's first line with doxygen later on.Eric Anholt
2007-07-20Replace DRM_IOCTL_ARGS with (dev, data, file_priv) and remove DRM_DEVICE.Eric Anholt
2007-07-20Replace filp in ioctl arguments with drm_file *file_priv.Eric Anholt
2007-07-20Remove DRM_ERR OS macro.Eric Anholt
2006-12-01Core build fix for BSD.Michel Dänzer
2005-11-08Correct another LOR issue with resource allocation. This leaves theEric Anholt
2005-11-08Initial port of savage to FreeBSD for the AGP and !ShadowStatus case. AddsEric Anholt
2005-11-08Correct a LOR related to the PCI resource allocations by simply moving theEric Anholt
2005-11-08Correct a recursion on non-recursive mutex in drm_addmap from radeon'sEric Anholt
2005-08-26- Don't try to allocate mappings of less than a PAGE_SIZE in MGA DMA code.Eric Anholt
2005-08-26Previously, drm_get_resource_start() and drm_get_resource_len() wouldEric Anholt
2005-08-26[1] Fix BSD DRM for the nonroot changes. [2] Don't attempt to acquire theEric Anholt
2005-08-05Rename the driver hooks in the DRM to something a little moreEric Anholt
2005-06-29Get the BSD DRM compiling again after MGA and mapping changes. Note thatEric Anholt
2005-06-06Add a few more bits of Tonnerre's NetBSD port (Still need to deal with theEric Anholt
2005-04-26Convert BSD code to mostly use bus_dma, the dma abstraction for dealingEric Anholt
2005-04-24Fix a panic on startup with non-initmapping drivers by assigning theEric Anholt
2005-04-16Use /*- to begin license blocks in BSD code to reduce diffs against FreeBSDEric Anholt
2005-04-13Fix build on FreeBSD-current, thanks to jhb@.Eric Anholt
2005-02-07Restore a debugging message to DRM_DEBUG instead of DRM_ERROR.Eric Anholt
2005-02-05- Implement drm_initmap, and extend it with the resource number to helpEric Anholt
2004-11-07Now that the memory debug code is gone, and all 3 BSDs have M_ZERO, stopEric Anholt
2004-11-06Commit first pieces of port to OpenBSD, done by Martin Lexa (martin atEric Anholt
2004-11-06Commit WIP of BSD conversion to core model. Compiles for r128, radeon, butEric Anholt
2004-08-17Merged drmfntbl-0-0-1Dave Airlie
2004-05-09Warning fixes.Eric Anholt
2004-01-06Fix some misuse of NULL where 0 is intended.Eric Anholt
2003-12-16Don't ioremap the framebuffer area. The ioremapped area wasn't used byEric Anholt
2003-11-12Fix a locking nit, and add asserts in some things that should be calledEric Anholt
2003-11-06Return EBUSY when attempting to addmap a DRM_SHM area with a lock in it ifEric Anholt
2003-10-20Clean up BSD MTRR handling. The NetBSD code is untested, but it's my bestEric Anholt
2003-10-19- SMPng lock the DRM. This is only partial -- there are a few code pathsEric Anholt
2003-10-03Some code cleanups done while working on locking. Reduces always-trueEric Anholt
2003-10-03Stylistic preparation for SMPng locking work: DRM_LOCK/DRM_UNLOCK have sideEric Anholt
2003-10-02Mostly whitespace cleanups and style(9) fixes focused on "if(" -> "if ("Eric Anholt
2003-08-19Fix the debug build.Eric Anholt
2003-08-19- Remove $FreeBSD$ tags as they weren't too useful and merges are now beingEric Anholt
2003-05-16Support AGP bridges where the AGP aperture can't be accessed directly byMichel Daenzer
2003-04-26Add PCI DMA memory functions and make addbufs_pci and associated code useEric Anholt
2003-04-25Merge from FreeBSD-current.Eric Anholt
2003-04-25Clean up the DRM_COPY_TO_USER()ing of DRM(infobufs), making it moreEric Anholt
2003-04-24Remove more gamma DMA infrastructure. Most of this code was copied straightEric Anholt
2003-04-24Move some common code from addbufs_<type> to addbufs. Make buf_alloc beEric Anholt
2003-04-24Remove DRM_DMA_HISTOGRAM and associated code.Eric Anholt
2003-03-29Add DRMFILE definitions and supply filp for BSD in theEric Anholt
2003-03-11Merge back from FreeBSD-current, adding FreeBSD ID tags to aid futureEric Anholt
2003-02-21Merge from bsd-4-0-0-branch.Eric Anholt
2002-09-29Remove some noise being spit to the console.Eric Anholt
2002-07-05merged bsd-3-0-0-branchAlan Hourihane
ef='#n402'>402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
/**************************************************************************

Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

**************************************************************************/

/*
 * Authors:
 *   Kevin E. Martin <martin@valinux.com>
 *   Jens Owen <jens@tungstengraphics.com>
 *   Rickard E. (Rik) Faith <faith@valinux.com>
 *
 */

/* THIS IS NOT AN X CONSORTIUM STANDARD */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define NEED_REPLIES
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include "xf86dristr.h"

static XExtensionInfo _xf86dri_info_data;
static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
static char xf86dri_extension_name[] = XF86DRINAME;

#define uniDRICheckExtension(dpy,i,val) \
  XextCheckExtension (dpy, i, xf86dri_extension_name, val)

/*****************************************************************************
 *                                                                           *
 *			   private utility routines                          *
 *                                                                           *
 *****************************************************************************/

static int close_display(Display * dpy, XExtCodes * extCodes);
static /* const */ XExtensionHooks xf86dri_extension_hooks = {
    NULL,			       /* create_gc */
    NULL,			       /* copy_gc */
    NULL,			       /* flush_gc */
    NULL,			       /* free_gc */
    NULL,			       /* create_font */
    NULL,			       /* free_font */
    close_display,		       /* close_display */
    NULL,			       /* wire_to_event */
    NULL,			       /* event_to_wire */
    NULL,			       /* error */
    NULL,			       /* error_string */
};

static
XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
    xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL)

    static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)

/*****************************************************************************
 *                                                                           *
 *		    public XFree86-DRI Extension routines                    *
 *                                                                           *
 *****************************************************************************/
#if 0
#include <stdio.h>
#define TRACE(msg)  fprintf(stderr,"uniDRI%s\n", msg);
#else
#define TRACE(msg)
#endif
    Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
    Display *dpy;
    int *event_basep, *error_basep;
{
    XExtDisplayInfo *info = find_display(dpy);

    TRACE("QueryExtension...");
    if (XextHasExtension(info)) {
	*event_basep = info->codes->first_event;
	*error_basep = info->codes->first_error;
	TRACE("QueryExtension... return True");
	return True;
    } else {
	TRACE("QueryExtension... return False");
	return False;
    }
}

Bool
uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
    Display *dpy;
    int *majorVersion;
    int *minorVersion;
    int *patchVersion;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIQueryVersionReply rep;
    xXF86DRIQueryVersionReq *req;

    TRACE("QueryVersion...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIQueryVersion, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIQueryVersion;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("QueryVersion... return False");
	return False;
    }
    *majorVersion = rep.majorVersion;
    *minorVersion = rep.minorVersion;
    *patchVersion = rep.patchVersion;
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("QueryVersion... return True");
    return True;
}

Bool
uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
    Display *dpy;
    int screen;
    Bool *isCapable;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIQueryDirectRenderingCapableReply rep;
    xXF86DRIQueryDirectRenderingCapableReq *req;

    TRACE("QueryDirectRenderingCapable...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIQueryDirectRenderingCapable, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
    req->screen = screen;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("QueryDirectRenderingCapable... return False");
	return False;
    }
    *isCapable = rep.isCapable;
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("QueryDirectRenderingCapable... return True");
    return True;
}

Bool
uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
    Display *dpy;
    int screen;
    drm_handle_t *hSAREA;
    char **busIdString;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIOpenConnectionReply rep;
    xXF86DRIOpenConnectionReq *req;

    TRACE("OpenConnection...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIOpenConnection, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIOpenConnection;
    req->screen = screen;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("OpenConnection... return False");
	return False;
    }

    *hSAREA = rep.hSAREALow;
#ifdef LONG64
    if (sizeof(drm_handle_t) == 8) {
	*hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
    }
#endif
    if (rep.length) {
	if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
	    _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
	    UnlockDisplay(dpy);
	    SyncHandle();
	    TRACE("OpenConnection... return False");
	    return False;
	}
	_XReadPad(dpy, *busIdString, rep.busIdStringLength);
    } else {
	*busIdString = NULL;
    }
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("OpenConnection... return True");
    return True;
}

Bool
uniDRIAuthConnection(dpy, screen, magic)
    Display *dpy;
    int screen;
    drm_magic_t magic;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIAuthConnectionReq *req;
    xXF86DRIAuthConnectionReply rep;

    TRACE("AuthConnection...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIAuthConnection, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIAuthConnection;
    req->screen = screen;
    req->magic = magic;
    rep.authenticated = 0;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("AuthConnection... return False");
	return False;
    }
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("AuthConnection... return True");
    return True;
}

Bool
uniDRICloseConnection(dpy, screen)
    Display *dpy;
    int screen;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRICloseConnectionReq *req;

    TRACE("CloseConnection...");

    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRICloseConnection, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRICloseConnection;
    req->screen = screen;
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("CloseConnection... return True");
    return True;
}

Bool
uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
    ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
    Display *dpy;
    int screen;
    int *ddxDriverMajorVersion;
    int *ddxDriverMinorVersion;
    int *ddxDriverPatchVersion;
    char **clientDriverName;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIGetClientDriverNameReply rep;
    xXF86DRIGetClientDriverNameReq *req;

    TRACE("GetClientDriverName...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIGetClientDriverName, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIGetClientDriverName;
    req->screen = screen;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("GetClientDriverName... return False");
	return False;
    }

    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;

    if (rep.length) {
	if (!(*clientDriverName =
		(char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
	    _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
	    UnlockDisplay(dpy);
	    SyncHandle();
	    TRACE("GetClientDriverName... return False");
	    return False;
	}
	_XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
    } else {
	*clientDriverName = NULL;
    }
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("GetClientDriverName... return True");
    return True;
}

Bool
uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
    Display *dpy;
    int screen;
    int configID;
    XID *context;
    drm_context_t *hHWContext;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRICreateContextReply rep;
    xXF86DRICreateContextReq *req;

    TRACE("CreateContext...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRICreateContext, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRICreateContext;
    req->visual = configID;
    req->screen = screen;
    *context = XAllocID(dpy);
    req->context = *context;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("CreateContext... return False");
	return False;
    }
    *hHWContext = rep.hHWContext;
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("CreateContext... return True");
    return True;
}

Bool
uniDRICreateContext(dpy, screen, visual, context, hHWContext)
    Display *dpy;
    int screen;
    Visual *visual;
    XID *context;
    drm_context_t *hHWContext;
{
    return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
	context, hHWContext);
}

Bool
uniDRIDestroyContext(Display * ndpy, int screen, XID context)
{
    Display *const dpy = (Display *) ndpy;
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIDestroyContextReq *req;

    TRACE("DestroyContext...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIDestroyContext, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIDestroyContext;
    req->screen = screen;
    req->context = context;
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("DestroyContext... return True");
    return True;
}

Bool
uniDRICreateDrawable(Display * ndpy, int screen,
    Drawable drawable, drm_drawable_t * hHWDrawable)
{
    Display *const dpy = (Display *) ndpy;
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRICreateDrawableReply rep;
    xXF86DRICreateDrawableReq *req;

    TRACE("CreateDrawable...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRICreateDrawable, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRICreateDrawable;
    req->screen = screen;
    req->drawable = drawable;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("CreateDrawable... return False");
	return False;
    }
    *hHWDrawable = rep.hHWDrawable;
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("CreateDrawable... return True");
    return True;
}

Bool
uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
{
    Display *const dpy = (Display *) ndpy;
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIDestroyDrawableReq *req;

    TRACE("DestroyDrawable...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIDestroyDrawable, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIDestroyDrawable;
    req->screen = screen;
    req->drawable = drawable;
    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("DestroyDrawable... return True");
    return True;
}

Bool
uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
    unsigned int *index, unsigned int *stamp,
    int *X, int *Y, int *W, int *H,
    int *numClipRects, drm_clip_rect_t ** pClipRects,
    int *backX, int *backY,
    int *numBackClipRects, drm_clip_rect_t ** pBackClipRects)
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIGetDrawableInfoReply rep;
    xXF86DRIGetDrawableInfoReq *req;
    int total_rects;

    TRACE("GetDrawableInfo...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIGetDrawableInfo, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIGetDrawableInfo;
    req->screen = screen;
    req->drawable = drawable;

    if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("GetDrawableInfo... return False");
	return False;
    }
    *index = rep.drawableTableIndex;
    *stamp = rep.drawableTableStamp;
    *X = (int)rep.drawableX;
    *Y = (int)rep.drawableY;
    *W = (int)rep.drawableWidth;
    *H = (int)rep.drawableHeight;
    *numClipRects = rep.numClipRects;
    total_rects = *numClipRects;

    *backX = rep.backX;
    *backY = rep.backY;
    *numBackClipRects = rep.numBackClipRects;
    total_rects += *numBackClipRects;

#if 0
    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
     * backwards compatibility (Because of the >> 2 shift) but the fix
     * enables multi-threaded apps to work.
     */
    if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
			SIZEOF(xGenericReply) +
			total_rects * sizeof(drm_clip_rect_t)) +
		    3) & ~3) >> 2)) {
	_XEatData(dpy, rep.length);
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("GetDrawableInfo... return False");
	return False;
    }
#endif

    if (*numClipRects) {
	int len = sizeof(drm_clip_rect_t) * (*numClipRects);

	*pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
	if (*pClipRects)
	    _XRead(dpy, (char *)*pClipRects, len);
    } else {
	*pClipRects = NULL;
    }

    if (*numBackClipRects) {
	int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);

	*pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
	if (*pBackClipRects)
	    _XRead(dpy, (char *)*pBackClipRects, len);
    } else {
	*pBackClipRects = NULL;
    }

    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("GetDrawableInfo... return True");
    return True;
}

Bool
uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
    fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
    Display *dpy;
    int screen;
    drm_handle_t *hFrameBuffer;
    int *fbOrigin;
    int *fbSize;
    int *fbStride;
    int *devPrivateSize;
    void **pDevPrivate;
{
    XExtDisplayInfo *info = find_display(dpy);
    xXF86DRIGetDeviceInfoReply rep;
    xXF86DRIGetDeviceInfoReq *req;

    TRACE("GetDeviceInfo...");
    uniDRICheckExtension(dpy, info, False);

    LockDisplay(dpy);
    GetReq(XF86DRIGetDeviceInfo, req);
    req->reqType = info->codes->major_opcode;
    req->driReqType = X_XF86DRIGetDeviceInfo;
    req->screen = screen;
    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
	UnlockDisplay(dpy);
	SyncHandle();
	TRACE("GetDeviceInfo... return False");
	return False;
    }

    *hFrameBuffer = rep.hFrameBufferLow;
#ifdef LONG64
    if (sizeof(drm_handle_t) == 8) {
	*hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
    }
#endif

    *fbOrigin = rep.framebufferOrigin;
    *fbSize = rep.framebufferSize;
    *fbStride = rep.framebufferStride;
    *devPrivateSize = rep.devPrivateSize;

    if (rep.length) {
	if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
	    _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
	    UnlockDisplay(dpy);
	    SyncHandle();
	    TRACE("GetDeviceInfo... return False");
	    return False;
	}
	_XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
    } else {
	*pDevPrivate = NULL;
    }

    UnlockDisplay(dpy);
    SyncHandle();
    TRACE("GetDeviceInfo... return True");
    return True;
}