From c06fa924b4781a35b86e4a78d95ff3e9d95b02d1 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Thu, 23 Aug 2007 11:53:02 +0200 Subject: [PATCH] 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. --- hw/kdrive/ephyr/Makefile.am | 9 +- hw/kdrive/ephyr/XF86dri.c | 59 +++--- hw/kdrive/ephyr/ephyr.c | 8 + hw/kdrive/ephyr/ephyrdri.c | 18 +- hw/kdrive/ephyr/ephyrdriext.c | 365 ++++++++++++++++++--------------- hw/kdrive/ephyr/ephyrglxext.c | 291 ++++++++++++++++++++++++++ hw/kdrive/ephyr/ephyrglxext.h | 35 ++++ hw/kdrive/ephyr/ephyrhostglx.c | 350 +++++++++++++++++++++++++++++++ hw/kdrive/ephyr/ephyrhostglx.h | 47 +++++ 9 files changed, 974 insertions(+), 208 deletions(-) create mode 100644 hw/kdrive/ephyr/ephyrglxext.c create mode 100644 hw/kdrive/ephyr/ephyrglxext.h create mode 100644 hw/kdrive/ephyr/ephyrhostglx.c create mode 100644 hw/kdrive/ephyr/ephyrhostglx.h 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__*/ +