Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22795)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22796)
@@ -939,4 +939,6 @@
     }
 
+    size_t size() {return mSurfaces.size(); }
+
     void remove(VBoxVHWASurfaceBase *pSurf)
     {
@@ -985,4 +987,12 @@
 //        mSurfPrimary = pVga;
         mOverlays.clear();
+        return old;
+    }
+
+    VBoxVHWASurfaceBase * updateVGA(VBoxVHWASurfaceBase * pVga)
+    {
+        VBoxVHWASurfaceBase * old = mSurfVGA;
+        Assert(old);
+        mSurfVGA = pVga;
         return old;
     }
@@ -1114,6 +1124,6 @@
     const VBOXVHWACALLBACKINFO & op() const {return u.mCallback; }
 
-private:
     VBoxVHWACommandElement * mpNext;
+private:
     VBOXVHWA_PIPECMD_TYPE mType;
     union
@@ -1123,8 +1133,4 @@
     }u;
     QRect                 mRect;
-
-    friend class VBoxVHWACommandElementPipe;
-    friend class VBoxVHWACommandElementStack;
-    friend class VBoxGLWidget;
 };
 
@@ -1202,4 +1208,23 @@
     VBoxVHWACommandElement *mpFirst;
 };
+
+class VBoxVHWACommandElementProcessor
+{
+public:
+    VBoxVHWACommandElementProcessor(VBoxConsoleView *aView);
+    ~VBoxVHWACommandElementProcessor();
+    void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData);
+    class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
+
+private:
+    RTCRITSECT mCritSect;
+    class VBoxVHWACommandProcessEvent *mpFirstEvent;
+    class VBoxVHWACommandProcessEvent *mpLastEvent;
+    VBoxConsoleView *mView;
+    bool mbNewEvent;
+    VBoxVHWACommandElementStack mFreeElements;
+    VBoxVHWACommandElement mElementsBuffer[2048];
+};
+
 
 class VBoxGLWidget : public QGLWidget
@@ -1247,5 +1272,5 @@
     void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re); }
 
-    void vboxProcessVHWACommands(class VBoxVHWACommandProcessEvent * pEvent) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pEvent);}
+    void vboxProcessVHWACommands(class VBoxVHWACommandElementProcessor * pPipe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pPipe);}
 #ifdef VBOX_WITH_VIDEOHWACCEL
     void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
@@ -1254,6 +1279,4 @@
 
     VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
-
-    void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData);
 
     static void doSetupMatrix(const QSize & aSize, bool bInverted);
@@ -1333,9 +1356,6 @@
     void vboxExecOnResize(PFNVBOXQGLOP pfn, void* pContext);
 
-    void cmdPipeInit();
-    void cmdPipeDelete();
     void vboxDoProcessVHWACommands(void *pContext);
 
-    class VBoxVHWACommandElement * detachCmdList(class VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free);
     class VBoxVHWACommandElement * processCmdList(class VBoxVHWACommandElement * pCmd);
 
@@ -1354,13 +1374,6 @@
     ulong  mPixelFormat;
     bool   mUsesGuestVRAM;
-    bool   mbVGASurfCreated;
+//    bool   mbVGASurfCreated;
     QRect mViewport;
-
-    RTCRITSECT mCritSect;
-    class VBoxVHWACommandProcessEvent *mpFirstEvent;
-    class VBoxVHWACommandProcessEvent *mpLastEvent;
-    bool mbNewEvent;
-    VBoxVHWACommandElementStack mFreeElements;
-    VBoxVHWACommandElement mElementsBuffer[2048];
 
     VBoxConsoleView *mView;
@@ -1413,4 +1426,6 @@
 //    void vboxMakeCurrent();
     VBoxGLWidget * vboxWidget();
+
+    VBoxVHWACommandElementProcessor mCmdPipe;
 };
 
@@ -1441,8 +1456,11 @@
     void vboxUpdateOverlayPosition(const QPoint & pos);
     void vboxUpdateOverlay(const QRect & rect, bool show);
+    VBoxVHWACommandElement * processCmdList(VBoxVHWACommandElement * pCmd);
     VBoxGLWidget *mpOverlayWidget;
     bool mGlOn;
     bool mOverlayVisible;
     VBoxVHWADirtyRect mMainDirtyRect;
