Index: /trunk/include/VBox/HostServices/VBoxCrOpenGLSvc.h
===================================================================
--- /trunk/include/VBox/HostServices/VBoxCrOpenGLSvc.h	(revision 41403)
+++ /trunk/include/VBox/HostServices/VBoxCrOpenGLSvc.h	(revision 41404)
@@ -42,4 +42,5 @@
 #define SHCRGL_HOST_FN_CRHGSMI_CTL (11)
 #endif
+#define SHCRGL_HOST_FN_VIEWPORT_CHANGED (15)
 #define SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT (20)
 /* crOpenGL guest functions */
@@ -67,5 +68,5 @@
 #define SHCRGL_CPARMS_WRITE_READ_BUFFERED (3)
 #define SHCRGL_CPARMS_SET_OUTPUT_REDIRECT (1)
-
+#define SHCRGL_CPARMS_VIEWPORT_CHANGED (5)
 
 /* @todo Move to H3DOR.h begin */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 41403)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 41404)
@@ -791,14 +791,21 @@
 }
 
+void UIMachineView::scrollContentsBy(int dx, int dy)
+{
 #ifdef VBOX_WITH_VIDEOHWACCEL
-void UIMachineView::scrollContentsBy(int dx, int dy)
-{
     if (m_pFrameBuffer)
     {
         m_pFrameBuffer->viewportScrolled(dx, dy);
     }
+#endif /* VBOX_WITH_VIDEOHWACCEL */
     QAbstractScrollArea::scrollContentsBy(dx, dy);
-}
-#endif /* VBOX_WITH_VIDEOHWACCEL */
+
+    session().GetConsole().GetDisplay().ViewportChanged(screenId(),
+                            contentsX(),
+                            contentsY(),
+                            contentsWidth(),
+                            contentsHeight());
+}
+
 
 #ifdef Q_WS_MAC
@@ -1003,5 +1010,4 @@
 bool UIMachineView::eventFilter(QObject *pWatched, QEvent *pEvent)
 {
-#ifdef VBOX_WITH_VIDEOHWACCEL
     if (pWatched == viewport())
     {
@@ -1010,6 +1016,14 @@
             case QEvent::Resize:
             {
+                QResizeEvent* pResizeEvent = static_cast<QResizeEvent*>(pEvent);
+#ifdef VBOX_WITH_VIDEOHWACCEL
                 if (m_pFrameBuffer)
-                    m_pFrameBuffer->viewportResized(static_cast<QResizeEvent*>(pEvent));
+                    m_pFrameBuffer->viewportResized(pResizeEvent);
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+                session().GetConsole().GetDisplay().ViewportChanged(screenId(),
+                        contentsX(),
+                        contentsY(),
+                        contentsWidth(),
+                        contentsHeight());
                 break;
             }
@@ -1018,5 +1032,4 @@
         }
     }
-#endif /* VBOX_WITH_VIDEOHWACCEL */
     if (pWatched == machineWindow())
     {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 41403)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 41404)
@@ -165,7 +165,5 @@
     void scrollBy(int dx, int dy);
     static void dimImage(QImage &img);
-#ifdef VBOX_WITH_VIDEOHWACCEL
     void scrollContentsBy(int dx, int dy);
-#endif /* VBOX_WITH_VIDEOHWACCEL */
 #ifdef Q_WS_MAC
     void updateDockIcon();
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 41403)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 41404)
@@ -169,7 +169,14 @@
 
 typedef struct {
+    int32_t    x, y;
+    uint32_t   w, h;
+} CRScreenViewportInfo;
+
+
+typedef struct {
     unsigned short tcpip_port;
 
     CRScreenInfo screen[CR_MAX_GUEST_MONITORS];
+    CRScreenViewportInfo screenVieport[CR_MAX_GUEST_MONITORS];
     int          screenCount;
 
@@ -312,4 +319,6 @@
 extern DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect *pCallbacks);
 
