726 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			726 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Xephyr - A kdrive X server thats runs in a host X window.
 | 
						|
 *          Authored by Matthew Allum <mallum@openedhand.com>
 | 
						|
 * 
 | 
						|
 * Copyright © 2007 OpenedHand Ltd 
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of OpenedHand Ltd not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission. OpenedHand Ltd makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 *
 | 
						|
 * This file is heavily copied from hw/xfree86/dri/xf86dri.c
 | 
						|
 *
 | 
						|
 * Authors:
 | 
						|
 *    Dodji Seketeli <dodji@openedhand.com>
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <kdrive-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef XEPHYR_DRI
 | 
						|
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#define NEED_REPLIES
 | 
						|
#define NEED_EVENTS
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/Xproto.h>
 | 
						|
#define _XF86DRI_SERVER_
 | 
						|
#include <X11/dri/xf86dri.h>
 | 
						|
#include <X11/dri/xf86dristr.h>
 | 
						|
#include "misc.h"
 | 
						|
#include "dixstruct.h"
 | 
						|
#include "extnsionst.h"
 | 
						|
#include "colormapst.h"
 | 
						|
#include "cursorstr.h"
 | 
						|
#include "scrnintstr.h"
 | 
						|
#include "servermd.h"
 | 
						|
#include "swaprep.h"
 | 
						|
#include "ephyrdri.h"
 | 
						|
#define _HAVE_XALLOC_DECLS
 | 
						|
#include "ephyrlog.h"
 | 
						|
 | 
						|
static int DRIErrorBase;
 | 
						|
 | 
						|
static DISPATCH_PROC(ProcXF86DRIQueryVersion);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIOpenConnection);
 | 
						|
static DISPATCH_PROC(ProcXF86DRICloseConnection);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
 | 
						|
static DISPATCH_PROC(ProcXF86DRICreateContext);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIDestroyContext);
 | 
						|
static DISPATCH_PROC(ProcXF86DRICreateDrawable);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIDispatch);
 | 
						|
static DISPATCH_PROC(ProcXF86DRIAuthConnection);
 | 
						|
 | 
						|
static DISPATCH_PROC(SProcXF86DRIQueryVersion);
 | 
						|
static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
 | 
						|
static DISPATCH_PROC(SProcXF86DRIDispatch);
 | 
						|
 | 
						|
static void XF86DRIResetProc(ExtensionEntry* extEntry);
 | 
						|
 | 
						|
static unsigned char DRIReqCode = 0;
 | 
						|
 | 
						|
extern void ephyrDRIExtensionInit(void);
 | 
						|
 | 
						|
void
 | 
						|
