Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 44813)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 44860)
@@ -80,4 +80,10 @@
 }
 
+GLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs)
+{
+    pVisInfo->displayName = crStrdup(displayName);
+    pVisInfo->visAttribs = visAttribs;
+    return renderspu_SystemInitVisual(pVisInfo);
+}
 
 /*
@@ -117,7 +123,5 @@
     /* create a new visual */
     i = render_spu.numVisuals;
-    render_spu.visuals[i].displayName = crStrdup(displayName);
-    render_spu.visuals[i].visAttribs = visAttribs;
-    if (renderspu_SystemInitVisual(&(render_spu.visuals[i]))) {
+    if (renderspuInitVisual(&(render_spu.visuals[i]), displayName, visAttribs)) {
         render_spu.numVisuals++;
         return &(render_spu.visuals[i]);
@@ -315,56 +319,9 @@
 }
 
-
-/*
- * Window functions
- */
-
-GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id )
-{
-    WindowInfo *window;
-    VisualInfo *visual;
-    GLboolean showIt;
-
-    if (id <= 0)
-    {
-        id = (GLint)crHashtableAllocKeys(render_spu.windowTable, 1);
-        if (id <= 0)
-        {
-            crWarning("failed to allocate window id");
-            return -1;
-        }
-    }
-    else
-    {
-        if (crHashtableIsKeyUsed(render_spu.windowTable, id))
-        {
-            crWarning("the specified window key %d is in use", id);
-            return -1;
-        }
-    }
-
-
-    if (!dpyName || crStrlen(render_spu.display_string) > 0)
-        dpyName = render_spu.display_string;
-
-    visual = renderspuFindVisual( dpyName, visBits );
-    if (!visual)
-    {
-        crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
-        return -1;
-    }
-
-    /* Allocate WindowInfo */
-    window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
-    if (!window)
-    {
-        crWarning( "Render SPU: Couldn't create a window" );
-        return -1;
-    }
-
+GLboolean renderspuWindowInit( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id )
+{
     RTCritSectInit(&window->CompositorLock);
     window->pCompositor = NULL;
 
-    crHashtableAdd(render_spu.windowTable, id, window);
     window->BltInfo.Base.id = id;
 
@@ -373,10 +330,4 @@
     window->BltInfo.width  = render_spu.defaultWidth;
     window->BltInfo.height = render_spu.defaultHeight;
-
-    if (render_spu.force_hidden_wdn_create
-            || ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")))
-        showIt = 0;
-    else
-        showIt = window->BltInfo.Base.id != CR_RENDER_DEFAULT_WINDOW_ID;
 
     /* Set window->title, replacing %i with the window ID number */
@@ -399,5 +350,8 @@
         }
     }
-
+        
+    window->BltInfo.Base.visualBits = visual->visAttribs;
+    
+    
     /*
     crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
@@ -406,13 +360,79 @@
     if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window ))
     {
+        crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
+        return GL_FALSE;
+    }
+
+    CRASSERT(window->visual == visual);
+    return GL_TRUE;
+}
+
+/*
+ * Window functions
+ */
+
+GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id )
+{
+    WindowInfo *window;
+    VisualInfo *visual;
+    GLboolean showIt;
+
+    if (id <= 0)
+    {
+        id = (GLint)crHashtableAllocKeys(render_spu.windowTable, 1);
+        if (id <= 0)
+        {
+            crWarning("failed to allocate window id");
+            return -1;
+        }
+    }
+    else
+    {
+        if (crHashtableIsKeyUsed(render_spu.windowTable, id))
+        {
+            crWarning("the specified window key %d is in use", id);
+            return -1;
+        }
+    }
+
+
+    if (!dpyName || crStrlen(render_spu.display_string) > 0)
+        dpyName = render_spu.display_string;
+
+    visual = renderspuFindVisual( dpyName, visBits );
+    if (!visual)
+    {
+        crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
+        return -1;
+    }
+
+    /* Allocate WindowInfo */
+    window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
+    if (!window)
+    {
+        crWarning( "Render SPU: Couldn't create a window" );
+        return -1;
+    }
+    
+    crHashtableAdd(render_spu.windowTable, id, window);
+
+    if (render_spu.force_hidden_wdn_create
+            || ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")))
+        showIt = 0;
+    else
+        showIt = window->BltInfo.Base.id != CR_RENDER_DEFAULT_WINDOW_ID;
+
+
+    /*
+    crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
+    */
+    /* Have GLX/WGL/AGL create the window */
+    if (!renderspuWindowInit( window, visual, showIt, id ))
+    {
         crFree(window);
         crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
         return -1;
     }
-
-    CRASSERT(window->visual == visual);
-
-    window->BltInfo.Base.visualBits = visual->visAttribs;
-
+    
     return window->BltInfo.Base.id;
 }
@@ -437,9 +457,28 @@
 }
 
