the attached patch adds basic Shared OpenGL support for Windows guests
on Linux hosts.
It currently works with the mesa software renderer.
tests with the accelerated but proprietary nvidia driver resulted in a
segmentation fault.
Another problem is that it needs a global Display variable which is
defined in the VirtualBox frontend.
The patched is released under the MIT license

Regards,
Alexander Eichner
Index: include/VBox/HostServices/VBoxOGLOp.h
===================================================================
--- include/VBox/HostServices/VBoxOGLOp.h	(Revision 3516)
+++ include/VBox/HostServices/VBoxOGLOp.h	(Arbeitskopie)
@@ -1846,11 +1846,12 @@
     vboxglDrvDescribePixelFormat,
     vboxglDrvSetPixelFormat,
     vboxglDrvSwapBuffers,
-
+
+#ifdef __WIN__
     /* OpenGL Extensions */
     vboxwglSwapIntervalEXT,
     vboxwglGetSwapIntervalEXT,
-
+#endif
 };
 #endif
 
Index: src/VBox/HostServices/SharedOpenGL/service.cpp
===================================================================
--- src/VBox/HostServices/SharedOpenGL/service.cpp	(Revision 3516)
+++ src/VBox/HostServices/SharedOpenGL/service.cpp	(Arbeitskopie)
@@ -285,13 +285,16 @@
                     rc = VERR_INVALID_PARAMETER;
                 }
                 else