+extern DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h);
+
 #ifdef VBOX_WITH_CRHGSMI
 /* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp	(revision 41403)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp	(revision 41404)
@@ -1133,4 +1133,45 @@
                 rc = VINF_SUCCESS;
             }
+            break;
+        }
+        case SHCRGL_HOST_FN_VIEWPORT_CHANGED:
+        {
+            Log(("svcCall: SHCRGL_HOST_FN_VIEWPORT_CHANGED\n"));
+
+            /* Verify parameter count and types. */
+            if (cParms != SHCRGL_CPARMS_VIEWPORT_CHANGED)
+            {
+                LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: cParms invalid - %d", cParms));
+                rc = VERR_INVALID_PARAMETER;
+                break;
+            }
+
+            for (int i = 0; i < SHCRGL_CPARMS_VIEWPORT_CHANGED; ++i)
+            {
+                if (paParms[i].type != VBOX_HGCM_SVC_PARM_32BIT)
+                {
+                    LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: param[%d] type invalid - %d", i, paParms[i].type));
+                    rc = VERR_INVALID_PARAMETER;
+                    break;
+                }
+            }
+
+            if (!RT_SUCCESS(rc))
+            {
+                LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: param validation failed, returning.."));
+                break;
+            }
+
+            rc = crVBoxServerSetScreenViewport((int)paParms[0].u.uint32,
+                    paParms[1].u.uint32, /* x */
+                    paParms[2].u.uint32, /* y */
+                    paParms[3].u.uint32, /* w */
+                    paParms[4].u.uint32  /* h */);
+            if (!RT_SUCCESS(rc))
+            {
+                LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: crVBoxServerSetScreenViewport failed, rc %d", rc));
+                break;
+            }
+
             break;
         }
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 41403)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 41404)
@@ -1389,4 +1389,60 @@
 }
 
+static void crVBoxServerUpdateScreenViewportCB(unsigned long key, void *data1, void *data2)
+{
+    CRMuralInfo *mural = (CRMuralInfo*) data1;
+    int *sIndex = (int*) data2;
+
+    if (mural->screenId != sIndex)
+        return;
+
+    if (!mural->width || !mural->height)
+        return;
+
+    crServerCheckMuralGeometry(mural);
+}
+
+
+DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h)
+{
+    CRScreenViewportInfo *pVieport;
+    GLboolean fPosChanged, fSizeChanged;
+
+    crDebug("crVBoxServerSetScreenViewport(%i)", sIndex);
+
+    if (sIndex<0 || sIndex>=cr_server.screenCount)
+    {
+        crWarning("crVBoxServerSetScreenViewport: invalid screen id %d", sIndex);
+        return VERR_INVALID_PARAMETER;
+    }
+
+    pVieport = &cr_server.screenVieport[sIndex];
+    fPosChanged = (pVieport->x != x || pVieport->y != y);
+    fSizeChanged = (pVieport->w != w || pVieport->h != h);
+
+    if (!fPosChanged && !fSizeChanged)
+    {
+        crDebug("crVBoxServerSetScreenViewport: no changes");
+        return;
+    }
+
+    if (fPosChanged)
+    {
+        pVieport->x = x;
+        pVieport->y = y;
+
+        crHashtableWalk(cr_server.muralTable, crVBoxServerUpdateScreenViewportCB, NULL);
+    }
+
+    if (fSizeChanged)
+    {
+        pVieport->w = w;
+        pVieport->h = h;
+
+        /* no need to do anything here actually */
+    }
+    return VINF_SUCCESS;
+}
+
 
 #ifdef VBOX_WITH_CRHGSMI
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c	(revision 41403)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c	(revision 41404)
@@ -103,4 +103,5 @@
     if (cr_server.screenCount<2 && !cr_server.bForceOffscreenRendering)
     {
+        CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
         CRASSERT(cr_server.screenCount>0);
 
@@ -108,5 +109,5 @@
         mural->hY = mural->gY-cr_server.screen[0].y;
 
-        cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX, mural->hY);
+        cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y);
 
         return;