+void renderspuWindowTerm( WindowInfo *window )
+{
+    GET_CONTEXT(pOldCtx);
+    /* ensure no concurrent draws can take place */
+    renderspuVBoxCompositorSet(window, NULL);
+    renderspu_SystemDestroyWindow( window );
+    RTCritSectDelete(&window->CompositorLock);
+    /* check if this window is bound to some ctx. Note: window pointer is already freed here */
+    crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
+    /* restore current context */
+    {
+        GET_CONTEXT(pNewCtx);
+        if (pNewCtx!=pOldCtx)
+        {
+            renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->BltInfo.Base.id:CR_RENDER_DEFAULT_WINDOW_ID, 0,
+                                     pOldCtx ? pOldCtx->BltInfo.Base.id:CR_RENDER_DEFAULT_CONTEXT_ID);
+        }
+    }
+}
+
 void
 RENDER_APIENTRY renderspuWindowDestroy( GLint win )
 {
     WindowInfo *window;
-    GET_CONTEXT(pOldCtx);
 
     CRASSERT(win >= 0);
@@ -452,24 +491,9 @@
     if (window) {
         crDebug("Render SPU: Destroy window (%d)", win);
-        renderspu_SystemDestroyWindow( window );
-
-        RTCritSectDelete(&window->CompositorLock);
-        window->pCompositor = NULL;
+        renderspuWindowTerm( window );
 
         /* remove window info from hash table, and free it */
         crHashtableDelete(render_spu.windowTable, win, crFree);
 
-        /* check if this window is bound to some ctx. Note: window pointer is already freed here */
-        crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
-
-        /* restore current context */
-        {
-            GET_CONTEXT(pNewCtx);
-            if (pNewCtx!=pOldCtx)
-            {
-                renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->BltInfo.Base.id:CR_RENDER_DEFAULT_WINDOW_ID, 0,
-                                     pOldCtx ? pOldCtx->BltInfo.Base.id:CR_RENDER_DEFAULT_CONTEXT_ID);
-            }
-        }
     }
     else {
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.h
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.h	(revision 44813)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.h	(revision 44860)
@@ -32,4 +32,15 @@
 #include <iprt/cdefs.h>
 #include <iprt/critsect.h>
+#if defined(GLX) /* @todo: unify windows and glx thread creation code */
+#include <iprt/thread.h>
+#include <iprt/semaphore.h>
+
+/* special window id used for representing the command window CRWindowInfo */
+#define CR_RENDER_WINCMD_ID (INT32_MAX-2)
+AssertCompile(CR_RENDER_WINCMD_ID != CR_RENDER_DEFAULT_WINDOW_ID);
+/* CRHashTable is using unsigned long keys, we use it to trore X Window -> CRWindowInfo association */
+AssertCompile(sizeof (Window) == sizeof (unsigned long));
+#endif
+
 
 #define MAX_VISUALS 32
@@ -167,4 +178,33 @@
 } Barrier;
 
+#ifdef GLX
+typedef enum
+{
+	CR_RENDER_WINCMD_TYPE_UNDEFINED = 0,
+	/* create the window (not used for now) */
+	CR_RENDER_WINCMD_TYPE_WIN_CREATE,
+	/* destroy the window (not used for now) */
+	CR_RENDER_WINCMD_TYPE_WIN_DESTROY,
+        /* notify the WinCmd thread about window creation */
+        CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE,
+        /* notify the WinCmd thread about window destroy */
+        CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY,
+        /* nop used to synchronize with the WinCmd thread */
+        CR_RENDER_WINCMD_TYPE_NOP,
+	/* exit Win Cmd thread */
+	CR_RENDER_WINCMD_TYPE_EXIT,
+} CR_RENDER_WINCMD_TYPE;
+
+typedef struct CR_RENDER_WINCMD
+{
+    /* command type */
+	CR_RENDER_WINCMD_TYPE enmCmd;
+	/* command result */
+	int rc;
+	/* valid for WIN_CREATE & WIN_DESTROY only */
+	WindowInfo *pWindow;
+} CR_RENDER_WINCMD, *PCR_RENDER_WINCMD;
+#endif
+
 /**
  * Renderspu state info
@@ -243,4 +283,16 @@
                      GLsizei height );
     void (*OSMesaDestroyContext)( OSMesaContext ctx );
+#endif
+
+#if defined(GLX)
+    RTTHREAD hWinCmdThread;
+    VisualInfo WinCmdVisual;
+    WindowInfo WinCmdWindow;
+    RTSEMEVENT hWinCmdCompleteEvent;
+    /* display connection used to send data to the WinCmd thread */
+    Display *pCommunicationDisplay;
+    Atom WinCmdAtom;
+    /* X Window -> CRWindowInfo table */
+    CRHashTable *pWinToInfoTable;
 #endif
 
