XEPHYR: more GLX/DRI proxying work.

* hw/kdrive/ephyr/XF86dri.c: re format this correctly.
	  Make function decls honour the Ansi-C standard.
	* hw/kdrive/ephyr/ephyr.c: protect glx/dri related
	  extension initialisation with the XEPHYR_DRI
	  macro. Initialize the GLX ext hijacking
	  at startup.
	* hw/kdrive/ephyr/ephyrdri.c: add more logging to ease debugging
	* hw/kdrive/ephyr/ephyrdriext.c: ditto. reformat.
	* hw/kdrive/ephyr/ephyrglxext.c,h: add this extension to
	  proxy GLX requests to the host X. started to proxy those nedded to
	  make glxinfo work with fglrx. Not yet finished.
	* hw/kdrive/ephyr/ephyrhostglx.c,h: put here the actual
	  Xlib code used to hit the host X server because Xlib stuff cannot be
	  mixed with xserver internal code, otherwise compilation erros due to
	  type clashes happen. So no Xlib type should be exported by the
	  entrypoints defined here.
This commit is contained in:
Dodji Seketeli 2007-08-23 11:53:02 +02:00 committed by Dodji Seketeli
parent 0b85451449
commit c06fa924b4
9 changed files with 974 additions and 208 deletions

View File

@ -26,12 +26,19 @@ libxephyr_a_SOURCES = \
ephyrdriext.c \
ephyrdri.c \
ephyrdri.h \
ephyrglxext.c \
ephyrglxext.h \
ephyrhostglx.c \
ephyrhostglx.h \
os.c \
hostx.h \
ephyr.h \
ephyrlog.h
libxephyr_a_CFLAGS = @LIBDRM_CFLAGS@ @DRIPROTO_CFLAGS@
libxephyr_a_CFLAGS = \
@LIBDRM_CFLAGS@ \
-I$(top_srcdir) \
@DRIPROTO_CFLAGS@
Xephyr_SOURCES = \
ephyrinit.c

View File