@@ -157,4 +158,6 @@
     if (overlappingScreenCount<2 && !cr_server.bForceOffscreenRendering)
     {
+        CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
+
         if (mural->bUseFBO)
         {
@@ -163,5 +166,5 @@
         }
 
-        cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX, mural->hY);
+        cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y);
     }
     else
@@ -193,5 +196,7 @@
         if (!mural->bUseFBO)
         {
-            cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX, mural->hY);
+            CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
+
+            cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y);
         }
     }
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 41403)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 41404)
@@ -12582,5 +12582,5 @@
   <interface
     name="IDisplay" extends="$unknown"
-    uuid="09EED313-CD56-4D06-BD56-FAC0F716B5DD"
+    uuid="4b75c45c-e22e-4b75-b7cd-7ce9a83bb36e"
     wsmap="managed"
     >
@@ -12844,4 +12844,40 @@
     </method>
 
+    <method name="viewportChanged">
+      <desc>
+        Signals that framebuffer window viewport has changed.
+
+      <result name="E_INVALIDARG">
+        The specified viewport data is invalid.
+      </result>
+
+      </desc>
+
+      <param name="screenId" type="unsigned long" dir="in">
+        <desc>
+          Monitor to take the screenshot from.
+        </desc>
+      </param>
+      <param name="x" type="unsigned long" dir="in">
+        <desc>
+          Framebuffer x offset.
+        </desc>
+      </param>
+      <param name="y" type="unsigned long" dir="in">
+        <desc>
+          Framebuffer y offset.
+        </desc>
+      </param>
+      <param name="width" type="unsigned long" dir="in">
+        <desc>
+          Viewport width.
+        </desc>
+      </param>
+      <param name="height" type="unsigned long" dir="in">
+        <desc>
+          Viewport height.
+        </desc>
+      </param>
+    </method>
   </interface>
 
Index: /trunk/src/VBox/Main/include/DisplayImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/DisplayImpl.h	(revision 41403)
+++ /trunk/src/VBox/Main/include/DisplayImpl.h	(revision 41404)
@@ -172,4 +172,6 @@
     STDMETHOD(CompleteVHWACommand)(BYTE *pCommand);
 
+    STDMETHOD(ViewportChanged)(ULONG aScreenId, ULONG x, ULONG y, ULONG width, ULONG height);
+
     static const PDMDRVREG  DrvReg;
 
Index: /trunk/src/VBox/Main/src-client/DisplayImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 41403)
+++ /trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 41404)
@@ -2863,4 +2863,39 @@
     return E_NOTIMPL;
 #endif
+}
+
+STDMETHODIMP Display::ViewportChanged(ULONG aScreenId, ULONG x, ULONG y, ULONG width, ULONG height)
+{
+#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
+    BOOL is3denabled;
+    mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
+
+    if (is3denabled)
+    {
+        VBOXHGCMSVCPARM aParms[5];
+
+        aParms[0].type = VBOX_HGCM_SVC_PARM_32BIT;
+        aParms[0].u.uint32 = aScreenId;
+
+        aParms[1].type = VBOX_HGCM_SVC_PARM_32BIT;
+        aParms[1].u.uint32 = x;
+
+        aParms[2].type = VBOX_HGCM_SVC_PARM_32BIT;
+        aParms[2].u.uint32 = y;
+
+
+        aParms[3].type = VBOX_HGCM_SVC_PARM_32BIT;
+        aParms[3].u.uint32 = width;
+
+        aParms[4].type = VBOX_HGCM_SVC_PARM_32BIT;
+        aParms[4].u.uint32 = height;
+
+        VMMDev *pVMMDev = mParent->getVMMDev();
+
+        if (pVMMDev)
+            pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_VIEWPORT_CHANGED, SHCRGL_CPARMS_VIEWPORT_CHANGED, aParms);
+    }
+#endif /* VBOX_WITH_CROGL && VBOX_WITH_HGCM */
+    return S_OK;
 }
 