@@ -328,4 +380,9 @@
 extern void renderspu_SystemSetRootVisibleRegion(GLint cRects, GLint *pRects);
 #endif
+
+#ifdef GLX
+extern int renderspu_SystemInit();
+extern int renderspu_SystemTerm();
+#endif
 extern void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt );
 extern void renderspu_SystemMakeCurrent( WindowInfo *window, GLint windowInfor, ContextInfo *context );
@@ -344,4 +401,7 @@
 extern PCR_BLITTER renderspuVBoxPresentBlitterGetAndEnter( WindowInfo *window );
 extern PCR_BLITTER renderspuVBoxPresentBlitterEnsureCreated( WindowInfo *window );
+extern void renderspuWindowTerm( WindowInfo *window );
+extern GLboolean renderspuWindowInit( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id );
+extern GLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs);
 extern void renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter);
 extern void renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY);
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c	(revision 44813)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c	(revision 44860)
@@ -404,4 +404,315 @@
 #endif /* GLX_VERSION_1_3 */
 
+static const char * renderspuGetDisplayName()
+{
+    const char *dpyName;
+
+    if (render_spu.display_string[0])
+        dpyName = render_spu.display_string;
+    else
+    {
+        crWarning("Render SPU: no display..");
+        dpyName = NULL;
+    }
+    return dpyName;
+}
+
+static int renderspuWinCmdWinCreate(WindowInfo *pWindow)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+static int renderspuWinCmdWinDestroy(WindowInfo *pWindow)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+static int renderspuWinCmdInit()
+{
+    const char * dpyName;
+    int rc = VERR_GENERAL_FAILURE;
+    
+    if (!crHashtableAllocRegisterKey(render_spu.windowTable, CR_RENDER_WINCMD_ID))
+    {
+        crError("CR_RENDER_WINCMD_ID %d is occupied already", CR_RENDER_WINCMD_ID);
+        return VERR_INVALID_STATE;
+    }
+    
+    render_spu.pWinToInfoTable = crAllocHashtable();
+    if (render_spu.pWinToInfoTable)
+    {
+        dpyName = renderspuGetDisplayName();
+        if (dpyName)
+        {
+            GLboolean bRc = renderspuInitVisual(&render_spu.WinCmdVisual, dpyName, render_spu.default_visual);
+            if (bRc)
+            {
+                bRc = renderspuWindowInit(&render_spu.WinCmdWindow, &render_spu.WinCmdVisual, GL_FALSE, CR_RENDER_WINCMD_ID);
+                if (bRc)
+                {
+                    XSelectInput(render_spu.WinCmdVisual.dpy, render_spu.WinCmdWindow.window, StructureNotifyMask);
+                    render_spu.WinCmdAtom = XInternAtom(render_spu.WinCmdVisual.dpy, "VBoxWinCmd", False);
+                    CRASSERT(render_spu.WinCmdAtom != None);
+                    return VINF_SUCCESS;
+                }
+                else
+                {
+                    crError("renderspuWindowInit failed");
+                }
+                /* there is no visual destroy impl currently
+                 * @todo: implement */
+            }
+            else
+            {
+                crError("renderspuInitVisual failed");
+            }
+        }
+        else
+        {
+            crError("Render SPU: no display, aborting");
+        }
+        crFreeHashtable(render_spu.pWinToInfoTable, NULL);
+        render_spu.pWinToInfoTable = NULL;
+    }
+    else
+    {
+        crError("crAllocHashtable failed");
+    }
+    return rc;
+}
+
+static void renderspuWinCmdTerm()
+{
+    /* the window is not in the table, this will just ensure the key is freed */
+    crHashtableDelete(render_spu.windowTable, CR_RENDER_WINCMD_ID, NULL);
+    renderspuWindowTerm(&render_spu.WinCmdWindow);
+    crFreeHashtable(render_spu.pWinToInfoTable, NULL);
+    /* we do not have visual destroy functionality 
+     * @todo implement */
+}
+
+
+static bool renderspuWinCmdProcess(CR_RENDER_WINCMD* pWinCmd)
+{
+    bool fExit = false;
+    /* process commands */
+    switch (pWinCmd->enmCmd)
+    {
+        case CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE:
+            crHashtableAdd(render_spu.pWinToInfoTable, pWinCmd->pWindow->window, pWinCmd->pWindow);
+            XSelectInput(render_spu.WinCmdVisual.dpy, pWinCmd->pWindow->window, ExposureMask);
+            pWinCmd->rc = VINF_SUCCESS;
+            break;
+        case CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY:
+            crHashtableDelete(render_spu.pWinToInfoTable, pWinCmd->pWindow->window, NULL);
+            pWinCmd->rc = VINF_SUCCESS;
+            break;
+        case CR_RENDER_WINCMD_TYPE_NOP:
+            pWinCmd->rc = VINF_SUCCESS;
+            break;
+        case CR_RENDER_WINCMD_TYPE_EXIT:
+            renderspuWinCmdTerm();
+            pWinCmd->rc = VINF_SUCCESS;
+            fExit = true;
+            pWinCmd->rc = VINF_SUCCESS;
+            break;
+        case CR_RENDER_WINCMD_TYPE_WIN_CREATE:
+            pWinCmd->rc = renderspuWinCmdWinCreate(pWinCmd->pWindow);
+            break;  
+        case CR_RENDER_WINCMD_TYPE_WIN_DESTROY:
+            pWinCmd->rc = renderspuWinCmdWinDestroy(pWinCmd->pWindow);
+            break;
+        default:
+            crError("unknown WinCmd command! %d", pWinCmd->enmCmd);
+            pWinCmd->rc = VERR_INVALID_PARAMETER;
+            break;
+    }
+
+    RTSemEventSignal(render_spu.hWinCmdCompleteEvent);
+    return fExit;
+}
+
+static DECLCALLBACK(int) renderspuWinCmdThreadProc(RTTHREAD ThreadSelf, void *pvUser)
+{
+    int rc;
+    bool fExit = false;
+    crDebug("RenderSPU: Window thread started (%x)", crThreadID());
+    
+    rc = renderspuWinCmdInit();
+
+    /* notify the main cmd thread that we have started */
+    RTSemEventSignal(render_spu.hWinCmdCompleteEvent);
+    
+    if (!RT_SUCCESS(rc))
+    {
+        CRASSERT(!render_spu.pWinToInfoTable);
+        return rc;
+    }
+
+    do
+    {
+    	XEvent event;
+    	XNextEvent(render_spu.WinCmdVisual.dpy, &event);
+        
+    	switch (event.type)
+    	{
+            case ClientMessage:
+            {
+                CRASSERT(event.xclient.window == render_spu.WinCmdWindow.window);
+                if (event.xclient.window == render_spu.WinCmdWindow.window)
+                {
+                    if (render_spu.WinCmdAtom == event.xclient.message_type)
+                    {
+                        CR_RENDER_WINCMD *pWinCmd;
+                        memcpy(&pWinCmd, event.xclient.data.b, sizeof (pWinCmd));
+                        fExit = renderspuWinCmdProcess(pWinCmd);
+                    }
+                }
+                
+                break;
+            }
+            case Expose:
+            {
+                if (!event.xexpose.count)
+                {    
+                    WindowInfo *pWindow = (WindowInfo*)crHashtableSearch(render_spu.pWinToInfoTable, event.xexpose.window);
+                    if (pWindow)
+                    {
+                        struct VBOXVR_SCR_COMPOSITOR * pCompositor;
+
+                        pCompositor = renderspuVBoxCompositorAcquire(pWindow);
+                        if (pCompositor)
+                        {
+                            renderspuVBoxPresentCompositionGeneric(pWindow, pCompositor, NULL);
+                            renderspuVBoxCompositorRelease(pWindow);
+                        }
+                    }
+                }
+                break;
+            }
+            default:
+                break;
+    	}
+    } while (!fExit);
+
+    return 0;
+}
+
+static int renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE enmCmd, WindowInfo *pWindow)
+{
+    Status status;
+    XEvent event;
+    CR_RENDER_WINCMD WinCmd, *pWinCmd;
+    int rc;
+    
+    pWinCmd = &WinCmd;
+    pWinCmd->enmCmd = enmCmd;
+    pWinCmd->rc = VERR_GENERAL_FAILURE;
+    pWinCmd->pWindow = pWindow;
+    
+    memset(&event, 0, sizeof (event));
+    event.type = ClientMessage;
+    event.xclient.window = render_spu.WinCmdWindow.window;
+    event.xclient.message_type = render_spu.WinCmdAtom;
+    event.xclient.format = 8;
+    memcpy(event.xclient.data.b, &pWinCmd, sizeof (pWinCmd));
+    
+    status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, StructureNotifyMask, &event);
+    if (!status)
+    {
+        Assert(0);
+        crWarning("XSendEvent returned null");
+        return VERR_GENERAL_FAILURE;
+    }
+    
+    XFlush(render_spu.pCommunicationDisplay);
+    rc = RTSemEventWaitNoResume(render_spu.hWinCmdCompleteEvent, RT_INDEFINITE_WAIT);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("RTSemEventWaitNoResume failed rc %d", rc);
+	return rc;
+    }
+    return pWinCmd->rc;
+}
+
+int renderspu_SystemInit()
+{
+    const char * dpyName;
+    int rc = VERR_GENERAL_FAILURE;
+    
+    if (!render_spu.use_glxchoosevisual) {
+        /* sometimes want to set this option with ATI drivers */
+        render_spu.ws.glXChooseVisual = NULL;
+    }
+
+    /* enable multi-threading */
+    XInitThreads();
+
+    /* setup communication display connection */
+    dpyName = renderspuGetDisplayName();
+    if (!dpyName)
+    {
+        crWarning("no display name, aborting");
+        return VERR_GENERAL_FAILURE;
+    }
+    
+    render_spu.pCommunicationDisplay = XOpenDisplay(dpyName);
+    if (!render_spu.pCommunicationDisplay)
+    {
+        crWarning( "Couldn't open X display named '%s'", dpyName );
+        return VERR_GENERAL_FAILURE;
+    }
+
+    if ( !render_spu.ws.glXQueryExtension( render_spu.pCommunicationDisplay, NULL, NULL ) )
+    {
+        crWarning( "Render SPU: Display %s doesn't support GLX", dpyName );
+        return VERR_GENERAL_FAILURE;
+    }
+
+    rc = RTSemEventCreate(&render_spu.hWinCmdCompleteEvent);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTThreadCreate(&render_spu.hWinCmdThread, renderspuWinCmdThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxCrWinCmd");
+	if (RT_SUCCESS(rc))
+	{
+            rc = RTSemEventWait(render_spu.hWinCmdCompleteEvent, RT_INDEFINITE_WAIT);
+	    if (RT_SUCCESS(rc))
+	    {
+                return VINF_SUCCESS;
+            }
+	    else
+	    {
+                crWarning("RTSemEventWait failed rc %d", rc);
+            }
+
+	    RTThreadWait(render_spu.hWinCmdThread, RT_INDEFINITE_WAIT, NULL);
+        }
+        else
+        {
+            crWarning("RTThreadCreate failed rc %d", rc);
+        }
+	RTSemEventDestroy(render_spu.hWinCmdCompleteEvent);
+    }
+    else
+    {
+        crWarning("RTSemEventCreate failed rc %d", rc);
+    }
+    
+    return rc;
+}
+
+int renderspu_SystemTerm()
+{
+	int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_EXIT, NULL);
+	if (!RT_SUCCESS(rc))
+	{
+	    crWarning("renderspuWinCmdSubmit EXIT failed rc %d", rc);
+	    return rc;
+	}
+
+	RTThreadWait(render_spu.hWinCmdThread, RT_INDEFINITE_WAIT, NULL);
+	RTSemEventDestroy(render_spu.hWinCmdCompleteEvent);
+	return VINF_SUCCESS;
+}
 
 GLboolean