@ -158,10 +158,8 @@ Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
return True;
}
Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
Display* dpy;
int screen;
Bool* isCapable;
Bool
XF86DRIQueryDirectRenderingCapable (Display *dpy, int screen, Bool *isCapable)
{
XExtDisplayInfo *info = find_display (dpy);
xXF86DRIQueryDirectRenderingCapableReply rep;
@ -176,10 +174,10 @@ Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
req->screen = screen;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryDirectRenderingCapable... return False");
return False;
return False;
}
*isCapable = rep.isCapable;
UnlockDisplay(dpy);
@ -188,11 +186,10 @@ Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
return True;
}
Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
Display* dpy;
int screen;
drm_handle_t * hSAREA;
char **busIdString;
Bool
XF86DRIOpenConnection (Display *dpy, int screen,
drm_handle_t *hSAREA,
char **busIdString)
{
XExtDisplayInfo *info = find_display (dpy);
xXF86DRIOpenConnectionReply rep;
@ -207,16 +204,16 @@ Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
req->driReqType = X_XF86DRIOpenConnection;
req->screen = screen;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
UnlockDisplay(dpy);
SyncHandle();
TRACE("OpenConnection... return False");
return False;
return False;
}
*hSAREA = rep.hSAREALow;
if (sizeof(drm_handle_t) == 8) {
int shift = 32; /* var to prevent warning on next line */
*hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
int shift = 32; /* var to prevent warning on next line */
*hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
}
if (rep.length) {
@ -227,7 +224,7 @@ Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
TRACE("OpenConnection... return False");
return False;
}
_XReadPad(dpy, *busIdString, rep.busIdStringLength);
_XReadPad(dpy, *busIdString, rep.busIdStringLength);
} else {
*busIdString = NULL;
}
@ -546,16 +543,10 @@ Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
return True;
}
Bool XF86DRIGetDeviceInfo(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;
Bool
XF86DRIGetDeviceInfo (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;
@ -606,10 +597,8 @@ Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer,
return True;
}
Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
Display* dpy;
int screen;
Drawable drawable;
Bool
XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable)
{
/* This function and the underlying X protocol are deprecated.
*/
@ -619,10 +608,8 @@ Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
return False;
}
Bool XF86DRICloseFullScreen(dpy, screen, drawable)
Display* dpy;
int screen;
Drawable drawable;
Bool
XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable)
{
/* This function and the underlying X protocol are deprecated.
*/

View File

@ -31,6 +31,8 @@
#include "inputstr.h"
#include "scrnintstr.h"
#include "ephyrlog.h"
#include "ephyrdri.h"
#include "ephyrglxext.h"
extern int KdTsPhyScreen;
KdKeyboardInfo *ephyrKbd;
@ -45,6 +47,11 @@ typedef struct _EphyrInputPrivate {
Bool EphyrWantGrayScale = 0;
#ifdef XEPHYR_DRI
extern void ephyrDRIExtensionInit(void) ;
#endif
Bool
ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
{
@ -617,6 +624,7 @@ ephyrInitScreen (ScreenPtr pScreen)
#ifdef XEPHYR_DRI
ephyrDRIExtensionInit () ;
ephyrHijackGLXExtension () ;
#endif
return TRUE;
}

View File

@ -159,16 +159,18 @@ ephyrDRICreateDrawable (int a_screen,
drm_drawable_t *a_hw_drawable)
{
EPHYR_LOG ("enter\n") ;
return FALSE ;
EPHYR_LOG_ERROR ("not implemented yet\n") ;
EPHYR_LOG ("leave\n") ;
return FALSE ;
}
Bool
ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
{
EPHYR_LOG ("enter\n") ;
return FALSE ;
EPHYR_LOG_ERROR ("not implemented yet\n") ;
EPHYR_LOG ("leave\n") ;
return FALSE ;
}
Bool
@ -188,8 +190,9 @@ ephyrDRIGetDrawableInfo (int a_screen,
drm_clip_rect_t **a_back_clip_rects)
{
EPHYR_LOG ("enter\n") ;
return FALSE ;
EPHYR_LOG_ERROR ("not implemented yet\n") ;
EPHYR_LOG ("leave\n") ;
return FALSE ;
}
Bool
@ -201,9 +204,16 @@ ephyrDRIGetDeviceInfo (int a_screen,
int *a_dev_private_size,
void **a_dev_private)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
EPHYR_LOG ("enter\n") ;
return FALSE ;
is_ok = XF86DRIGetDeviceInfo (dpy, a_screen, a_frame_buffer,
a_fb_origin, a_fb_size, a_fb_stride,
a_dev_private_size, a_dev_private) ;
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
#endif /*EPHYR_DRI*/

View File

@ -79,7 +79,7 @@ static void XF86DRIResetProc(ExtensionEntry* extEntry);
static unsigned char DRIReqCode = 0;
extern void XFree86DRIExtensionInit(void);
extern void ephyrDRIExtensionInit(void);
void
ephyrDRIExtensionInit(void)
@ -113,13 +113,13 @@ XF86DRIResetProc (
}
static int
ProcXF86DRIQueryVersion(
register ClientPtr client
)
ProcXF86DRIQueryVersion (register ClientPtr client)
{
xXF86DRIQueryVersionReply rep;
register int n;
EPHYR_LOG ("enter\n") ;
REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
rep.type = X_Reply;
rep.length = 0;
@ -135,18 +135,18 @@ ProcXF86DRIQueryVersion(
swapl(&rep.patchVersion, n);
}
WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRIQueryDirectRenderingCapable(
register ClientPtr client
)
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) {
@ -171,20 +171,20 @@ ProcXF86DRIQueryDirectRenderingCapable(
swapl(&rep.length, n);
}
WriteToClient(client,
sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRIOpenConnection(
register ClientPtr client
)
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) {
@ -215,17 +215,17 @@ ProcXF86DRIOpenConnection(
WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
if (rep.busIdStringLength)
WriteToClient(client, rep.busIdStringLength, busIdString);
WriteToClient(client, rep.busIdStringLength, busIdString);
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRIAuthConnection(
register ClientPtr client
)
ProcXF86DRIAuthConnection (register ClientPtr client)
{
xXF86DRIAuthConnectionReply rep;
EPHYR_LOG ("enter\n") ;
REQUEST(xXF86DRIAuthConnectionReq);
REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
if (stuff->screen >= screenInfo.numScreens) {
@ -243,36 +243,36 @@ ProcXF86DRIAuthConnection(
rep.authenticated = 0;
}
WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRICloseConnection(
register ClientPtr client
)
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;
client->errorValue = stuff->screen;
return BadValue;
}
/*
DRICloseConnection( screenInfo.screens[stuff->screen]);
*/
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRIGetClientDriverName(
register ClientPtr client
)
ProcXF86DRIGetClientDriverName (register ClientPtr client)
{
xXF86DRIGetClientDriverNameReply rep;
char* clientDriverName;
EPHYR_LOG ("enter\n") ;
REQUEST(xXF86DRIGetClientDriverNameReq);
REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
if (stuff->screen >= screenInfo.numScreens) {
@ -301,19 +301,19 @@ ProcXF86DRIGetClientDriverName(
WriteToClient(client,
rep.clientDriverNameLength,
clientDriverName);
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRICreateContext(
register ClientPtr client
)
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) {
@ -347,101 +347,104 @@ ProcXF86DRICreateContext(
*/
WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRIDestroyContext(
register ClientPtr client
)
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;
client->errorValue = stuff->screen;
return BadValue;
}
/*
if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
stuff->context)) {
return BadValue;
}
*/
if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
stuff->context)) {
return BadValue;
}
*/
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRICreateDrawable(
ClientPtr client
)
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;
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);
rc = dixLookupDrawable (&pDrawable, stuff->drawable, client, 0,
DixReadAccess);
if (rc != Success)
return rc;
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)) {
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
)
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;
client->errorValue = stuff->screen;
return BadValue;
}
rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
DixReadAccess);
rc = dixLookupDrawable(&pDrawable,
stuff->drawable,
client,
0,
DixReadAccess);
if (rc != Success)
return rc;
return rc;
if (!ephyrDRIDestroyDrawable(stuff->screen,
0/*should be drawable in host x*/)) {
return BadValue;
return BadValue;
}
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRIGetDrawableInfo(
register ClientPtr client
)
ProcXF86DRIGetDrawableInfo (register ClientPtr client)
{
xXF86DRIGetDrawableInfoReply rep;
DrawablePtr pDrawable;
@ -450,11 +453,12 @@ ProcXF86DRIGetDrawableInfo(
drm_clip_rect_t * pBackClipRects;
int backX, backY, rc;
EPHYR_LOG ("enter\n") ;
REQUEST(xXF86DRIGetDrawableInfoReq);
REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
if (stuff->screen >= screenInfo.numScreens) {
client->errorValue = stuff->screen;
return BadValue;
client->errorValue = stuff->screen;
return BadValue;
}
rep.type = X_Reply;
@ -466,25 +470,25 @@ ProcXF86DRIGetDrawableInfo(
* between xephyr drawable and the host drawable
*/
rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
DixReadAccess);
DixReadAccess);
if (rc != Success)
return rc;
return rc;
if (!ephyrDRIGetDrawableInfo (stuff->screen,
0 /*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;
0 /*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;
@ -492,78 +496,78 @@ ProcXF86DRIGetDrawableInfo(
rep.drawableWidth = W;
rep.drawableHeight = H;
rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
SIZEOF(xGenericReply));
SIZEOF(xGenericReply));
rep.backX = backX;
rep.backY = backY;
if (rep.numBackClipRects)
rep.length += sizeof(drm_clip_rect_t) * 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));
/* 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;
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);
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++;
}
}
if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
pClippedRects[j].y1 < pClippedRects[j].y2) {
j++;
}
}
rep.numClipRects = j;
} else {
rep.numClipRects = 0;
}
rep.numClipRects = j;
} else {
rep.numClipRects = 0;
}
rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
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);
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);
WriteToClient(client,
sizeof(drm_clip_rect_t) * rep.numBackClipRects,
(char *)pBackClipRects);
}
EPHYR_LOG ("leave\n") ;
return (client->noClientException);
}
static int
ProcXF86DRIGetDeviceInfo(
register ClientPtr client
)
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;
client->errorValue = stuff->screen;
return BadValue;
}
rep.type = X_Reply;
@ -571,12 +575,12 @@ ProcXF86DRIGetDeviceInfo(
rep.sequenceNumber = client->sequence;
if (!ephyrDRIGetDeviceInfo (stuff->screen,
&hFrameBuffer,
(int*)&rep.framebufferOrigin,
(int*)&rep.framebufferSize,
(int*)&rep.framebufferStride,
(int*)&rep.devPrivateSize,
&pDevPrivate)) {
&hFrameBuffer,
(int*)&rep.framebufferOrigin,
(int*)&rep.framebufferSize,
(int*)&rep.framebufferStride,
(int*)&rep.devPrivateSize,
&pDevPrivate)) {
return BadValue;
}
@ -590,30 +594,34 @@ ProcXF86DRIGetDeviceInfo(
rep.length = 0;
if (rep.devPrivateSize) {
rep.length = (SIZEOF(xXF86DRIGetDeviceInfoReply) -
SIZEOF(xGenericReply) +
((rep.devPrivateSize + 3) & ~3)) >> 2;
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
)
ProcXF86DRIDispatch (register ClientPtr client)
{
REQUEST(xReq);
EPHYR_LOG ("enter\n") ;
switch (stuff->data)
{
case X_XF86DRIQueryVersion:
return ProcXF86DRIQueryVersion(client);
case X_XF86DRIQueryDirectRenderingCapable:
return ProcXF86DRIQueryDirectRenderingCapable(client);
case X_XF86DRIQueryVersion: {
EPHYR_LOG ("leave\n") ;
return ProcXF86DRIQueryVersion(client);
}
case X_XF86DRIQueryDirectRenderingCapable: {
EPHYR_LOG ("leave\n") ;
return ProcXF86DRIQueryDirectRenderingCapable(client);
}
}
if (!LocalClient(client))
@ -621,36 +629,56 @@ ProcXF86DRIDispatch (
switch (stuff->data)
{
case X_XF86DRIOpenConnection:
return ProcXF86DRIOpenConnection(client);
case X_XF86DRICloseConnection:
return ProcXF86DRICloseConnection(client);
case X_XF86DRIGetClientDriverName:
return ProcXF86DRIGetClientDriverName(client);
case X_XF86DRICreateContext:
return ProcXF86DRICreateContext(client);
case X_XF86DRIDestroyContext:
return ProcXF86DRIDestroyContext(client);
case X_XF86DRICreateDrawable:
return ProcXF86DRICreateDrawable(client);
case X_XF86DRIDestroyDrawable:
return ProcXF86DRIDestroyDrawable(client);
case X_XF86DRIGetDrawableInfo:
return ProcXF86DRIGetDrawableInfo(client);
case X_XF86DRIGetDeviceInfo:
return ProcXF86DRIGetDeviceInfo(client);
case X_XF86DRIAuthConnection:
return ProcXF86DRIAuthConnection(client);
/* {Open,Close}FullScreen are deprecated now */
default:
return BadRequest;
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
)
SProcXF86DRIQueryVersion (register ClientPtr client)
{
register int n;
REQUEST(xXF86DRIQueryVersionReq);
@ -659,9 +687,7 @@ SProcXF86DRIQueryVersion(
}
static int
SProcXF86DRIQueryDirectRenderingCapable(
register ClientPtr client
)
SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
{
register int n;
REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
@ -671,24 +697,29 @@ SProcXF86DRIQueryDirectRenderingCapable(
}
static int
SProcXF86DRIDispatch (
register ClientPtr client
)
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:
return SProcXF86DRIQueryVersion(client);
case X_XF86DRIQueryDirectRenderingCapable:
return SProcXF86DRIQueryDirectRenderingCapable(client);
default:
return DRIErrorBase + XF86DRIClientNotLocal;
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;
}
}
}

View File

@ -0,0 +1,291 @@
/*
* 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.
*
* Authors:
* Dodji Seketeli <dodji@openedhand.com>
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "extnsionst.h"
#include "ephyrglxext.h"
#include "ephyrhostglx.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#include <GL/glxproto.h>
#include "GL/glx/glxserver.h"
#include "GL/glx/indirect_table.h"
#include "GL/glx/unpack.h"
#ifdef XEPHYR_DRI
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
Bool
ephyrHijackGLXExtension (void)
{
const void *(*dispatch_functions)[2];
EPHYR_LOG ("Got GLX extension\n") ;
if (!Single_dispatch_info.dispatch_functions) {
EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
return FALSE ;
}
dispatch_functions = Single_dispatch_info.dispatch_functions ;
EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
dispatch_functions[X_GLXQueryServerString][1] = ephyrGLXQueryServerStringSwap ;
EPHYR_LOG ("hijacked mesa GL to forward requests to host X\n") ;
return TRUE ;
}
/*********************
* implementation of
* hijacked GLX entry
* points
********************/
int
ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
{
ClientPtr client = a_cl->client;
xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
xGLXQueryVersionReply reply;
int major, minor;
int res = BadImplementation ;
EPHYR_LOG ("enter\n") ;
major = req->majorVersion ;
minor = req->minorVersion ;
if (!ephyrHostGLXQueryVersion (&major, &minor)) {
EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
goto out ;
}
reply.majorVersion = major ;
reply.minorVersion = minor ;
reply.length = 0 ;
reply.type = X_Reply ;
reply.sequenceNumber = client->sequence ;
if (client->swapped) {
__glXSwapQueryVersionReply(client, &reply);
} else {
WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
}
res = Success ;
out:
EPHYR_LOG ("leave\n") ;
return res;
}
int
ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
{
xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_SHORT (&req->length);
__GLX_SWAP_INT (&req->majorVersion);
__GLX_SWAP_INT (&req->minorVersion);
return ephyrGLXQueryVersion (a_cl, a_pc) ;
}
static int
ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
{
xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
ClientPtr client = a_cl->client;
xGLXGetVisualConfigsReply reply;
int32_t *props_buf=NULL, num_visuals=0,
num_props=0, res=BadImplementation, i=0,
props_per_visual_size=0,
props_buf_size=0;
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetVisualConfigs (req->screen,
&num_visuals,
&num_props,
&props_buf_size,
&props_buf)) {
EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
goto out ;
}
EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
reply.numVisuals = num_visuals;
reply.numProps = num_props;
reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
if (a_do_swap) {
__GLX_SWAP_SHORT(&reply.sequenceNumber);
__GLX_SWAP_INT(&reply.length);
__GLX_SWAP_INT(&reply.numVisuals);
__GLX_SWAP_INT(&reply.numProps);
__GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
}
WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
props_per_visual_size = props_buf_size/num_visuals ;
for (i=0; i < num_visuals; i++) {
WriteToClient (client,
props_per_visual_size,
(char*)props_buf +i*props_per_visual_size);
}
res = Success ;
out:
EPHYR_LOG ("leave\n") ;
if (props_buf) {
xfree (props_buf) ;
props_buf = NULL ;
}
return res ;
}
int
ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
{
return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
}
int
ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
{
return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
}
int
ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
{
int res=BadImplementation ;
xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
goto out ;
}
res = Success ;
out:
EPHYR_LOG ("leave\n") ;
return res ;
}
int
ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
{
xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_SHORT (&req->length);
__GLX_SWAP_INT (&req->major);
__GLX_SWAP_INT (&req->minor);
__GLX_SWAP_INT (&req->numbytes);
return ephyrGLXClientInfo (a_cl, a_pc) ;
}
int
ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
{
int res = BadImplementation ;
ClientPtr client = a_cl->client;
xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
xGLXQueryServerStringReply reply;
char *server_string=NULL ;
int length=0 ;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetStringFromServer (req->screen, req->name, &server_string)) {
EPHYR_LOG_ERROR ("failed to query string from host\n") ;
goto out ;
}
length= strlen (server_string) + 1;
reply.type = X_Reply ;
reply.sequenceNumber = client->sequence ;
reply.length = __GLX_PAD (length) >> 2 ;
reply.n = length ;
WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
WriteToClient(client, (int)length, server_string);
res = Success ;
out:
EPHYR_LOG ("leave\n") ;
if (server_string) {
xfree (server_string) ;
server_string = NULL;
}
return res ;
}
int
ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
{
EPHYR_LOG_ERROR ("not yet implemented\n") ;
return BadImplementation ;
}
#endif /*XEPHYR_DRI*/

