diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index cc9c9109a..5e3316324 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -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 diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c index bed65e5a4..fc35ce267 100644 --- a/hw/kdrive/ephyr/XF86dri.c +++ b/hw/kdrive/ephyr/XF86dri.c @@ -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. */ diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 330158a7d..b460b9630 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -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; } diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c index 5201082d8..89d9ae7b5 100644 --- a/hw/kdrive/ephyr/ephyrdri.c +++ b/hw/kdrive/ephyr/ephyrdri.c @@ -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*/ diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c index 437d8c4da..ac68054a3 100644 --- a/hw/kdrive/ephyr/ephyrdriext.c +++ b/hw/kdrive/ephyr/ephyrdriext.c @@ -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; + } } } diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c new file mode 100644 index 000000000..d0380f105 --- /dev/null +++ b/hw/kdrive/ephyr/ephyrglxext.c @@ -0,0 +1,291 @@ +/* + * Xephyr - A kdrive X server thats runs in a host X window. + * Authored by Matthew Allum + * + * 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 + */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "extnsionst.h" +#include "ephyrglxext.h" +#include "ephyrhostglx.h" +#define _HAVE_XALLOC_DECLS +#include "ephyrlog.h" +#include +#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*/ + diff --git a/hw/kdrive/ephyr/ephyrglxext.h b/hw/kdrive/ephyr/ephyrglxext.h new file mode 100644 index 000000000..22ea605d7 --- /dev/null +++ b/hw/kdrive/ephyr/ephyrglxext.h @@ -0,0 +1,35 @@ +/* + * Xephyr - A kdrive X server thats runs in a host X window. + * Authored by Matthew Allum + * + * 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 + */ +#ifndef __EPHYR_GLXEXT_H__ +#define __EPHYR_GLXEXT_H__ + +#include +Bool ephyrHijackGLXExtension (void) ; + +#endif /*__EPHYR_GLXEXT_H__*/ + diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c new file mode 100644 index 000000000..693fbc1a9 --- /dev/null +++ b/hw/kdrive/ephyr/ephyrhostglx.c @@ -0,0 +1,350 @@ +/* + * Xephyr - A kdrive X server thats runs in a host X window. + * Authored by Matthew Allum + * + * 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 + */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#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*/ + diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h new file mode 100644 index 000000000..7a158f3d0 --- /dev/null +++ b/hw/kdrive/ephyr/ephyrhostglx.h @@ -0,0 +1,47 @@ +/* + * Xephyr - A kdrive X server thats runs in a host X window. + * Authored by Matthew Allum + * + * 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 + */ +#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__*/ +