+
+    VBoxVHWACommandElementProcessor mCmdPipe;
 };
 #endif
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp	(revision 22795)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp	(revision 22796)
@@ -806,9 +806,8 @@
     }
     VBoxVHWACommandElementPipe & pipe() { return mCmdPipe; }
+
+    VBoxVHWACommandProcessEvent *mpNext;
 private:
     VBoxVHWACommandElementPipe mCmdPipe;
-    VBoxVHWACommandProcessEvent *mpNext;
-
-    friend class VBoxGLWidget;
 };
 
@@ -2931,5 +2930,6 @@
 
 VBoxQGLFrameBuffer::VBoxQGLFrameBuffer (VBoxConsoleView *aView) :
-    VBoxFrameBuffer (aView)
+    VBoxFrameBuffer (aView),
+    mCmdPipe(aView)
 {
 //    mWidget = new GLWidget(aView->viewport());
@@ -2956,5 +2956,5 @@
 #else
     QRect r(aX, aY, aW, aH);
-    vboxWidget()->postCmd(VBOXVHWA_PIPECMD_PAINT, &r);
+    mCmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r);
 #endif
     return S_OK;
@@ -3022,5 +3022,5 @@
 void VBoxQGLFrameBuffer::doProcessVHWACommand(QEvent * pEvent)
 {
-    vboxWidget()->vboxProcessVHWACommands((VBoxVHWACommandProcessEvent*)pEvent);
+    vboxWidget()->vboxProcessVHWACommands(&mCmdPipe);
 }
 
@@ -3032,10 +3032,9 @@
     mPixelFormat(0),
     mUsesGuestVRAM(false),
-    mbVGASurfCreated(false),
+//    mbVGASurfCreated(false),
     mView(aView),
     mConstructingList(NULL),
     mcRemaining2Contruct(0)
 {
-    cmdPipeInit();
     mpMngr = new VBoxVHWAGlProgramMngr();
 //        /* No need for background drawing */
@@ -3060,25 +3059,6 @@
 {
     delete mpMngr;
-    cmdPipeDelete();
-}
-
-void VBoxGLWidget::cmdPipeInit()
-{
-    int rc = RTCritSectInit(&mCritSect);
-    AssertRC(rc);
-
-    mpFirstEvent = NULL;
-    mpLastEvent = NULL;
-    mbNewEvent = false;
-    for(int i = RT_ELEMENTS(mElementsBuffer) - 1; i >= 0; i--)
-    {
-        mFreeElements.push(&mElementsBuffer[i]);
-    }
-}
-
-void VBoxGLWidget::cmdPipeDelete()
-{
-    RTCritSectDelete(&mCritSect);
-}
+}
+
 
 void VBoxGLWidget::doSetupMatrix(const QSize & aSize, bool bInverted)
@@ -3127,92 +3107,4 @@
 }
 