@@ -421,11 +732,5 @@
 #endif
     
-    if (render_spu.display_string[0])
-        dpyName = render_spu.display_string;
-    else if (visual->displayName[0])
-        dpyName = visual->displayName;
-    else
-        dpyName = NULL;
-
+    dpyName = renderspuGetDisplayName();
     if (!dpyName)
     {
@@ -433,4 +738,5 @@
         return GL_FALSE;
     }
+
 
     crInfo("Render SPU: Opening display %s", dpyName);
@@ -850,4 +1156,10 @@
 
     XSync(dpy, 0);
+    
+    if (window->BltInfo.Base.id != CR_RENDER_WINCMD_ID)
+    {
+        int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_WIN_ON_CREATE, window);
+        AssertRC(rc);
+    }
 
     return GL_TRUE;
@@ -941,4 +1253,9 @@
              */
             if (!window->nativeWindow) {
+                if (window->BltInfo.Base.id != CR_RENDER_WINCMD_ID)
+                {
+                    int rc = renderspuWinCmdSubmit(CR_RENDER_WINCMD_TYPE_WIN_ON_DESTROY, window);
+                    AssertRC(rc);
+                }
                 XDestroyWindow(window->visual->dpy, window->window);
                 XSync(window->visual->dpy, 0);
@@ -1639,5 +1956,46 @@
 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
 {
-    renderspuVBoxPresentCompositionGeneric(window, pCompositor, pChangedEntry);
+    /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl,
+     * here it forces rendering in WinCmd thread rather than a Main thread.
+     * it is used for debugging only in any way actually.
+     * @todo: change to some more generic macro name */
+#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
+    struct VBOXVR_SCR_COMPOSITOR *pCurCompositor;
+    /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */
+    int rc = renderspuVBoxCompositorTryAcquire(window, &pCurCompositor);
+    if (RT_SUCCESS(rc))
+    {
+        Assert(pCurCompositor == pCompositor);
+        renderspuVBoxPresentCompositionGeneric(window, pCompositor, pChangedEntry);
+        renderspuVBoxCompositorRelease(window);
+    }
+    else if (rc == VERR_SEM_BUSY)
+#endif
+    {
+        Status status;
+        XEvent event;
+        render_spu.self.Flush();
+        renderspuVBoxPresentBlitterEnsureCreated(window);
+
+        crMemset(&event, 0, sizeof (event));
+        event.type = Expose;
+        event.xexpose.window = window->window;
+        event.xexpose.width = window->BltInfo.width;
+        event.xexpose.height = window->BltInfo.height;
+        status = XSendEvent(render_spu.pCommunicationDisplay, render_spu.WinCmdWindow.window, False, 0, &event);
+        if (!status)
+        {
+            Assert(0);
+            crWarning("XSendEvent returned null");
+        }
+        XFlush(render_spu.pCommunicationDisplay);
+    }
+#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
+    else
+    {
+        /* this is somewhat we do not expect */
+        crWarning("renderspuVBoxCompositorTryAcquire failed rc %d", rc);
+    }
+#endif
 }
 
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c	(revision 44813)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c	(revision 44860)
@@ -192,11 +192,4 @@
     numFuncs += numSpecial;
 
-#ifdef GLX
-    if (!render_spu.use_glxchoosevisual) {
-        /* sometimes want to set this option with ATI drivers */
-        render_spu.ws.glXChooseVisual = NULL;
-    }
-#endif
-
     render_spu.contextTable = crAllocHashtableEx(1, INT32_MAX);
     render_spu.windowTable = crAllocHashtableEx(1, INT32_MAX);
@@ -227,4 +220,15 @@
 
     CRASSERT(render_spu.default_visual & CR_RGB_BIT);
+    
+#ifdef GLX
+    {
+        int rc = renderspu_SystemInit();
+        if (!RT_SUCCESS(rc))
+        {
+            crError("renderspu_SystemInit failed rc %d", rc);
+            return NULL;
+        }
+    }
+#endif
 
 #ifdef USE_OSMESA
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c	(revision 44813)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c	(revision 44860)
@@ -1247,4 +1247,9 @@
 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
 {
+    /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl,
+     * here it forces rendering in WinCmd thread rather than a Main thread.
+     * it is used for debugging only in any way actually.
+     * @todo: change to some more generic macro name */
+#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
     struct VBOXVR_SCR_COMPOSITOR *pCurCompositor;
     /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */
@@ -1257,4 +1262,5 @@
     }
     else if (rc == VERR_SEM_BUSY)
+#endif
     {
         render_spu.self.Flush();
@@ -1262,4 +1268,5 @@
         RedrawWindow(window->hWnd, NULL, NULL, RDW_INTERNALPAINT);
     }
+#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
     else
     {
@@ -1267,4 +1274,5 @@
         crWarning("renderspuVBoxCompositorTryAcquire failed rc %d", rc);
     }
+#endif
 }
 
