* hw/kdrive/ephyr/ephyrdri.c: (ephyrDRIGetDrawableInfo): quickly hook this into getting the drawable info from the host X server. For the time being, this only gets the drawable info of the Xephyr main window in the host. It should really get the info of a the peer drawable in the host X. So there should be a peer drawable to begin with. * hw/kdrive/ephyr/ephyrdriext.c: (ProcXF86DRIGetDrawableInfo): some cleanups. Properly get the the drawable info otherwise there is a host X hang. * hw/kdrive/ephyr/ephyrhostglx.c: do not (ephyrHostGLXQueryVersion): do not use C bindings of the glx protocol calls. Some of those actually access DRI context directly, resulting in the context having three clients. Instead all XF86DRI proto fowarding request should be coded by hand and only forward the protocol requests
727 lines
21 KiB
C
727 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=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0;
|
|
drm_clip_rect_t *pClipRects=NULL, *pClippedRects=NULL;
|
|
drm_clip_rect_t *pBackClipRects=NULL;
|
|
|
|
EPHYR_LOG ("enter\n") ;
|
|
memset (&rep, 0, sizeof (rep)) ;
|
|
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*/
|