-                {
+                {
+#ifdef __WIN__
                     /* Execute the function. */
                     if (vboxwglGetProcAddress(pszExtFnName))
                         rc = VINF_SUCCESS;
                     else
                         rc = VERR_FILE_NOT_FOUND;
-
+#else
+                        rc = VERR_FILE_NOT_FOUND;
+#endif
                     if (VBOX_SUCCESS(rc))
                     {
                         /* Update parameters.*/
Index: src/VBox/HostServices/SharedOpenGL/gllindrv.cpp
===================================================================
--- src/VBox/HostServices/SharedOpenGL/gllindrv.cpp	(Revision 3516)
+++ src/VBox/HostServices/SharedOpenGL/gllindrv.cpp	(Arbeitskopie)
@@ -22,16 +22,50 @@
 
 #include "vboxgl.h"
 #define LOG_GROUP LOG_GROUP_SHARED_OPENGL
-#include <VBox/log.h>
-
+#include <VBox/log.h>
+#include <string.h>
+
+extern Display *globalDisplay;
+
+/* from http://www.mesa3d.org/brianp/sig97/exten.htm */
+GLboolean vboxglCheckExtension(Display *dpy, int screenNum, char *extName )
+{
+   /*
+    ** Search for extName in the extensions string.  Use of strstr()
+    ** is not sufficient because extension names can be prefixes of
+    ** other extension names.  Could use strtok() but the constant
+    ** string returned by glGetString can be in read-only memory.
+    */
+    char *p = (char *) glXQueryExtensionsString(dpy, screenNum);
+    char *end;
+    int extNameLen;
+
+    extNameLen = strlen(extName);
+    end = p + strlen(p);
+
+    while (p < end) {
+        int n = strcspn(p, " ");
+        if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
+            return GL_TRUE;
+        }
+        p += (n + 1);
+    }
+    return GL_FALSE;
+}
+
+
+
+
 /**
  * Global init of VBox OpenGL for windows
  *
  * @returns VBox error code
  */
 int vboxglGlobalInit()
-{
-    vboxInitOpenGLExtensions();
+{
+    Log(("vboxglGlobalInit\n"));
+
+    /*vboxInitOpenGLExtensions();*/
     return VINF_SUCCESS;
 }
 
@@ -41,9 +75,34 @@
  * @returns VBox error code
  * @param   pClient         Client context
  */
-int vboxglConnect(PVBOXOGLCTX pClient)
-{
-    return VINF_SUCCESS;
+int vboxglConnect(PVBOXOGLCTX pClient)
+{
+    int rc = VERR_NOT_IMPLEMENTED;
+    Log(("vboxglConnect\n"));
+    pClient->getContextIDPtr = NULL;
+    pClient->importContextEXTPtr = NULL;
+    pClient->VisualIDMapper = NULL;
+    pClient->xwin = 0;
+
+    pClient->dpy = globalDisplay;
+
+    if (pClient->dpy) {
+        int  screenNum;
+
+        XLockDisplay(pClient->dpy);
+
+        screenNum = DefaultScreen(pClient->dpy);
+        if (vboxglCheckExtension(pClient->dpy, screenNum, "GLX_EXT_import_context")) {
+            pClient->getContextIDPtr = (GLXContextID (*)(const GLXContext))glXGetProcAddress((const GLubyte *)"glXGetContextIDEXT");
+            pClient->importContextEXTPtr = (GLXContext (*)(Display *, GLXContextID))glXGetProcAddress((const GLubyte *) "glXImportContextEXT");
+            if (pClient->getContextIDPtr && pClient->importContextEXTPtr)
+                rc = VINF_SUCCESS;
+        }
+
+       XUnlockDisplay(pClient->dpy);
+    }
+
+    return rc;
 }
 
 /**
@@ -53,70 +112,185 @@
  * @param   pClient         Client context
  */
 int vboxglDisconnect(PVBOXOGLCTX pClient)
-{
+{
+    Log(("vboxglDisconnect\n"));
+
+#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
+    if (pClient->dpy) {
+        if (pClient->xwin != 0) {
+            XUnmapWindow(pClient->dpy, pClient->xwin);
+            XDestroyWindow(pClient->dpy, pClient->xwin);
+        }
+        if (pClient->curVisualInfo) {
+            XFree(pClient->curVisualInfo);
+        }
+        if (pClient->VisualIDMapper) {
+            RTMemFree(pClient->VisualIDMapper);
+        }
+    }
+    pClient->dpy = NULL;
+    pClient->xwin = 0;
+#endif
     return VINF_SUCCESS;
 }
 
 /* Driver functions */
 void vboxglDrvCreateContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
-{
-    OGL_CMD(DrvCreateContext, 4);
+{
+    XSetWindowAttributes attr;
+    XVisualInfo *visinfo = NULL;
+    unsigned long mask;
+    //GLXContext ctx;
+    GLXContextID glrc;
+    int screen_num;
+    OGL_CMD(DrvCreateContext, 1);
     OGL_PARAM(HDC, hdc);
-    OGL_PARAM(uint32_t, cx);
-    OGL_PARAM(uint32_t, cy);
-    OGL_PARAM(BYTE, cColorBits);
-    OGL_PARAM(BYTE, iPixelType);
-    OGL_PARAM(BYTE, cDepthBits);
 
-    pClient->lastretval = 0; /** @todo */
+    Log(("DrvCreateContext %x\n", hdc));
+#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
+
+    XLockDisplay(pClient->dpy);
+
+    screen_num = DefaultScreen(pClient->dpy);
+    visinfo = pClient->curVisualInfo;
+
+    /* choose a standard */
+    if (visinfo == NULL) {
+        static int attribs[] = {
+          GLX_RGBA,
+          GLX_RED_SIZE, 1,
+          GLX_GREEN_SIZE, 1,
+          GLX_BLUE_SIZE, 1,
+          GLX_DEPTH_SIZE, 1,
+          GLX_DOUBLEBUFFER,
+          None
+        };
+
+        visinfo = glXChooseVisual(pClient->dpy, screen_num, attribs);
+    }
+
+    if (pClient->xwin == 0) {
+
+    if (pClient->win_width == 0)
+       pClient->win_width = 100;
+
+    if (pClient->win_height == 0)
+       pClient->win_height = 100;
+
+	/* window attributes */
+	attr.background_pixel = 0;
+	attr.border_pixel = 0;
+	attr.colormap = XCreateColormap(pClient->dpy, RootWindow(pClient->dpy, screen_num ), visinfo->visual, AllocNone);
+	attr.event_mask = StructureNotifyMask | ExposureMask;
+	mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+	screen_num = DefaultScreen(pClient->dpy);
+	pClient->xwin = XCreateWindow(pClient->dpy, 
+	                                RootWindow(pClient->dpy, screen_num), 
+	                                0, 0, pClient->win_width, pClient->win_height, 0,
+	                                visinfo->depth, InputOutput,
+	                                visinfo->visual, mask, &attr);
+	XMapWindow(pClient->dpy, pClient->xwin);
+    }
+    XResizeWindow(pClient->dpy, pClient->xwin, pClient->win_width, pClient->win_height);
+
+    pClient->ctx = glXCreateContext(pClient->dpy, visinfo, NULL, True);
+    //glrc = pClient->getContextIDPtr(ctx);
+    XUnlockDisplay(pClient->dpy);
+    glrc = 1;
+    Assert(glrc);
+#else
+    AssertFailed();
+    glrc = 0;
+#endif
+
+    pClient->lastretval = (uint64_t)glrc;
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvDeleteContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
-{
+{
+    //GLXContext ctx;
     OGL_CMD(DrvDeleteContext, 1);
     OGL_PARAM(HGLRC, hglrc);
-    /** @todo */
-    pClient->lastretval = 0; /** @todo */
+    Log(("DrvDeleteContext %x\n", hglrc));
+    XLockDisplay(pClient->dpy);
+    //ctx = pClient->importContextEXTPtr(pClient->dpy, hglrc);
+    glXDestroyContext(pClient->dpy, VBOX_OGL_GUEST_TO_HOST_HDC(hglrc));
+    XUnlockDisplay(pClient->dpy);
+    pClient->lastretval = 1;
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvSetContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
-{
+{
+    //GLXContext ctx;
     OGL_CMD(DrvSetContext, 2);
     OGL_PARAM(HDC, hdc);
     OGL_PARAM(HGLRC, hglrc);
-
-    pClient->lastretval = 0; /** @todo */
+    Log(("DrvSetContext %x %x\n", hdc, hglrc));
+#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
+    XLockDisplay(pClient->dpy);
+    //ctx = pClient->importContextEXTPtr(pClient->dpy, hglrc);
+    pClient->lastretval = glXMakeCurrent(pClient->dpy, pClient->xwin, VBOX_OGL_GUEST_TO_HOST_HDC(hglrc));
+    XUnlockDisplay(pClient->dpy);
+    if (!pClient->lastretval)
+        Log(("glXMakeCurrent failed\n"));
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
+#else
+    AssertFailed();
+#endif
 }
 
 void vboxglDrvCopyContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
-{
+{
+    //GLXContext ctxSrc, ctxDst;
     OGL_CMD(DrvDeleteContext, 3);
     OGL_PARAM(HGLRC, hglrcSrc);
     OGL_PARAM(HGLRC, hglrcDst);
     OGL_PARAM(UINT,  mask);
-    pClient->lastretval = 0; /** @todo */
+    Log(("DrvCopyContext %x %x %x\n", hglrcSrc, hglrcDst, mask));
+    XLockDisplay(pClient->dpy);
+    //ctxSrc = pClient->importContextEXTPtr(pClient->dpy, hglrcSrc);
+    //ctxDst = pClient->importContextEXTPtr(pClient->dpy, hglrcDst);
+    glXCopyContext(pClient->dpy, VBOX_OGL_GUEST_TO_HOST_HDC(hglrc), VBOX_OGL_GUEST_TO_HOST_HDC(hglrc), mask);
+    XUnlockDisplay(pClient->dpy);
+    pClient->lastretval = 1;
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvReleaseContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
-{
+{
     OGL_CMD(DrvReleaseContext, 1);
     OGL_PARAM(HGLRC, hglrc);
-    pClient->lastretval = 0; /** @todo */
+    Log(("DrvReleaseContext %x\n", hglrc));
+    XLockDisplay(pClient->dpy);
+    /* clear current selection */
+    pClient->lastretval = glXMakeCurrent(pClient->dpy, pClient->xwin, NULL);
+    XUnlockDisplay(pClient->dpy);
+    if (!pClient->lastretval)
+        Log(("glXMakeCurrent failed\n"));
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvCreateLayerContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
 {
-    OGL_CMD(DrvCreateLayerContext, 5);
+    OGL_CMD(DrvCreateLayerContext, 2);
     OGL_PARAM(HDC, hdc);
     OGL_PARAM(int, iLayerPlane);
-    OGL_PARAM(uint32_t, cx);
-    OGL_PARAM(uint32_t, cy);
-    OGL_PARAM(BYTE, cColorBits);
-    OGL_PARAM(BYTE, iPixelType);
-    OGL_PARAM(BYTE, cDepthBits);
+
+    Log(("DrvCreateLayerContext %x\n", hdc));
+#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
+    pClient->lastretval = 0; /** @todo */
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
+#else
     AssertFailed();
-    /** @todo create memory dc with the parameters above */
-    pClient->lastretval = 0; /** @todo */
+#endif
 }
 
 void vboxglDrvShareLists(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
@@ -124,7 +298,9 @@
     OGL_CMD(DrvShareLists, 3);
     OGL_PARAM(HGLRC, hglrc1);
     OGL_PARAM(HGLRC, hglrc2);
-    pClient->lastretval = 0; /** @todo */
+    pClient->lastretval = 0; /** @todo */
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 
@@ -134,7 +310,9 @@
     OGL_PARAM(HDC, hdc);
     OGL_PARAM(int, iLayerPlane);
     OGL_PARAM(BOOL, bRealize);
-    pClient->lastretval = 0; /** @todo */
+    pClient->lastretval = 0; /** @todo */
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvSwapLayerBuffers(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
@@ -142,24 +320,64 @@
     OGL_CMD(DrvSwapLayerBuffers, 2);
     OGL_PARAM(HDC, hdc);
     OGL_PARAM(UINT, fuPlanes);
-    pClient->lastretval = 0; /** @todo */
+    pClient->lastretval = 0; /** @todo */
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvSetPixelFormat(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
-{
-    OGL_CMD(DrvSetPixelFormat, 2);
+{
+    XVisualInfo templateVisInfo, *VisualInfos = NULL;
+    long visualMask;
+    int screenNum, numVisuals;
+
+    OGL_CMD(DrvSetPixelFormat, 4);
     OGL_PARAM(HDC, hdc);
-    OGL_PARAM(int, iPixelFormat);
+    OGL_PARAM(int, iPixelFormat);
+    OGL_PARAM(uint32_t, cx);
+    OGL_PARAM(uint32_t, cy);
 
-    pClient->lastretval = 0; /** @todo */
+    Log(("vboxDrvSetPixelFormat %d\n", iPixelFormat));
+
+    XLockDisplay(pClient->dpy);
+    /* Get XVisualInfo based on the given ID */
+    screenNum = DefaultScreen(pClient->dpy);
+    templateVisInfo.visualid = pClient->VisualIDMapper[iPixelFormat];
+    templateVisInfo.screen = screenNum;
+    visualMask = VisualIDMask | VisualScreenMask;
+    VisualInfos = XGetVisualInfo(pClient->dpy, visualMask, &templateVisInfo, &numVisuals);
+    Log(("Window width: %d Window height: %d\n", cx, cy));
+    pClient->win_width = cx;
+    pClient->win_height = cy;
+    if (VisualInfos) {
+        /* Free old if available*/
+        if (pClient->curVisualInfo)
+            XFree(pClient->curVisualInfo);
+
+        pClient->curVisualInfo = VisualInfos;
+        pClient->lastretval = true;
+    } else {
+        pClient->lastretval = false;
+    }
+    XUnlockDisplay(pClient->dpy);
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvSwapBuffers(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
 {
     OGL_CMD(DrvSwapBuffers, 1);
     OGL_PARAM(HDC, hdc);
+
+    XLockDisplay(pClient->dpy);
+
+    glXSwapBuffers(pClient->dpy, pClient->xwin);
+
+    XUnlockDisplay(pClient->dpy);
 
-    pClient->lastretval = 0; /** @todo */
+    pClient->lastretval = 1;
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvDescribeLayerPlane(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
@@ -174,7 +392,9 @@
     Assert(pClient->cbLastParam == nBytes);
     plpd = (PLAYERPLANEDESCRIPTOR)pClient->pLastParam;
 
-    pClient->lastretval = 0; /** @todo */
+    pClient->lastretval = 0; /** @todo */
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvSetLayerPaletteEntries(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
@@ -185,7 +405,9 @@
     OGL_PARAM(int, iStart);
     OGL_PARAM(int, cEntries);
     OGL_MEMPARAM(COLORREF, pcr);
-    pClient->lastretval = 0; /** @todo */
+    pClient->lastretval = 0; /** @todo */
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvGetLayerPaletteEntries(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
@@ -200,12 +422,17 @@
 
     Assert(pClient->cbLastParam == sizeof(COLORREF)*cEntries);
     pcr = (COLORREF *)pClient->pLastParam;
-    pClient->lastretval = 0; /** @todo */
+    pClient->lastretval = 0; /** @todo */
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 void vboxglDrvDescribePixelFormat(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
 {
     LPPIXELFORMATDESCRIPTOR ppfd;
+    XVisualInfo templateVisualInfo, *matchingVisualInfo;
+    int numVisuals, screenNum, returnNumVisuals, glxReturnValue;
+    long maskVisualInfo;
 
     OGL_CMD(DrvDescribePixelFormat, 3);
     OGL_PARAM(HDC, hdc);
@@ -213,12 +440,79 @@
     OGL_PARAM(UINT, nBytes);
     Assert(pClient->cbLastParam == nBytes);
     ppfd = (LPPIXELFORMATDESCRIPTOR)pClient->pLastParam;
-
-    pClient->lastretval = 0; /** @todo */
+
+    XLockDisplay(pClient->dpy);
+    /* First get number of all visuals for the return value */
+    screenNum = DefaultScreen(pClient->dpy);
+    templateVisualInfo.screen = screenNum;
+    maskVisualInfo = VisualScreenMask;
+    matchingVisualInfo = XGetVisualInfo(pClient->dpy, maskVisualInfo, 
+                                        &templateVisualInfo,
+                                        &returnNumVisuals);
+    if (!pClient->VisualIDMapper) {
+        /* Create the PixelFormat to XVisualInfo->visualid mapper 
+         * because the Visual ID's are not contiguos and don't start at 1*/
+        int actualVisual = 0;
+
+        pClient->VisualIDMapper = (VisualID *)RTMemAlloc(returnNumVisuals * sizeof(VisualID));
+        for (actualVisual = 0; actualVisual < returnNumVisuals; actualVisual++) {
+             pClient->VisualIDMapper[actualVisual] = matchingVisualInfo[actualVisual].visualid;
+        }
+    }
+    XFree(matchingVisualInfo);
+
+    if (nBytes == sizeof(PIXELFORMATDESCRIPTOR)) {
+        /* Get XVisualInfo which matches iPixelFormat */
+        templateVisualInfo.screen = screenNum;
+        templateVisualInfo.visualid = pClient->VisualIDMapper[iPixelFormat];
+        maskVisualInfo = VisualIDMask | VisualScreenMask;
+        matchingVisualInfo = XGetVisualInfo(pClient->dpy, maskVisualInfo,
+                                            &templateVisualInfo,
+                                            &numVisuals);
+        if (matchingVisualInfo) {
+            Log(("Filling values into PIXELFORMATDESCRIPTOR\n"));
+            /* translate all values to theire corresponding Windows ones */
+            ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
+            ppfd->nVersion = 1;
+            ppfd->cColorBits = (BYTE)matchingVisualInfo->bits_per_rgb;
+            ppfd->iLayerType = PFD_MAIN_PLANE;
+            /* Set dwFlags */
+            ppfd->dwFlags = PFD_DRAW_TO_WINDOW;
+            if (!glXGetConfig(pClient->dpy, matchingVisualInfo, GLX_USE_GL, &glxReturnValue)) {
+                if (glxReturnValue)
+                    ppfd->dwFlags |= PFD_SUPPORT_OPENGL;
+            }
+            if (!glXGetConfig(pClient->dpy, matchingVisualInfo, GLX_DOUBLEBUFFER, &glxReturnValue)) {
+                if (glxReturnValue)
+                    ppfd->dwFlags |= PFD_DOUBLEBUFFER;
+            }
+            /* Set iPixelType */
+            if (!glXGetConfig(pClient->dpy, matchingVisualInfo, GLX_RGBA, &glxReturnValue)) {
+                if (glxReturnValue)
+                    ppfd->iPixelType = PFD_TYPE_RGBA;
+                else
+                    ppfd->iPixelType = PFD_TYPE_COLORINDEX;
+            }
+            /* Set cDepthBits */
+            if (!glXGetConfig(pClient->dpy, matchingVisualInfo, GLX_DEPTH_SIZE, &glxReturnValue)) {
+                ppfd->cDepthBits = glxReturnValue;
+            } else {
+                ppfd->cDepthBits = 0;
+            }
+            /** @todo Fill in the rest */
+            XFree(matchingVisualInfo);
+        }
+    }
+    XUnlockDisplay(pClient->dpy);
+    pClient->lastretval = returnNumVisuals;
+    pClient->fHasLastError = true;
+    pClient->ulLastError   = glGetError();
 }
 
 RTUINTPTR vboxDrvIsExtensionAvailable(char *pszExtFunctionName)
-{
-    return 0;
+{
+    RTUINTPTR pfnProc = (RTUINTPTR)glXGetProcAddress((const GLubyte *)pszExtFunctionName);
+    Log(("vboxDrvIsExtensionAvailable %s -> %d\n", pszExtFunctionName, !!pfnProc));
+    return pfnProc;
 }
 
Index: src/VBox/HostServices/SharedOpenGL/vboxgl.cpp
===================================================================
--- src/VBox/HostServices/SharedOpenGL/vboxgl.cpp	(Revision 3516)
+++ src/VBox/HostServices/SharedOpenGL/vboxgl.cpp	(Arbeitskopie)
@@ -47,6 +47,8 @@
     const GLubyte *pName;
     uint32_t cbLen;
     int      rc = VINF_SUCCESS;
+
+    Log(("vboxglGetString\n"));
 
 #ifdef __WIN__
     PIXELFORMATDESCRIPTOR pfd;
@@ -66,6 +68,43 @@
 
     HGLRC hRC = wglCreateContext(hdc);
     wglMakeCurrent(hdc, hRC);
+#elif defined __LINUX__
+    Display *dpy;
+    static int attribs[] = {
+      GLX_RGBA,
+      GLX_RED_SIZE, 1,
+      GLX_GREEN_SIZE, 1,
+      GLX_BLUE_SIZE, 1,
+      GLX_DEPTH_SIZE, 1,
+      GLX_DOUBLEBUFFER,
+      None
+    };
+    XVisualInfo *visinfo;
+    int screen_num;
+    GLXContext ctx;
+    XSetWindowAttributes attr;
+    unsigned long mask;
+    Window win;
+
+    /* we have to set up a rendering context to be able to use glGetString
+     * a window is created but is not mapped to screen (so it's not visible') 
+     * and a GLXContext is bound to it */
+    XLockDisplay(pClient->dpy);
+    dpy = pClient->dpy;
+    screen_num = DefaultScreen(dpy);
+    visinfo = glXChooseVisual(dpy, screen_num, attribs);
+    /* Create Window */
+    attr.background_pixel = 0;
+    attr.border_pixel = 0;
+    attr.colormap = XCreateColormap(dpy, RootWindow(dpy, screen_num), visinfo->visual, AllocNone);
+    attr.event_mask = StructureNotifyMask | ExposureMask;
+    mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+    win = XCreateWindow(dpy, RootWindow(dpy, screen_num), 0, 0, 100, 100,
+		       0, visinfo->depth, InputOutput,
+		       visinfo->visual, mask, &attr);
+    /* Create Context */
+    ctx = glXCreateContext(dpy, visinfo, NULL, True);
+    glXMakeCurrent(dpy, win, ctx);
 #endif
 
     pName = glGetString(name);
@@ -90,7 +129,13 @@
 #ifdef __WIN__
     wglMakeCurrent(NULL, NULL);
     wglDeleteContext(hRC);
-    ReleaseDC(0, hdc);
+    ReleaseDC(0, hdc);
+#elif defined __LINUX__
+    /* Free all data */
+    glXDestroyContext(dpy, ctx);
+    XFree(visinfo);
+    XDestroyWindow(dpy, win);
+    XUnlockDisplay(pClient->dpy);
 #endif
     return rc;
 }
@@ -114,7 +159,9 @@
     Log(("vboxglFlushBuffer cCommands=%d cbCmdBuffer=%x\n", cCommands, cbCmdBuffer));
 
     pClient->fHasLastError = false;
-
+
+    XLockDisplay(pClient->dpy);
+    glXMakeCurrent(pClient->dpy, pClient->xwin, pClient->ctx);
     for (i=0;i<cCommands;i++)
     {
         PVBOX_OGL_CMD pCmd = (PVBOX_OGL_CMD)pCmdBuffer;
@@ -142,6 +189,8 @@
         *pLastError = pClient->ulLastError;
     else
         *pLastError = glGetError();
+
+    XUnlockDisplay(pClient->dpy);
 
 #ifdef DEBUG
     Log(("Flush: last return value=%VX64\n", *pLastRetVal));
Index: src/VBox/HostServices/SharedOpenGL/gldrv.h
===================================================================
--- src/VBox/HostServices/SharedOpenGL/gldrv.h	(Revision 3516)
+++ src/VBox/HostServices/SharedOpenGL/gldrv.h	(Arbeitskopie)
@@ -22,17 +22,32 @@
 #ifndef __VBOXGLWIN__H
 #define __VBOXGLWIN__H
 
-#include <iprt/types.h>
+#include <iprt/types.h>
+#include <iprt/mem.h>
 
 #ifdef __WIN__
 #define VBOX_OGL_DEBUG_WINDOW_OUTPUT
 #endif
+
+#ifdef __LINUX__
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include <GL/glxext.h>
+
+typedef GLXContextID (*glXGetContextIDEXTProc) (const GLXContext);
+typedef GLXContext (*glXImportContextEXTProc) (Display *, GLXContextID);
+
+
+#define VBOX_OGL_DEBUG_WINDOW_OUTPUT
+#endif
 
-#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
-#define VBOX_OGL_GUEST_TO_HOST_HDC(a)       pClient->hdc
-#else
-#define VBOX_OGL_GUEST_TO_HOST_HDC(a)       a
+#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
+#if defined(__WIN__)
+#define VBOX_OGL_GUEST_TO_HOST_HDC(a)       pClient->hdc
+#elif defined(__LINUX__)
+#define VBOX_OGL_GUEST_TO_HOST_HDC(a)       pClient->ctx
 #endif
+#endif
 
 typedef struct
 {
@@ -44,10 +59,21 @@
     uint8_t    *pLastParam;
     uint32_t    cbLastParam;
 
-#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
+#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
+#ifdef __WIN__
     HWND        hwnd;
-    HDC         hdc;
+    HDC         hdc;
+#elif defined __LINUX__
+    Display     *dpy;
+    Window      xwin;
+    XVisualInfo *curVisualInfo;
+    int         win_width, win_height;
+    VisualID    *VisualIDMapper;
+    GLXContext  ctx;
+    glXGetContextIDEXTProc getContextIDPtr;
+    glXImportContextEXTProc importContextEXTPtr;
 #endif
+#endif
 } VBOXOGLCTX, *PVBOXOGLCTX;
 
 
@@ -66,12 +92,24 @@
 typedef void *      LPVOID;
 typedef int16_t     SHORT;
 typedef uint16_t    USHORT;
-typedef int64_t     INT64;
-typedef int32_t     INT32;
+typedef int64_t     INT64;
+typedef int32_t     INT32;
 typedef float       FLOAT; /* ??? */
 
 #define DECLARE_HANDLE(a)  typedef HANDLE a
 #define WINAPI
+
+#define PFD_DOUBLEBUFFER   0x00000001
+#define PFD_STEREO         0x00000002
+#define PFD_DRAW_TO_WINDOW 0x00000004
+#define PFD_SUPPORT_OPENGL 0x00000020
+
+#define PFD_TYPE_RGBA       0
+#define PFD_TYPE_COLORINDEX 1
+
+#define PFD_MAIN_PLANE 0
+#define PFD_OVERLAY_PLANE 1
+#define PFD_UNDERLAY_PLANE (-1)
 
 typedef struct
 {
@@ -130,7 +168,7 @@
     BYTE  bReserved;
     COLORREF crTransparent;
 } LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, LPLAYERPLANEDESCRIPTOR;
-
+
 #endif
 
 void vboxglDrvReleaseContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
Index: src/VBox/HostServices/SharedOpenGL/vboxgl.h
===================================================================
--- src/VBox/HostServices/SharedOpenGL/vboxgl.h	(Revision 3516)
+++ src/VBox/HostServices/SharedOpenGL/vboxgl.h	(Arbeitskopie)
@@ -92,10 +92,11 @@
  *
  * @returns VBox error code
  * @param   pszFunctionName     OpenGL extension function name
- */
+ */
+#ifdef __WIN__
 bool vboxwglGetProcAddress(char *pszFunctionName);
+#endif
 
-
 /* OpenGL wrappers */
 void vboxglArrayElement(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
 void vboxglBegin(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
@@ -351,9 +352,11 @@
 void vboxglGetTexLevelParameterfv (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
 void vboxglGetTexLevelParameteriv (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
 void vboxglGetTexImage (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
-
+
+#ifdef __WIN__
 void vboxwglSwapIntervalEXT (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
 void vboxwglGetSwapIntervalEXT (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer);
+#endif
 
 /* after the above */
 #include <VBox/HostServices/VBoxOpenGLSvc.h>
Index: src/VBox/HostServices/SharedOpenGL/Makefile.kmk
===================================================================
--- src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(Revision 3516)
+++ src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(Arbeitskopie)
@@ -31,7 +31,9 @@
 VBoxSharedOpenGL_DEFS      = VBOX_HGCM VBOX_OGL_HOST_SIDE
 VBoxSharedOpenGL_INCS.win  = \
 	$(PATH_TOOL_$(VBOX_VCC_TOOL)_ATLMFC_INC) \
-	$(VBOX_PATH_SDK)
+	$(VBOX_PATH_SDK)
+VBoxSharedOpenGL_INCS.linux = \
+	/usr/include/qt3
 
 VBoxSharedOpenGL_SOURCES = \
 	service.cpp \
@@ -53,7 +55,12 @@
 	$(LIB_RUNTIME) \
 	$(LIB_REM)
 VBoxSharedOpenGL_LIBS.win = \
-        $(PATH_SDK_WINPSDK_LIB)/opengl32.lib
+        $(PATH_SDK_WINPSDK_LIB)/opengl32.lib
+VBoxSharedOpenGL_LIBPATH.linux = \
+	$(VBOX_LIBPATH_X11)
+VBoxSharedOpenGL_LIBS.linux = \
+	GL \
+	qt-mt
 
 include $(PATH_KBUILD)/subfooter.kmk
 
Index: src/VBox/Frontends/VirtualBox/src/main.cpp
===================================================================
--- src/VBox/Frontends/VirtualBox/src/main.cpp	(Revision 3516)
+++ src/VBox/Frontends/VirtualBox/src/main.cpp	(Arbeitskopie)
@@ -53,8 +53,12 @@
 # define REG_PC REG_EIP
 #endif
 
+/** XXX: For Shared OpenGL support*/
+#if defined(Q_WS_X11)
+#include <X11/Xlib.h>
+Display *globalDisplay __attribute__ ((visibility ("default")));
+#endif
 
-
 /**
  * the signal handler that prints out a backtrace of the call stack.
  * the code is taken from http://www.linuxjournal.com/article/6391.
@@ -131,10 +135,17 @@
     sigaction (SIGUSR1, &sa, NULL);
 #endif
 
+#if defined(Q_WS_X11)
+    XInitThreads();
+
     qInstallMsgHandler (QtMessageOutput);
+    globalDisplay = XOpenDisplay(NULL);
+    QIApplication a (globalDisplay, argc, argv);
+#else
+    qInstallMsgHandler (QtMessageOutput);
 
     QIApplication a (argc, argv);
-
+#endif
     /* weird palette test */
 #if 0
     QPalette pal = a.palette();
@@ -202,6 +213,10 @@
         }
     }
 
+#if defined(Q_WS_X11)
+    XCloseDisplay(globalDisplay);
+#endif
+
     LogFlowFunc (("rc=%d\n", rc));
     LogFlowFuncLeave();
 
Index: src/VBox/Main/VMMDevInterface.cpp
===================================================================
--- src/VBox/Main/VMMDevInterface.cpp	(Revision 3516)
+++ src/VBox/Main/VMMDevInterface.cpp	(Arbeitskopie)
@@ -544,7 +544,6 @@
     {
         LogRel(("Failed to load Shared OpenGL service %Vrc\n", rc));
     }
-
     pDrvIns->pDrvHlp->pfnSSMRegister(pDrvIns, "HGCM", 0, HGCM_SSM_VERSION, 4096/* bad guess */, NULL, iface_hgcmSave, NULL, NULL, iface_hgcmLoad, NULL);
 #endif /* VBOX_HGCM */
 
_______________________________________________
vbox-dev mailing list
[email protected]
http://vbox.innotek.de/mailman/listinfo/vbox-dev

Reply via email to