ephyrDRIExtensionInit(void)
 | 
						|
{
 | 
						|
    ExtensionEntry* extEntry;
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
 | 
						|
#ifdef XF86DRI_EVENTS
 | 
						|
    EventType = CreateNewResourceType(XF86DRIFreeEvents);
 | 
						|
#endif
 | 
						|
 | 
						|
    if ((extEntry = AddExtension(XF86DRINAME,
 | 
						|
				 XF86DRINumberEvents,
 | 
						|
				 XF86DRINumberErrors,
 | 
						|
				 ProcXF86DRIDispatch,
 | 
						|
				 SProcXF86DRIDispatch,
 | 
						|
				 XF86DRIResetProc,
 | 
						|
				 StandardMinorOpcode))) {
 | 
						|
	DRIReqCode = (unsigned char)extEntry->base;
 | 
						|
	DRIErrorBase = extEntry->errorBase;
 | 
						|
    }
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static void
 | 
						|
XF86DRIResetProc (
 | 
						|
    ExtensionEntry* extEntry
 | 
						|
)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIQueryVersion (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRIQueryVersionReply rep;
 | 
						|
    register int n;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.majorVersion = XF86DRI_MAJOR_VERSION;
 | 
						|
    rep.minorVersion = XF86DRI_MINOR_VERSION;
 | 
						|
    rep.patchVersion = XF86DRI_PATCH_VERSION;
 | 
						|
    if (client->swapped) {
 | 
						|
    	swaps(&rep.sequenceNumber, n);
 | 
						|
    	swapl(&rep.length, n);
 | 
						|
	swaps(&rep.majorVersion, n);
 | 
						|
	swaps(&rep.minorVersion, n);
 | 
						|
	swapl(&rep.patchVersion, n);
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRIQueryDirectRenderingCapableReply	rep;
 | 
						|
    Bool isCapable;
 | 
						|
    register int n;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
	client->errorValue = stuff->screen;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
 | 
						|
    if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    rep.isCapable = isCapable;
 | 
						|
 | 
						|
    if (!LocalClient(client) || client->swapped)
 | 
						|
	rep.isCapable = 0;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
    	swaps(&rep.sequenceNumber, n);
 | 
						|
    	swapl(&rep.length, n);
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIOpenConnection (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRIOpenConnectionReply rep;
 | 
						|
    drm_handle_t			hSAREA;
 | 
						|
    char*			busIdString;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRIOpenConnectionReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
	client->errorValue = stuff->screen;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!ephyrDRIOpenConnection(stuff->screen,
 | 
						|
                                &hSAREA,
 | 
						|
                                &busIdString)) {
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.busIdStringLength = 0;
 | 
						|
    if (busIdString)
 | 
						|
	rep.busIdStringLength = strlen(busIdString);
 | 
						|
    rep.length = (SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
 | 
						|
                  ((rep.busIdStringLength + 3) & ~3)) >> 2;
 | 
						|
 | 
						|
    rep.hSAREALow  = (CARD32)(hSAREA & 0xffffffff);
 | 
						|
#if defined(LONG64) && !defined(__linux__)
 | 
						|
    rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
 | 
						|
#else
 | 
						|
    rep.hSAREAHigh = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
 | 
						|
    if (rep.busIdStringLength)
 | 
						|
        WriteToClient(client, rep.busIdStringLength, busIdString);
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIAuthConnection  (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRIAuthConnectionReply rep;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRIAuthConnectionReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
	client->errorValue = stuff->screen;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.authenticated = 1;
 | 
						|
 | 
						|
    if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
 | 
						|
        ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
 | 
						|
        rep.authenticated = 0;
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRICloseConnection (register ClientPtr client)
 | 
						|
{
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRICloseConnectionReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
        client->errorValue = stuff->screen;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    DRICloseConnection( screenInfo.screens[stuff->screen]);
 | 
						|
    */
 | 
						|
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIGetClientDriverName (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRIGetClientDriverNameReply	rep;
 | 
						|
    char* clientDriverName;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRIGetClientDriverNameReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
	client->errorValue = stuff->screen;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    ephyrDRIGetClientDriverName (stuff->screen,
 | 
						|
                                 (int *)&rep.ddxDriverMajorVersion,
 | 
						|
                                 (int *)&rep.ddxDriverMinorVersion,
 | 
						|
                                 (int *)&rep.ddxDriverPatchVersion,
 | 
						|
                                 &clientDriverName);
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.clientDriverNameLength = 0;
 | 
						|
    if (clientDriverName)
 | 
						|
	rep.clientDriverNameLength = strlen(clientDriverName);
 | 
						|
    rep.length = (SIZEOF(xXF86DRIGetClientDriverNameReply) - 
 | 
						|
			SIZEOF(xGenericReply) +
 | 
						|
			((rep.clientDriverNameLength + 3) & ~3)) >> 2;
 | 
						|
 | 
						|
    WriteToClient(client, 
 | 
						|
	sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
 | 
						|
    if (rep.clientDriverNameLength)
 | 
						|
	WriteToClient(client, 
 | 
						|
                      rep.clientDriverNameLength, 
 | 
						|
                      clientDriverName);
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRICreateContext (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRICreateContextReply	rep;
 | 
						|
    ScreenPtr pScreen;
 | 
						|
    VisualPtr visual;
 | 
						|
    int i;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRICreateContextReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
	client->errorValue = stuff->screen;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
 | 
						|
    pScreen = screenInfo.screens[stuff->screen];
 | 
						|
    visual = pScreen->visuals;
 | 
						|
 | 
						|
    /* Find the requested X visual */
 | 
						|
    for (i = 0; i < pScreen->numVisuals; i++, visual++)
 | 
						|
	if (visual->vid == stuff->visual)
 | 
						|
	    break;
 | 
						|
    if (i == pScreen->numVisuals) {
 | 
						|
	/* No visual found */
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    if (!DRICreateContext( pScreen,
 | 
						|
			   visual,
 | 
						|
			   stuff->context,
 | 
						|
			   (drm_context_t *)&rep.hHWContext)) {
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
    */
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIDestroyContext (register ClientPtr client)
 | 
						|
{
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
 | 
						|
    REQUEST(xXF86DRIDestroyContextReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
        client->errorValue = stuff->screen;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
       if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
 | 
						|
       stuff->context)) {
 | 
						|
       return BadValue;
 | 
						|
       }
 | 
						|
   */
 | 
						|
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRICreateDrawable (ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRICreateDrawableReply	rep;
 | 
						|
    DrawablePtr pDrawable;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRICreateDrawableReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
        client->errorValue = stuff->screen;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
 | 
						|
    rc = dixLookupDrawable (&pDrawable, stuff->drawable, client, 0,
 | 
						|
                            DixReadAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    /*TODO: this cannot work. We must properly
 | 
						|
     * do the mapping between the xephyr drawable and
 | 
						|
     * the host drawable
 | 
						|
     */
 | 
						|
    if (!ephyrDRICreateDrawable (stuff->screen,
 | 
						|
                0/*should be host drawableID*/,
 | 
						|
                (drm_drawable_t *)&rep.hHWDrawable)) {
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIDestroyDrawable (register ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xXF86DRIDestroyDrawableReq);
 | 
						|
    DrawablePtr pDrawable;
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
        client->errorValue = stuff->screen;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rc = dixLookupDrawable(&pDrawable,
 | 
						|
                           stuff->drawable,
 | 
						|
                           client,
 | 
						|
                           0,
 | 
						|
                           DixReadAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    if (!ephyrDRIDestroyDrawable(stuff->screen,
 | 
						|
                                 0/*should be drawable in host x*/)) {
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIGetDrawableInfo (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRIGetDrawableInfoReply	rep;
 | 
						|
    DrawablePtr drawable;
 | 
						|
    int X, Y, W, H, backX, backY, rc;
 | 
						|
    drm_clip_rect_t * pClipRects, *pClippedRects;
 | 
						|
    drm_clip_rect_t * pBackClipRects;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRIGetDrawableInfoReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
        client->errorValue = stuff->screen;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
 | 
						|
    /*TODO: this cannot work.
 | 
						|
     * We must properly do the mapping
 | 
						|
     * between xephyr drawable and the host drawable
 | 
						|
     */
 | 
						|
    rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
 | 
						|
                           DixReadAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    if (!ephyrDRIGetDrawableInfo (stuff->screen,
 | 
						|
                                  drawable/*should be the drawable in hostx*/,
 | 
						|
                                  (unsigned int*)&rep.drawableTableIndex,
 | 
						|
                                  (unsigned int*)&rep.drawableTableStamp,
 | 
						|
                                  (int*)&X,
 | 
						|
                                  (int*)&Y,
 | 
						|
                                  (int*)&W,
 | 
						|
                                  (int*)&H,
 | 
						|
                                  (int*)&rep.numClipRects,
 | 
						|
                                  &pClipRects,
 | 
						|
                                  &backX,
 | 
						|
                                  &backY,
 | 
						|
                                  (int*)&rep.numBackClipRects,
 | 
						|
                                  &pBackClipRects)) {
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.drawableX = X;
 | 
						|
    rep.drawableY = Y;
 | 
						|
    rep.drawableWidth = W;
 | 
						|
    rep.drawableHeight = H;
 | 
						|
    rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - 
 | 
						|
                  SIZEOF(xGenericReply));
 | 
						|
 | 
						|
    rep.backX = backX;
 | 
						|
    rep.backY = backY;
 | 
						|
 | 
						|
    if (rep.numBackClipRects) 
 | 
						|
        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;    
 | 
						|
 | 
						|
    pClippedRects = pClipRects;
 | 
						|
 | 
						|
    if (rep.numClipRects) {
 | 
						|
        /* Clip cliprects to screen dimensions (redirected windows) */
 | 
						|
        pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
 | 
						|
 | 
						|
        if (pClippedRects) {
 | 
						|
            ScreenPtr pScreen = screenInfo.screens[stuff->screen];
 | 
						|
            int i, j;
 | 
						|
 | 
						|
            for (i = 0, j = 0; i < rep.numClipRects; i++) {
 | 
						|
                pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
 | 
						|
                pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
 | 
						|
                pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
 | 
						|
                pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
 | 
						|
 | 
						|
                if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
 | 
						|
                        pClippedRects[j].y1 < pClippedRects[j].y2) {
 | 
						|
                    j++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            rep.numClipRects = j;
 | 
						|
        } else {
 | 
						|
            rep.numClipRects = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.length = ((rep.length + 3) & ~3) >> 2;
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
 | 
						|
 | 
						|
    if (rep.numClipRects) {
 | 
						|
        WriteToClient(client,  
 | 
						|
                sizeof(drm_clip_rect_t) * rep.numClipRects,
 | 
						|
                (char *)pClippedRects);
 | 
						|
        xfree(pClippedRects);
 | 
						|
    }
 | 
						|
 | 
						|
    if (rep.numBackClipRects) {
 | 
						|
        WriteToClient(client, 
 | 
						|
                sizeof(drm_clip_rect_t) * rep.numBackClipRects,
 | 
						|
                (char *)pBackClipRects);
 | 
						|
    }
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIGetDeviceInfo (register ClientPtr client)
 | 
						|
{
 | 
						|
    xXF86DRIGetDeviceInfoReply	rep;
 | 
						|
    drm_handle_t hFrameBuffer;
 | 
						|
    void *pDevPrivate;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    REQUEST(xXF86DRIGetDeviceInfoReq);
 | 
						|
    REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
 | 
						|
    if (stuff->screen >= screenInfo.numScreens) {
 | 
						|
        client->errorValue = stuff->screen;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
 | 
						|
    if (!ephyrDRIGetDeviceInfo (stuff->screen,
 | 
						|
                &hFrameBuffer,
 | 
						|
                (int*)&rep.framebufferOrigin,
 | 
						|
                (int*)&rep.framebufferSize,
 | 
						|
                (int*)&rep.framebufferStride,
 | 
						|
                (int*)&rep.devPrivateSize,
 | 
						|
                &pDevPrivate)) {
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rep.hFrameBufferLow  = (CARD32)(hFrameBuffer & 0xffffffff);
 | 
						|
#if defined(LONG64) && !defined(__linux__)
 | 
						|
    rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
 | 
						|
#else
 | 
						|
    rep.hFrameBufferHigh = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
    rep.length = 0;
 | 
						|
    if (rep.devPrivateSize) {
 | 
						|
        rep.length = (SIZEOF(xXF86DRIGetDeviceInfoReply) - 
 | 
						|
                SIZEOF(xGenericReply) +
 | 
						|
                ((rep.devPrivateSize + 3) & ~3)) >> 2;
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
 | 
						|
    if (rep.length) {
 | 
						|
        WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
 | 
						|
    }
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ProcXF86DRIDispatch (register ClientPtr	client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
 | 
						|
    switch (stuff->data)
 | 
						|
    {
 | 
						|
        case X_XF86DRIQueryVersion: {
 | 
						|
                EPHYR_LOG ("leave\n") ;
 | 
						|
                return ProcXF86DRIQueryVersion(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIQueryDirectRenderingCapable: {
 | 
						|
                EPHYR_LOG ("leave\n") ;
 | 
						|
                return ProcXF86DRIQueryDirectRenderingCapable(client);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!LocalClient(client))
 | 
						|
        return DRIErrorBase + XF86DRIClientNotLocal;
 | 
						|
 | 
						|
    switch (stuff->data)
 | 
						|
    {
 | 
						|
        case X_XF86DRIOpenConnection: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRIOpenConnection(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRICloseConnection: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRICloseConnection(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIGetClientDriverName: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRIGetClientDriverName(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRICreateContext: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRICreateContext(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIDestroyContext: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRIDestroyContext(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRICreateDrawable: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRICreateDrawable(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIDestroyDrawable: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRIDestroyDrawable(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIGetDrawableInfo: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRIGetDrawableInfo(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIGetDeviceInfo: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRIGetDeviceInfo(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIAuthConnection: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return ProcXF86DRIAuthConnection(client);
 | 
						|
        }
 | 
						|
            /* {Open,Close}FullScreen are deprecated now */
 | 
						|
        default: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return BadRequest;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcXF86DRIQueryVersion (register ClientPtr	client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST(xXF86DRIQueryVersionReq);
 | 
						|
    swaps(&stuff->length, n);
 | 
						|
    return ProcXF86DRIQueryVersion(client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
 | 
						|
{
 | 
						|
    register int n;
 | 
						|
    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
 | 
						|
    swaps(&stuff->length, n);
 | 
						|
    swapl(&stuff->screen, n);
 | 
						|
    return ProcXF86DRIQueryDirectRenderingCapable(client);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SProcXF86DRIDispatch (register ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
    /*
 | 
						|
     * Only local clients are allowed DRI access, but remote clients still need
 | 
						|
     * these requests to find out cleanly.
 | 
						|
     */
 | 
						|
    switch (stuff->data)
 | 
						|
    {
 | 
						|
        case X_XF86DRIQueryVersion: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return SProcXF86DRIQueryVersion(client);
 | 
						|
        }
 | 
						|
        case X_XF86DRIQueryDirectRenderingCapable: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return SProcXF86DRIQueryDirectRenderingCapable(client);
 | 
						|
        }
 | 
						|
        default: {
 | 
						|
            EPHYR_LOG ("leave\n") ;
 | 
						|
            return DRIErrorBase + XF86DRIClientNotLocal;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#endif /*XEPHYR_DRI*/
 |