View File

@ -0,0 +1,35 @@
/*
* 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.
*
* Authors:
* Dodji Seketeli <dodji@openedhand.com>
*/
#ifndef __EPHYR_GLXEXT_H__
#define __EPHYR_GLXEXT_H__
#include <X11/Xdefs.h>
Bool ephyrHijackGLXExtension (void) ;
#endif /*__EPHYR_GLXEXT_H__*/

View File

@ -0,0 +1,350 @@
/*
* 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.
*
* a lots of the content of this file has been adapted from the mesa source
* code.
* Authors:
* Dodji Seketeli <dodji@openedhand.com>
*/
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include <X11/Xlibint.h>
#include <GL/glx.h>
#include <GL/internal/glcore.h>
#include <GL/glxproto.h>
#include <GL/glxint.h>
#include "hostx.h"
#include "ephyrhostglx.h"
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
#ifdef XEPHYR_DRI
Bool
ephyrHostGLXGetMajorOpcode (int *a_opcode)
{
Bool is_ok=FALSE ;
Display *dpy=hostx_get_display () ;
static int opcode ;
int first_event_return=0, first_error_return=0;
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
EPHYR_LOG ("enter\n") ;
if (!opcode) {
if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode,
&first_event_return, &first_error_return)) {
EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ;
goto out ;
}
}
*a_opcode = opcode ;
is_ok = TRUE ;
out:
EPHYR_LOG ("release\n") ;
return is_ok ;
}
Bool
ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
EPHYR_LOG ("enter\n") ;
if (!glXQueryVersion (dpy, a_major, a_minor)) {
EPHYR_LOG_ERROR ("glxQueryVersion() failed\n") ;
goto out ;
}
is_ok = TRUE ;
out:
EPHYR_LOG ("leave\n") ;
return is_ok ;
}
/**
* GLX protocol structure for the ficticious "GXLGenericGetString" request.
*
* This is a non-existant protocol packet. It just so happens that all of
* the real protocol packets used to request a string from the server have
* an identical binary layout. The only difference between them is the
* meaning of the \c for_whom field and the value of the \c glxCode.
*/
typedef struct GLXGenericGetString {
CARD8 reqType;
CARD8 glxCode;
CARD16 length B16;
CARD32 for_whom B32;
CARD32 name B32;
} xGLXGenericGetStringReq;
/* These defines are only needed to make the GetReq macro happy.
*/
#define sz_xGLXGenericGetStringReq 12
#define X_GLXGenericGetString 0
Bool
ephyrHostGLXGetStringFromServer (int a_screen_number,
int a_string_name,
char **a_string)
{
Display *dpy = hostx_get_display () ;
xGLXGenericGetStringReq *req=NULL;
xGLXSingleReply reply;
int length=0, numbytes=0, major_opcode=0;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
EPHYR_LOG ("enter\n") ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
return FALSE ;
}
EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
LockDisplay (dpy);
/* All of the GLX protocol requests for getting a string from the server
* look the same. The exact meaning of the a_for_whom field is usually
* either the screen number (for glXQueryServerString) or the context tag
* (for GLXSingle).
*/
GetReq (GLXGenericGetString, req);
req->reqType = major_opcode;
req->glxCode = X_GLXQueryServerString;
req->for_whom = a_screen_number;
req->name = a_string_name;
_XReply (dpy, (xReply *)&reply, 0, False);
length = reply.length * 4;
numbytes = reply.size;
*a_string = (char *) Xmalloc( numbytes );
if (*a_string != NULL) {
if (_XRead (dpy, *a_string, numbytes)) {
EPHYR_LOG_ERROR ("read failed\n") ;
}
length -= numbytes;
}
_XEatData (dpy, length) ;
UnlockDisplay (dpy);
SyncHandle ();
EPHYR_LOG ("leave\n") ;
return TRUE ;
}
Bool
ephyrHostGLXGetVisualConfigs (int32_t a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
xGLXGetVisualConfigsReq *req;
xGLXGetFBConfigsReq *fb_req;
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXGetFBConfigsSGIXReq *sgi_req;
xGLXGetVisualConfigsReply reply;
unsigned supported_request=0;
char *server_glx_version=NULL,
*server_glx_extensions=NULL ;
int j=0,
screens=0,
major_opcode=0,
num_props=0,
num_visuals=0,
props_buf_size=0,
props_per_visual_size=0;
int32_t *props_buf=NULL;
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
screens = ScreenCount (dpy);
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get opcode\n") ;
goto out ;
}
if (!ephyrHostGLXGetStringFromServer (0, GLX_VERSION,
&server_glx_version)
|| !server_glx_version) {
EPHYR_LOG_ERROR ("failed to get glx version from server\n") ;
goto out ;
}
if (atof (server_glx_version) >= 1.3 ) {
supported_request = 1;
}
if (!ephyrHostGLXGetStringFromServer (a_screen, GLX_EXTENSIONS,
&server_glx_extensions)) {
EPHYR_LOG_ERROR ("failed to get glx extensions from server for screen: %d\n",
a_screen) ;
goto out ;
}
if (supported_request != 1) {
if (server_glx_extensions
&& strstr (server_glx_extensions, "GLX_SGIX_fbconfig" ) != NULL ) {
supported_request = 2;
} else {
supported_request = 3;
}
}
LockDisplay(dpy);
switch (supported_request) {
case 1:
GetReq(GLXGetFBConfigs,fb_req);
fb_req->reqType = major_opcode;
fb_req->glxCode = X_GLXGetFBConfigs;
fb_req->screen = a_screen;
break;
case 2:
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
sgi_req->reqType = major_opcode;
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
sgi_req->screen = a_screen;
break;
case 3:
GetReq(GLXGetVisualConfigs,req);
req->reqType = major_opcode;
req->glxCode = X_GLXGetVisualConfigs;
req->screen = a_screen;
break;
}
if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
EPHYR_LOG_ERROR ("unknown error\n") ;
UnlockDisplay(dpy);
goto out ;
}
if (!reply.numVisuals) {
EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ;
UnlockDisplay(dpy);
goto out ;
}
num_visuals = reply.numVisuals ;
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
* FIXME: FBconfigs?
*/
/* Check number of properties */
num_props = reply.numProps;
if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
(num_props > __GLX_MAX_CONFIG_PROPS)) {
/* Huh? Not in protocol defined limits. Punt */
EPHYR_LOG_ERROR ("got a bad reply to request\n") ;
UnlockDisplay(dpy);
goto out ;
}
if (supported_request != 3) {
num_props *= 2;
}
props_per_visual_size = num_props * __GLX_SIZE_INT32;
props_buf_size = props_per_visual_size * reply.numVisuals;
props_buf = malloc (props_buf_size) ;
for (j = 0; j < reply.numVisuals; j++) {
if (_XRead (dpy,
(char*)props_buf + j*props_per_visual_size,
props_per_visual_size) != Success) {
EPHYR_LOG_ERROR ("read failed\n") ;
}
}
UnlockDisplay(dpy);
*a_num_visuals = num_visuals ;
*a_num_props = num_props ;
*a_props_buf_size = props_buf_size ;
*a_props_buf = props_buf ;
is_ok = TRUE ;
out:
if (server_glx_version) {
XFree (server_glx_version) ;
server_glx_version = NULL ;
}
if (server_glx_extensions) {
XFree (server_glx_extensions) ;
server_glx_extensions = NULL ;
}
SyncHandle () ;
return is_ok;
}
Bool
ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
const char* a_extension_list)
{
Bool is_ok = FALSE ;
Display *dpy = hostx_get_display () ;
xGLXClientInfoReq *req;
int size;
int32_t major_opcode=0 ;
EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ;
if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
goto out ;
}
LockDisplay (dpy);
GetReq (GLXClientInfo,req);
req->reqType = major_opcode;
req->glxCode = X_GLXClientInfo;
req->major = a_major;
req->minor = a_minor;
size = strlen (a_extension_list) + 1;
req->length += (size + 3) >> 2;
req->numbytes = size;
Data (dpy, a_extension_list, size);
is_ok=TRUE ;
out:
UnlockDisplay(dpy);
SyncHandle();
return is_ok ;
}
#endif /*XEPHYR_DRI*/

View File

@ -0,0 +1,47 @@
/*
* 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.
*
* Authors:
* Dodji Seketeli <dodji@openedhand.com>
*/
#ifndef __EPHYRHOSTGLX_H__
#define __EPHYRHOSTGLX_H__
Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
int a_string_name,
char **a_string) ;
Bool ephyrHostGLXGetVisualConfigs (int a_screen,
int32_t *a_num_visuals,
int32_t *a_num_props,
int32_t *a_props_buf_size,
int32_t **a_props_buf) ;
Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
const char* a_extension_list) ;
#endif /*__EPHYRHOSTGLX_H__*/