-void VBoxGLWidget::postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
-{
-    /* 1. lock*/
-    RTCritSectEnter(&mCritSect);
-    VBoxVHWACommandElement * pCmd = mFreeElements.pop();
-    if(!pCmd)
-    {
-        VBOXQGLLOG(("!!!no more free elements!!!\n"));
-#ifdef VBOXQGL_PROF_BASE
-        RTCritSectLeave(&mCritSect);
-        return;
-#else
-    //TODO:
-#endif
-    }
-    pCmd->setData(aType, pvData);
-    /* 2. if can add to current*/
-    if(!mbNewEvent)
-    {
-        /* 3. if event is being processed (event != 0) */
-        if(mpLastEvent)
-        {
-            /* 3.a add cmd to event */
-            mpLastEvent->pipe().put(pCmd);
-            /* 3.b unlock and return */
-            RTCritSectLeave(&mCritSect);
-            return;
-        }
-    }
-
-    /* we're here because the cmd was NOT be added to the current event queue */
-    /* 4. unlock*/
-    RTCritSectLeave(&mCritSect);
-    /* 5. create & initialize new Event */
-    VBoxVHWACommandProcessEvent *pCurrentEvent = new VBoxVHWACommandProcessEvent(pCmd);
-    /* 6. lock */
-    RTCritSectEnter(&mCritSect);
-    /* 7. if no current event set event as current */
-    if(!mpLastEvent)
-    {
-        Assert(!mpFirstEvent);
-        mpFirstEvent = pCurrentEvent;
-        mpLastEvent = pCurrentEvent;
-        pCurrentEvent->mpNext = NULL;
-    }
-    else
-    {
-        mpLastEvent->mpNext = pCurrentEvent;
-        mpLastEvent = pCurrentEvent;
-    }
-    /* 8. reset blocking events counter */
-    mbNewEvent = false;
-    /* 9. unlock */
-    RTCritSectLeave(&mCritSect);
-    /* 10. post event */
-    QApplication::postEvent (mView, pCurrentEvent);
-}
-
-VBoxVHWACommandElement * VBoxGLWidget::detachCmdList(VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free)
-{
-    VBoxVHWACommandElement * pList = NULL;
-    RTCritSectEnter(&mCritSect);
-    if(pFirst2Free)
-    {
-        mFreeElements.pusha(pFirst2Free, pLast2Free);
-    }
-    if(mpFirstEvent)
-    {
-        pList = mpFirstEvent->pipe().detachList();
-        if(!pList)
-        {
-            VBoxVHWACommandProcessEvent *pNext = mpFirstEvent->mpNext;
-            if(pNext)
-            {
-                mpFirstEvent = pNext;
-            }
-            else
-            {
-                mpFirstEvent = NULL;
-                mpLastEvent = NULL;
-            }
-        }
-    }
-    RTCritSectLeave(&mCritSect);
-
-    return pList;
-}
-
 VBoxVHWACommandElement * VBoxGLWidget::processCmdList(VBoxVHWACommandElement * pCmd)
 {
@@ -3248,11 +3140,11 @@
 void VBoxGLWidget::vboxDoProcessVHWACommands(void *pContext)
 {
-    Q_UNUSED(pContext);
-    VBoxVHWACommandElement * pFirst = detachCmdList(NULL, NULL);
+    VBoxVHWACommandElementProcessor * pPipe = (VBoxVHWACommandElementProcessor*)pContext;
+    VBoxVHWACommandElement * pFirst = pPipe->detachCmdList(NULL, NULL);
     do
     {
         VBoxVHWACommandElement * pLast = processCmdList(pFirst);
 
-        pFirst = detachCmdList(pFirst, pLast);
+        pFirst = pPipe->detachCmdList(pFirst, pLast);
     } while(pFirst);
 
@@ -3277,5 +3169,5 @@
 //    QApplication::postEvent (mView,
 //                             new VBoxVHWACommandProcessEvent (pCmd));
-    vboxWidget()->postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
+    mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
     return S_OK;
 }
@@ -3518,11 +3410,15 @@
     {
         bPrimary = true;
-        if(!mbVGASurfCreated)
-        {
-            VBoxVHWASurfaceBase * pVga = vboxGetVGASurface();
-            if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
+        VBoxVHWASurfaceBase * pVga = vboxGetVGASurface();
+
+        if(pVga->handle() == VBOXVHWA_SURFHANDLE_INVALID)
+        {
+            Assert(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB);
+//            if(pCmd->SurfInfo.PixelFormat.flags & VBOXVHWA_PF_RGB)
             {
-                if(pCmd->SurfInfo.width == pVga->width()
-                        && pCmd->SurfInfo.height == pVga->height())
+                Assert(pCmd->SurfInfo.width == pVga->width());
+                Assert(pCmd->SurfInfo.height == pVga->height());
+//                if(pCmd->SurfInfo.width == pVga->width()
+//                        && pCmd->SurfInfo.height == pVga->height())
                 {
                     VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.c.rgbBitCount,
@@ -3530,5 +3426,6 @@
                                                 pCmd->SurfInfo.PixelFormat.m2.rgbGBitMask,
                                                 pCmd->SurfInfo.PixelFormat.m3.rgbBBitMask);
-                    if(pVga->colorFormat().equals(format))
+                    Assert(pVga->colorFormat().equals(format));
+//                    if(pVga->colorFormat().equals(format))
                     {
                         surf = pVga;
@@ -3542,5 +3439,5 @@
                         surf->setDefaultSrcOverlayCKey(pDstOverlayCKey);
                         surf->resetDefaultSrcOverlayCKey();
-                        mbVGASurfCreated = true;
+//                        mbVGASurfCreated = true;
                     }
                 }
@@ -3613,10 +3510,15 @@
         else if(bPrimary)
         {
-            Assert(mbVGASurfCreated);
+            VBoxVHWASurfaceBase * pVga = vboxGetVGASurface();
+            Assert(pVga->handle() != VBOXVHWA_SURFHANDLE_INVALID);
+            Assert(pVga != surf);
+//            Assert(mbVGASurfCreated);
             mDisplay.getVGA()->getComplexList()->add(surf);
-            if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_VISIBLE)
+            Assert(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_VISIBLE);
+//            if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_VISIBLE)
             {
                 Assert(surf->getComplexList() == mDisplay.getVGA()->getComplexList());
                 surf->getComplexList()->setCurrentVisible(surf);
+                mDisplay.updateVGA(surf);
             }
         }
@@ -3631,4 +3533,6 @@
         }
     }
+
+    Assert(mDisplay.getVGA() == mDisplay.getPrimary());
 
     /* tell the guest how we think the memory is organized */
@@ -3666,37 +3570,55 @@
 {
     VBoxVHWASurfaceBase *pSurf = handle2Surface(pCmd->u.in.hSurf);
+    VBoxVHWASurfList *pList = pSurf->getComplexList();
+    Assert(pSurf->handle() != VBOXVHWA_SURFHANDLE_INVALID);
+
     VBOXQGLLOG_ENTER(("pSurf (0x%x)\n",pSurf));
-    if(pSurf != mDisplay.getVGA())
-    {
-        VBoxVHWASurfList *pList = pSurf->getComplexList();
-        if(pList)
-        {
-            pList->remove(pSurf);
-            if(pList->surfaces().empty())
+    if(pList != mDisplay.getVGA()->getComplexList())
+    {
+        Assert(pList);
+        pList->remove(pSurf);
+        if(pList->surfaces().empty())
+        {
+            mDisplay.removeOverlay(pList);
+//                Assert(mConstructingList != pList);
+            if(pList == mConstructingList)
             {
-                mDisplay.removeOverlay(pList);
-//                Assert(mConstructingList != pList);
-                if(pList == mConstructingList)
+                mConstructingList = NULL;
+                mcRemaining2Contruct = 0;
+            }
+            delete pList;
+        }
+
+        delete(pSurf);
+    }
+    else
+    {
+        Assert(pList->size() >= 1);
+        if(pList->size() > 1)
+        {
+            if(pSurf == mDisplay.getVGA())
+            {
+                const SurfList & surfaces = pList->surfaces();
+
+                for (SurfList::const_iterator it = surfaces.begin();
+                         it != surfaces.end(); ++ it)
                 {
-                    mConstructingList = NULL;
-                    mcRemaining2Contruct = 0;
-                }
-                delete pList;
-            }
-            else if(pList == mDisplay.getVGA()->getComplexList())
-            {
-                if(pList->current() == NULL)
-                {
-                    pList->setCurrentVisible(mDisplay.getVGA());
+                    VBoxVHWASurfaceBase *pCurSurf = (*it);
+                    if(pCurSurf != pSurf)
+                    {
+                        mDisplay.updateVGA(pCurSurf);
+                        pList->setCurrentVisible(pCurSurf);
+                        break;
+                    }
                 }
             }
-        }
-
-        delete(pSurf);
-    }
-    else
-    {
-        Assert(mbVGASurfCreated);
-        mbVGASurfCreated = false;
+
+            pList->remove(pSurf);
+            delete(pSurf);
+        }
+        else
+        {
+            pSurf->setHandle(VBOXVHWA_SURFHANDLE_INVALID);
+        }
     }
 
@@ -3934,4 +3856,16 @@
         vboxCheckUpdateAddress (pDstSurf, pCmd->u.in.offDstSurface);
         VBOXQGLLOG(("pDstSurf (0x%x)\n",pDstSurf));
+        Assert(pDstSurf == mDisplay.getVGA());
+        Assert(mDisplay.getVGA() == mDisplay.getPrimary());
+        Assert(pDstSurf->getComplexList() == mDisplay.getVGA()->getComplexList());
+
+        if(pCmd->u.in.flags & VBOXVHWA_OVER_SHOW)
+        {
+            if(pDstSurf != mDisplay.getPrimary())
+            {
+                mDisplay.updateVGA(pDstSurf);
+                pDstSurf->getComplexList()->setCurrentVisible(pDstSurf);
+            }
+        }
     }
 
@@ -4468,5 +4402,5 @@
     uint32_t cPrimary = (uint32_t)primaryList.size();
     Assert(cPrimary >= 1);
-    if(!mbVGASurfCreated)
+    if(mDisplay.getVGA()->handle() == VBOXVHWA_SURFHANDLE_INVALID)
     {
         cPrimary -= 1;
@@ -4478,5 +4412,5 @@
     {
         VBoxVHWASurfaceBase *pSurf = *pr;
-        bool bVga = (pSurf == mDisplay.getVGA());
+//        bool bVga = (pSurf == mDisplay.getVGA());
         bool bVisible = (pSurf == mDisplay.getPrimary());
         uint32_t flags = VBOXVHWA_SCAPS_PRIMARYSURFACE;
@@ -4484,5 +4418,5 @@
             flags |= VBOXVHWA_SCAPS_VISIBLE;
 
-        if(mbVGASurfCreated || !bVga)
+        if(pSurf->handle() != VBOXVHWA_SURFHANDLE_INVALID)
         {
             rc = vhwaSaveSurface(pSSM, *pr, flags);    AssertRC(rc);
@@ -4491,4 +4425,8 @@
             Assert(cPrimary < UINT32_MAX / 2);
 #endif
+        }
+        else
+        {
+            Assert(pSurf == mDisplay.getVGA());
         }
     }
@@ -5290,5 +5228,6 @@
     : VBoxQImageFrameBuffer(aView),
       mGlOn(false),
-      mOverlayVisible(false)
+      mOverlayVisible(false),
+      mCmdPipe(aView)
 {
     mpOverlayWidget = new VBoxGLWidget (aView, aView->viewport());
@@ -5305,5 +5244,5 @@
 //    QApplication::postEvent (mView,
 //                             new VBoxVHWACommandProcessEvent (pCmd));
-    mpOverlayWidget->postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
+    mCmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
     return S_OK;
 //    return E_NOTIMPL;
@@ -5312,5 +5251,12 @@
 void VBoxQGLOverlayFrameBuffer::doProcessVHWACommand(QEvent * pEvent)
 {
-    mpOverlayWidget->vboxProcessVHWACommands((VBoxVHWACommandProcessEvent*)pEvent);
+    Q_UNUSED(pEvent);
+    VBoxVHWACommandElement * pFirst = mCmdPipe.detachCmdList(NULL, NULL);
+    do
+    {
+        VBoxVHWACommandElement * pLast = processCmdList(pFirst);
+
+        pFirst = mCmdPipe.detachCmdList(pFirst, pLast);
+    } while(pFirst);
 }
 
@@ -5318,5 +5264,7 @@
                          ULONG aW, ULONG aH)
 {
-    return VBoxQImageFrameBuffer::NotifyUpdate(aX, aY, aW, aH);
+    QRect r(aX, aY, aW, aH);
+    mCmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r);
+    return S_OK;
 }
 
@@ -5494,4 +5442,145 @@
     }
 }
-#endif
-#endif
+
+VBoxVHWACommandElement * VBoxQGLOverlayFrameBuffer::processCmdList(VBoxVHWACommandElement * pCmd)
+{
+    VBoxVHWACommandElement * pCur;
+    do
+    {
+        pCur = pCmd;
+        switch(pCmd->type())
+        {
+        case VBOXVHWA_PIPECMD_PAINT:
+//            vboxDoUpdateRect(&pCmd->rect());
+            break;
+#ifdef VBOX_WITH_VIDEOHWACCEL
+        case VBOXVHWA_PIPECMD_VHWA:
+//            vboxDoVHWACmd(pCmd->vhwaCmd());
+            break;
+        case VBOXVHWA_PIPECMD_OP:
+        {
+            const VBOXVHWACALLBACKINFO & info = pCmd->op();
+            (info.pThis->*(info.pfnCallback))(info.pContext);
+            break;
+        }
+#endif
+        default:
+            Assert(0);
+        }
+        pCmd = pCmd->mpNext;
+    } while(pCmd);
+
+    return pCur;
+}
+
+#endif
+
+VBoxVHWACommandElementProcessor::VBoxVHWACommandElementProcessor(VBoxConsoleView *aView)
+{
+    int rc = RTCritSectInit(&mCritSect);
+    AssertRC(rc);
+
+    mpFirstEvent = NULL;
+    mpLastEvent = NULL;
+    mbNewEvent = false;
+    mView = aView;
+    for(int i = RT_ELEMENTS(mElementsBuffer) - 1; i >= 0; i--)
+    {
+        mFreeElements.push(&mElementsBuffer[i]);
+    }
+}
+
+VBoxVHWACommandElementProcessor::~VBoxVHWACommandElementProcessor()
+{
+    RTCritSectDelete(&mCritSect);
+}
+
+void VBoxVHWACommandElementProcessor::postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData)
+{
+    /* 1. lock*/
+    RTCritSectEnter(&mCritSect);
+    VBoxVHWACommandElement * pCmd = mFreeElements.pop();
+    if(!pCmd)
+    {
+        VBOXQGLLOG(("!!!no more free elements!!!\n"));
+#ifdef VBOXQGL_PROF_BASE
+        RTCritSectLeave(&mCritSect);
+        return;
+#else
+    //TODO:
+#endif
+    }
+    pCmd->setData(aType, pvData);
+    /* 2. if can add to current*/
+    if(!mbNewEvent)
+    {
+        /* 3. if event is being processed (event != 0) */
+        if(mpLastEvent)
+        {
+            /* 3.a add cmd to event */
+            mpLastEvent->pipe().put(pCmd);
+            /* 3.b unlock and return */
+            RTCritSectLeave(&mCritSect);
+            return;
+        }
+    }
+
+    /* we're here because the cmd was NOT be added to the current event queue */
+    /* 4. unlock*/
+    RTCritSectLeave(&mCritSect);
+    /* 5. create & initialize new Event */
+    VBoxVHWACommandProcessEvent *pCurrentEvent = new VBoxVHWACommandProcessEvent(pCmd);
+    /* 6. lock */
+    RTCritSectEnter(&mCritSect);
+    /* 7. if no current event set event as current */
+    if(!mpLastEvent)
+    {
+        Assert(!mpFirstEvent);
+        mpFirstEvent = pCurrentEvent;
+        mpLastEvent = pCurrentEvent;
+        pCurrentEvent->mpNext = NULL;
+    }
+    else
+    {
+        mpLastEvent->mpNext = pCurrentEvent;
+        mpLastEvent = pCurrentEvent;
+    }
+    /* 8. reset blocking events counter */
+    mbNewEvent = false;
+    /* 9. unlock */
+    RTCritSectLeave(&mCritSect);
+    /* 10. post event */
+    QApplication::postEvent (mView, pCurrentEvent);
+}
+
+VBoxVHWACommandElement * VBoxVHWACommandElementProcessor::detachCmdList(VBoxVHWACommandElement * pFirst2Free, VBoxVHWACommandElement * pLast2Free)
+{
+    VBoxVHWACommandElement * pList = NULL;
+    RTCritSectEnter(&mCritSect);
+    if(pFirst2Free)
+    {
+        mFreeElements.pusha(pFirst2Free, pLast2Free);
+    }
+    if(mpFirstEvent)
+    {
+        pList = mpFirstEvent->pipe().detachList();
+        if(!pList)
+        {
+            VBoxVHWACommandProcessEvent *pNext = mpFirstEvent->mpNext;
+            if(pNext)
+            {
+                mpFirstEvent = pNext;
+            }
+            else
+            {
+                mpFirstEvent = NULL;
+                mpLastEvent = NULL;
+            }
+        }
+    }
+    RTCritSectLeave(&mCritSect);
+
+    return pList;
+}
+
+#endif
