Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 30548)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 30549)
@@ -49,5 +49,5 @@
 #ifdef Q_WS_PM
 # include "QIHotKeyEdit.h"
-#endif /* defined (Q_WS_PM) */
+#endif /* Q_WS_PM */
 
 #ifdef Q_WS_WIN
@@ -59,5 +59,5 @@
 static UIMachineView *gView = 0;
 static HHOOK gKbdHook = 0;
-#endif /* defined (Q_WS_WIN) */
+#endif /* Q_WS_WIN */
 
 #ifdef Q_WS_X11
@@ -78,5 +78,5 @@
 # endif
 # include "XKeyboard.h"
-#endif /* defined (Q_WS_X11) */
+#endif /* Q_WS_X11 */
 
 #ifdef Q_WS_MAC
@@ -115,5 +115,5 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
                                      , bool bAccelerate2DVideo
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
                                      )
 {
@@ -126,5 +126,5 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
                                            , bAccelerate2DVideo
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
                                            );
             break;
@@ -134,5 +134,5 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
                                                , bAccelerate2DVideo
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
                                                );
             break;
@@ -142,5 +142,5 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
                                              , bAccelerate2DVideo
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
                                              );
             break;
@@ -160,4 +160,72 @@
     return (m_bIsKeyboardCaptured ? UIViewStateType_KeyboardCaptured : 0) |
            (m_bIsHostkeyPressed ? UIViewStateType_HostKeyPressed : 0);
+}
+
+void UIMachineView::sltMachineStateChanged()
+{
+    /* Get machine state: */
+    KMachineState state = uisession()->machineState();
+    switch (state)
+    {
+        case KMachineState_Paused:
+        case KMachineState_TeleportingPausedVM:
+        {
+            if (vboxGlobal().vmRenderMode() != VBoxDefs::TimerMode &&  m_pFrameBuffer &&
+                (state != KMachineState_TeleportingPausedVM || m_previousState != KMachineState_Teleporting))
+            {
+                /* Take a screen snapshot. Note that TakeScreenShot() always needs a 32bpp image: */
+                QImage shot = QImage(m_pFrameBuffer->width(), m_pFrameBuffer->height(), QImage::Format_RGB32);
+                /* If TakeScreenShot fails or returns no image, just show a black image. */
+                shot.fill(0);
+                CDisplay dsp = session().GetConsole().GetDisplay();
+                dsp.TakeScreenShot(screenId(), shot.bits(), shot.width(), shot.height());
+                /* TakeScreenShot() may fail if, e.g. the Paused notification was delivered
+                 * after the machine execution was resumed. It's not fatal: */
+                if (dsp.isOk())
+                {
+                    dimImage(shot);
+                }
+                m_pauseShot = QPixmap::fromImage(shot);
+                /* Fully repaint to pick up m_pauseShot: */
+                viewport()->repaint();
+            }
+            /* Reuse the focus event handler to uncapture keyboard: */
+            if (hasFocus())
+                focusEvent(false /* aHasFocus*/, false /* aReleaseHostKey */);
+            break;
+        }
+        case KMachineState_Stuck:
+        {
+            /* Reuse the focus event handler to uncapture keyboard: */
+            if (hasFocus())
+                focusEvent(false /* aHasFocus*/, false /* aReleaseHostKey */);
+            break;
+        }
+        case KMachineState_Running:
+        {
+            if (   m_previousState == KMachineState_Paused
+                || m_previousState == KMachineState_TeleportingPausedVM
+                || m_previousState == KMachineState_Restoring)
+            {
+                if (vboxGlobal().vmRenderMode() != VBoxDefs::TimerMode && m_pFrameBuffer)
+                {
+                    /* Reset the pixmap to free memory: */
+                    m_pauseShot = QPixmap();
+                    /* Ask for full guest display update (it will also update
+                     * the viewport through IFramebuffer::NotifyUpdate): */
+                    CDisplay dsp = session().GetConsole().GetDisplay();
+                    dsp.InvalidateAndUpdate();
+                }
+            }
+            /* Reuse the focus event handler to capture keyboard: */
+            if (hasFocus())
+                focusEvent(true /* aHasFocus */);
+            break;
+        }
+        default:
+            break;
+    }
+
+    m_previousState = state;
 }
 
@@ -166,5 +234,5 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
                              , bool bAccelerate2DVideo
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
                              )
     : QAbstractScrollArea(pMachineWindow->machineWindow())
@@ -195,177 +263,4 @@
 }
 
-UISession* UIMachineView::uisession() const
-{
-    return machineLogic()->uisession();
-}
-
-CSession& UIMachineView::session()
-{
-    return uisession()->session();
-}
-
-QSize UIMachineView::sizeHint() const
-{
-#ifdef VBOX_WITH_DEBUGGER
-    // TODO: Fix all DEBUGGER stuff!
-    /* HACK ALERT! Really ugly workaround for the resizing to 9x1 done by DevVGA if provoked before power on. */
-    QSize fb(m_pFrameBuffer->width(), m_pFrameBuffer->height());
-    if ((fb.width() < 16 || fb.height() < 16) && (vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled()))
-        fb = QSize(640, 480);
-    return QSize(fb.width() + frameWidth() * 2, fb.height() + frameWidth() * 2);
-#else
-    return QSize(m_pFrameBuffer->width() + frameWidth() * 2, m_pFrameBuffer->height() + frameWidth() * 2);
-#endif
-}
-
-int UIMachineView::contentsX() const
-{
-    return horizontalScrollBar()->value();
-}
-
-int UIMachineView::contentsY() const
-{
-    return verticalScrollBar()->value();
-}
-
-int UIMachineView::contentsWidth() const
-{
-    return m_pFrameBuffer->width();
-}
-
-int UIMachineView::contentsHeight() const
-{
-    return m_pFrameBuffer->height();
-}
-
-int UIMachineView::visibleWidth() const
-{
-    return horizontalScrollBar()->pageStep();
-}
-
-int UIMachineView::visibleHeight() const
-{
-    return verticalScrollBar()->pageStep();
-}
-
-UIMachineLogic* UIMachineView::machineLogic() const
-{
-    return machineWindowWrapper()->machineLogic();
-}
-
-QSize UIMachineView::desktopGeometry() const
-{
-    QSize geometry;
-    switch (m_desktopGeometryType)
-    {
-        case DesktopGeo_Fixed:
-        case DesktopGeo_Automatic:
-            geometry = QSize(qMax(m_desktopGeometry.width(), m_storedConsoleSize.width()),
-                             qMax(m_desktopGeometry.height(), m_storedConsoleSize.height()));
-            break;
-        case DesktopGeo_Any:
-            geometry = QSize(0, 0);
-            break;
-        default:
-            AssertMsgFailed(("Bad geometry type %d!\n", m_desktopGeometryType));
-    }
-    return geometry;
-}
-
-QSize UIMachineView::guestSizeHint()
-{
-    /* Result: */
-    QSize sizeHint;
-
-    /* Get current machine: */
-    CMachine machine = session().GetMachine();
-
-    /* Load machine view hint: */
-    QString strKey = m_uScreenId == 0 ? QString("%1").arg(VBoxDefs::GUI_LastGuestSizeHint) :
-                     QString("%1%2").arg(VBoxDefs::GUI_LastGuestSizeHint).arg(m_uScreenId);
-    QString strValue = machine.GetExtraData(strKey);
-
-    bool ok = true;
-    int width = 0, height = 0;
-    if (ok)
-        width = strValue.section(',', 0, 0).toInt(&ok);
-    if (ok)
-        height = strValue.section(',', 1, 1).toInt(&ok);
-
-    if (ok /* If previous parameters were read correctly! */)
-    {
-        /* Compose guest size hint from loaded values: */
-        sizeHint = QSize(width, height);
-    }
-    else
-    {
-        /* Compose guest size hint from default attributes: */
-        sizeHint = QSize(800, 600);
-    }
-
-    /* Return result: */
-    return sizeHint;
-}
-
-void UIMachineView::setDesktopGeometry(DesktopGeo geometry, int aWidth, int aHeight)
-{
-    switch (geometry)
-    {
-        case DesktopGeo_Fixed:
-            m_desktopGeometryType = DesktopGeo_Fixed;
-            if (aWidth != 0 && aHeight != 0)
-                m_desktopGeometry = QSize(aWidth, aHeight);
-            else
-                m_desktopGeometry = QSize(0, 0);
-            storeConsoleSize(0, 0);
-            break;
-        case DesktopGeo_Automatic:
-            m_desktopGeometryType = DesktopGeo_Automatic;
-            m_desktopGeometry = QSize(0, 0);
-            storeConsoleSize(0, 0);
-            break;
-        case DesktopGeo_Any:
-            m_desktopGeometryType = DesktopGeo_Any;
-            m_desktopGeometry = QSize(0, 0);
-            break;
-        default:
-            AssertMsgFailed(("Invalid desktop geometry type %d\n", geometry));
-            m_desktopGeometryType = DesktopGeo_Invalid;
-    }
-}
-
-void UIMachineView::storeConsoleSize(int iWidth, int iHeight)
-{
-    m_storedConsoleSize = QSize(iWidth, iHeight);
-}
-
-void UIMachineView::storeGuestSizeHint(const QSize &sizeHint)
-{
-    /* Get current machine: */
-    CMachine machine = session().GetMachine();
-
-    /* Save machine view hint: */
-    QString strKey = m_uScreenId == 0 ? QString("%1").arg(VBoxDefs::GUI_LastGuestSizeHint) :
-                     QString("%1%2").arg(VBoxDefs::GUI_LastGuestSizeHint).arg(m_uScreenId);
-    QString strValue = QString("%1,%2").arg(sizeHint.width()).arg(sizeHint.height());
-    machine.SetExtraData(strKey, strValue);
-}
-
-void UIMachineView::updateSliders()
-{
-    QSize p = viewport()->size();
-    QSize m = maximumViewportSize();
-
-    QSize v = QSize(frameBuffer()->width(), frameBuffer()->height());
-    /* No scroll bars needed: */
-    if (m.expandedTo(v) == m)
-        p = m;
-
-    horizontalScrollBar()->setRange(0, v.width() - p.width());
-    verticalScrollBar()->setRange(0, v.height() - p.height());
-    horizontalScrollBar()->setPageStep(p.width());
-    verticalScrollBar()->setPageStep(p.height());
-}
-
 void UIMachineView::prepareFrameBuffer()
 {
@@ -381,7 +276,7 @@
             pViewport = new VBoxViewport(this);
     }
-#else
+#else /* VBOX_GUI_USE_QGLFB */
     VBoxViewport *pViewport = new VBoxViewport(this);
-#endif
+#endif /* !VBOX_GUI_USE_QGLFB */
     setViewport(pViewport);
 
@@ -411,7 +306,7 @@
             else
                 m_pFrameBuffer = new UIFrameBufferQImage(this);
-# else
+# else /* VBOX_WITH_VIDEOHWACCEL */
             m_pFrameBuffer = new UIFrameBufferQImage(this);
-# endif
+# endif /* !VBOX_WITH_VIDEOHWACCEL */
             break;
 #endif /* VBOX_GUI_USE_QIMAGE */
@@ -432,5 +327,5 @@
             /* This is somehow necessary to prevent strange X11 warnings on i386 and segfaults on x86_64: */
             XFlush(QX11Info::display());
-# endif
+# endif /* Q_WS_X11 */
 # if defined(VBOX_WITH_VIDEOHWACCEL) && defined(DEBUG_misha) /* not tested yet */
             if (m_fAccelerate2DVideo)
@@ -493,7 +388,7 @@
             else
                 m_pFrameBuffer = new UIFrameBufferQuartz2D(this);
-# else
+# else /* VBOX_WITH_VIDEOHWACCEL */
             m_pFrameBuffer = new UIFrameBufferQuartz2D(this);
-# endif
+# endif /* !VBOX_WITH_VIDEOHWACCEL */
             break;
 #endif /* VBOX_GUI_USE_QUARTZ2D */
@@ -517,5 +412,5 @@
         }
         if (fb.raw() != m_pFrameBuffer) /* <-this will evaluate to true iff m_fAccelerate2DVideo is disabled or iff no framebuffer is yet assigned */
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
         {
             m_pFrameBuffer->AddRef();
@@ -558,5 +453,5 @@
     Assert(ok);
     NOREF(ok);
-#endif
+#endif /* Q_WS_PM */
 }
 
@@ -587,5 +482,5 @@
         /* Initialize the X keyboard subsystem: */
         initMappedX11Keyboard(QX11Info::display(), vboxGlobal().settings().publicProperty("GUI/RemapScancodes"));
-#endif
+#endif /* Q_WS_X11 */
 
         /* Remember the desktop geometry and register for geometry
@@ -651,5 +546,5 @@
         }
         else
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
         {
             /* Warn framebuffer about its no more necessary: */
@@ -666,4 +561,537 @@
 }
 
+UIMachineLogic* UIMachineView::machineLogic() const
+{
+    return machineWindowWrapper()->machineLogic();
+}
+
+UISession* UIMachineView::uisession() const
+{
+    return machineLogic()->uisession();
+}
+
+CSession& UIMachineView::session()
+{
+    return uisession()->session();
+}
+
+QSize UIMachineView::sizeHint() const
+{
+#ifdef VBOX_WITH_DEBUGGER
+    // TODO: Fix all DEBUGGER stuff!
+    /* HACK ALERT! Really ugly workaround for the resizing to 9x1 done by DevVGA if provoked before power on. */
+    QSize fb(m_pFrameBuffer->width(), m_pFrameBuffer->height());
+    if ((fb.width() < 16 || fb.height() < 16) && (vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled()))
+        fb = QSize(640, 480);
+    return QSize(fb.width() + frameWidth() * 2, fb.height() + frameWidth() * 2);
+#else /* VBOX_WITH_DEBUGGER */
+    return QSize(m_pFrameBuffer->width() + frameWidth() * 2, m_pFrameBuffer->height() + frameWidth() * 2);
+#endif /* !VBOX_WITH_DEBUGGER */
+}
+
+int UIMachineView::contentsX() const
+{
+    return horizontalScrollBar()->value();
+}
+
+int UIMachineView::contentsY() const
+{
+    return verticalScrollBar()->value();
+}
+
+int UIMachineView::contentsWidth() const
+{
+    return m_pFrameBuffer->width();
+}
+
+int UIMachineView::contentsHeight() const
+{
+    return m_pFrameBuffer->height();
+}
+
+int UIMachineView::visibleWidth() const
+{
+    return horizontalScrollBar()->pageStep();
+}
+
+int UIMachineView::visibleHeight() const
+{
+    return verticalScrollBar()->pageStep();
+}
+
+QSize UIMachineView::desktopGeometry() const
+{
+    QSize geometry;
+    switch (m_desktopGeometryType)
+    {
+        case DesktopGeo_Fixed:
+        case DesktopGeo_Automatic:
+            geometry = QSize(qMax(m_desktopGeometry.width(), m_storedConsoleSize.width()),
+                             qMax(m_desktopGeometry.height(), m_storedConsoleSize.height()));
+            break;
+        case DesktopGeo_Any:
+            geometry = QSize(0, 0);
+            break;
+        default:
+            AssertMsgFailed(("Bad geometry type %d!\n", m_desktopGeometryType));
+    }
+    return geometry;
+}
+
+QSize UIMachineView::guestSizeHint()
+{
+    /* Result: */
+    QSize sizeHint;
+
+    /* Get current machine: */
+    CMachine machine = session().GetMachine();
+
+    /* Load machine view hint: */
+    QString strKey = m_uScreenId == 0 ? QString("%1").arg(VBoxDefs::GUI_LastGuestSizeHint) :
+                     QString("%1%2").arg(VBoxDefs::GUI_LastGuestSizeHint).arg(m_uScreenId);
+    QString strValue = machine.GetExtraData(strKey);
+
+    bool ok = true;
+    int width = 0, height = 0;
+    if (ok)
+        width = strValue.section(',', 0, 0).toInt(&ok);
+    if (ok)
+        height = strValue.section(',', 1, 1).toInt(&ok);
+
+    if (ok /* If previous parameters were read correctly! */)
+    {
+        /* Compose guest size hint from loaded values: */
+        sizeHint = QSize(width, height);
+    }
+    else
+    {
+        /* Compose guest size hint from default attributes: */
+        sizeHint = QSize(800, 600);
+    }
+
+    /* Return result: */
+    return sizeHint;
+}
+
+void UIMachineView::setDesktopGeometry(DesktopGeo geometry, int aWidth, int aHeight)
+{
+    switch (geometry)
+    {
+        case DesktopGeo_Fixed:
+            m_desktopGeometryType = DesktopGeo_Fixed;
+            if (aWidth != 0 && aHeight != 0)
+                m_desktopGeometry = QSize(aWidth, aHeight);
+            else
+                m_desktopGeometry = QSize(0, 0);
+            storeConsoleSize(0, 0);
+            break;
+        case DesktopGeo_Automatic:
+            m_desktopGeometryType = DesktopGeo_Automatic;
+            m_desktopGeometry = QSize(0, 0);
+            storeConsoleSize(0, 0);
+            break;
+        case DesktopGeo_Any:
+            m_desktopGeometryType = DesktopGeo_Any;
+            m_desktopGeometry = QSize(0, 0);
+            break;
+        default:
+            AssertMsgFailed(("Invalid desktop geometry type %d\n", geometry));
+            m_desktopGeometryType = DesktopGeo_Invalid;
+    }
+}
+
+void UIMachineView::storeConsoleSize(int iWidth, int iHeight)
+{
+    m_storedConsoleSize = QSize(iWidth, iHeight);
+}
+
+void UIMachineView::storeGuestSizeHint(const QSize &sizeHint)
+{
+    /* Get current machine: */
+    CMachine machine = session().GetMachine();
+
+    /* Save machine view hint: */
+    QString strKey = m_uScreenId == 0 ? QString("%1").arg(VBoxDefs::GUI_LastGuestSizeHint) :
+                     QString("%1%2").arg(VBoxDefs::GUI_LastGuestSizeHint).arg(m_uScreenId);
+    QString strValue = QString("%1,%2").arg(sizeHint.width()).arg(sizeHint.height());
+    machine.SetExtraData(strKey, strValue);
+}
+
+void UIMachineView::updateSliders()
+{
+    QSize p = viewport()->size();
+    QSize m = maximumViewportSize();
+
+    QSize v = QSize(frameBuffer()->width(), frameBuffer()->height());
+    /* No scroll bars needed: */
+    if (m.expandedTo(v) == m)
+        p = m;
+
+    horizontalScrollBar()->setRange(0, v.width() - p.width());
+    verticalScrollBar()->setRange(0, v.height() - p.height());
+    horizontalScrollBar()->setPageStep(p.width());
+    verticalScrollBar()->setPageStep(p.height());
+}
+
+void UIMachineView::fixModifierState(LONG *piCodes, uint *puCount)
+{
+    /* Synchronize the views of the host and the guest to the modifier keys.
+     * This function will add up to 6 additional keycodes to codes. */
+
+#if defined(Q_WS_X11)
+
+    Window   wDummy1, wDummy2;
+    int      iDummy3, iDummy4, iDummy5, iDummy6;
+    unsigned uMask;
+    unsigned uKeyMaskNum = 0, uKeyMaskCaps = 0, uKeyMaskScroll = 0;
+
+    uKeyMaskCaps          = LockMask;
+    XModifierKeymap* map  = XGetModifierMapping(QX11Info::display());
+    KeyCode keyCodeNum    = XKeysymToKeycode(QX11Info::display(), XK_Num_Lock);
+    KeyCode keyCodeScroll = XKeysymToKeycode(QX11Info::display(), XK_Scroll_Lock);
+
+    for (int i = 0; i < 8; ++ i)
+    {
+        if (keyCodeNum != NoSymbol && map->modifiermap[map->max_keypermod * i] == keyCodeNum)
+            uKeyMaskNum = 1 << i;
+        else if (keyCodeScroll != NoSymbol && map->modifiermap[map->max_keypermod * i] == keyCodeScroll)
+            uKeyMaskScroll = 1 << i;
+    }
+    XQueryPointer(QX11Info::display(), DefaultRootWindow(QX11Info::display()), &wDummy1, &wDummy2,
+                  &iDummy3, &iDummy4, &iDummy5, &iDummy6, &uMask);
+    XFreeModifiermap(map);
+
+    if (uisession()->numLockAdaptionCnt() && (uisession()->isNumLock() ^ !!(uMask & uKeyMaskNum)))
+    {
+        uisession()->setNumLockAdaptionCnt(uisession()->numLockAdaptionCnt() - 1);
+        piCodes[(*puCount)++] = 0x45;
+        piCodes[(*puCount)++] = 0x45 | 0x80;
+    }
+    if (uisession()->capsLockAdaptionCnt() && (uisession()->isCapsLock() ^ !!(uMask & uKeyMaskCaps)))
+    {
+        uisession()->setCapsLockAdaptionCnt(uisession()->capsLockAdaptionCnt() - 1);
+        piCodes[(*puCount)++] = 0x3a;
+        piCodes[(*puCount)++] = 0x3a | 0x80;
+        /* Some keyboard layouts require shift to be pressed to break
+         * capslock.  For simplicity, only do this if shift is not
+         * already held down. */
+        if (uisession()->isCapsLock() && !(m_pressedKeys[0x2a] & IsKeyPressed))
+        {
+            piCodes[(*puCount)++] = 0x2a;
+            piCodes[(*puCount)++] = 0x2a | 0x80;
+        }
+    }
+
+#elif defined(Q_WS_WIN)
+
+    if (uisession()->numLockAdaptionCnt() && (uisession()->isNumLock() ^ !!(GetKeyState(VK_NUMLOCK))))
+    {
+        uisession()->setNumLockAdaptionCnt(uisession()->numLockAdaptionCnt() - 1);
+        piCodes[(*puCount)++] = 0x45;
+        piCodes[(*puCount)++] = 0x45 | 0x80;
+    }
+    if (uisession()->capsLockAdaptionCnt() && (uisession()->isCapsLock() ^ !!(GetKeyState(VK_CAPITAL))))
+    {
+        uisession()->setCapsLockAdaptionCnt(uisession()->capsLockAdaptionCnt() - 1);
+        piCodes[(*puCount)++] = 0x3a;
+        piCodes[(*puCount)++] = 0x3a | 0x80;
+        /* Some keyboard layouts require shift to be pressed to break
+         * capslock.  For simplicity, only do this if shift is not
+         * already held down. */
+        if (uisession()->isCapsLock() && !(m_pressedKeys[0x2a] & IsKeyPressed))
+        {
+            piCodes[(*puCount)++] = 0x2a;
+            piCodes[(*puCount)++] = 0x2a | 0x80;
+        }
+    }
+
+#elif defined(Q_WS_MAC)
+
+    /* if (uisession()->numLockAdaptionCnt()) ... - NumLock isn't implemented by Mac OS X so ignore it. */
+    if (uisession()->capsLockAdaptionCnt() && (uisession()->isCapsLock() ^ !!(::GetCurrentEventKeyModifiers() & alphaLock)))
+    {
+        uisession()->setCapsLockAdaptionCnt(uisession()->capsLockAdaptionCnt() - 1);
+        piCodes[(*puCount)++] = 0x3a;
+        piCodes[(*puCount)++] = 0x3a | 0x80;
+        /* Some keyboard layouts require shift to be pressed to break
+         * capslock.  For simplicity, only do this if shift is not
+         * already held down. */
+        if (uisession()->isCapsLock() && !(m_pressedKeys[0x2a] & IsKeyPressed))
+        {
+            piCodes[(*puCount)++] = 0x2a;
+            piCodes[(*puCount)++] = 0x2a | 0x80;
+        }
+    }
+
+#else
+
+//#warning Adapt UIMachineView::fixModifierState
+
+#endif
+}
+
+QPoint UIMachineView::viewportToContents(const QPoint &vp) const
+{
+    return QPoint(vp.x() + contentsX(), vp.y() + contentsY());
+}
+
+void UIMachineView::scrollBy(int dx, int dy)
+{
+    horizontalScrollBar()->setValue(horizontalScrollBar()->value() + dx);
+    verticalScrollBar()->setValue(verticalScrollBar()->value() + dy);
+}
+
+void UIMachineView::emitKeyboardStateChanged()
+{
+    emit keyboardStateChanged(keyboardState());
+}
+
+void UIMachineView::captureKbd(bool fCapture, bool fEmitSignal /* = true */)
+{
+    if (m_bIsKeyboardCaptured == fCapture)
+        return;
+
+#if defined(Q_WS_WIN)
+    /* On Win32, keyboard grabbing is ineffective, a low-level keyboard hook is used instead. */
+#elif defined(Q_WS_X11)
+    /* On X11, we are using passive XGrabKey for normal (windowed) mode
+     * instead of XGrabKeyboard (called by QWidget::grabKeyboard())
+     * because XGrabKeyboard causes a problem under metacity - a window cannot be moved
+     * using the mouse if it is currently actively grabing the keyboard;
+     * For static modes we are using usual (active) keyboard grabbing. */
+    switch (machineLogic()->visualStateType())
+    {
+        /* If window is moveable we are making passive keyboard grab: */
+        case UIVisualStateType_Normal:
+        {
+            if (fCapture)
+                XGrabKey(QX11Info::display(), AnyKey, AnyModifier, machineWindowWrapper()->machineWindow()->winId(), False, GrabModeAsync, GrabModeAsync);
+            else
+                XUngrabKey(QX11Info::display(), AnyKey, AnyModifier, machineWindowWrapper()->machineWindow()->winId());
+            break;
+        }
+        /* If window is NOT moveable we are making active keyboard grab: */
+        case UIVisualStateType_Fullscreen:
+        case UIVisualStateType_Seamless:
+        {
+            if (fCapture)
+            {
+                /* Keyboard grabbing can fail because of some keyboard shortcut is still grabbed by window manager.
+                 * We can't be sure this shortcut will be released at all, so we will retry to grab keyboard for 50 times,
+                 * and after we will just ignore that issue: */
+                int cTriesLeft = 50;
+                while (cTriesLeft && XGrabKeyboard(QX11Info::display(), machineWindowWrapper()->machineWindow()->winId(), False, GrabModeAsync, GrabModeAsync, CurrentTime)) { --cTriesLeft; }
+            }
+            else
+                XUngrabKeyboard(QX11Info::display(), CurrentTime);
+            break;
+        }
+        /* Should we try to grab keyboard in default case? I think - NO. */
+        default:
+            break;
+    }
+#elif defined(Q_WS_MAC)
+    /* On Mac OS X, we use the Qt methods + disabling global hot keys + watching modifiers
+     * (for right/left separation). */
+    if (fCapture)
+    {
+        ::DarwinDisableGlobalHotKeys(true);
+        grabKeyboard();
+    }
+    else
+    {
+        ::DarwinDisableGlobalHotKeys(false);
+        releaseKeyboard();
+    }
+#else
+    if (fCapture)
+        grabKeyboard();
+    else
+        releaseKeyboard();
+#endif
+
+    m_bIsKeyboardCaptured = fCapture;
+
+    if (fEmitSignal)
+        emitKeyboardStateChanged();
+}
+
+void UIMachineView::saveKeyStates()
+{
+    ::memcpy(m_pressedKeysCopy, m_pressedKeys, sizeof(m_pressedKeys));
+}
+
+void UIMachineView::releaseAllPressedKeys(bool aReleaseHostKey /* = true */)
+{
+    CKeyboard keyboard = session().GetConsole().GetKeyboard();
+    bool fSentRESEND = false;
+
+    /* Send a dummy scan code (RESEND) to prevent the guest OS from recognizing
+     * a single key click (for ex., Alt) and performing an unwanted action
+     * (for ex., activating the menu) when we release all pressed keys below.
+     * Note, that it's just a guess that sending RESEND will give the desired
+     * effect :), but at least it works with NT and W2k guests. */
+    for (uint i = 0; i < SIZEOF_ARRAY (m_pressedKeys); i++)
+    {
+        if (m_pressedKeys[i] & IsKeyPressed)
+        {
+            if (!fSentRESEND)
+            {
+                keyboard.PutScancode (0xFE);
+                fSentRESEND = true;
+            }
+            keyboard.PutScancode(i | 0x80);
+        }
+        else if (m_pressedKeys[i] & IsExtKeyPressed)
+        {
+            if (!fSentRESEND)
+            {
+                keyboard.PutScancode(0xFE);
+                fSentRESEND = true;
+            }
+            QVector <LONG> codes(2);
+            codes[0] = 0xE0;
+            codes[1] = i | 0x80;
+            keyboard.PutScancodes(codes);
+        }
+        m_pressedKeys[i] = 0;
+    }
+
+    if (aReleaseHostKey)
+        m_bIsHostkeyPressed = false;
+
+#ifdef Q_WS_MAC
+    /* Clear most of the modifiers: */
+    m_darwinKeyModifiers &=
+        alphaLock | kEventKeyModifierNumLockMask |
+        (aReleaseHostKey ? 0 : ::DarwinKeyCodeToDarwinModifierMask (m_globalSettings.hostKey()));
+#endif /* Q_WS_MAC */
+
+    emitKeyboardStateChanged();
+}
+
+void UIMachineView::sendChangedKeyStates()
+{
+    QVector <LONG> codes(2);
+    CKeyboard keyboard = session().GetConsole().GetKeyboard();
+    for (uint i = 0; i < SIZEOF_ARRAY(m_pressedKeys); ++ i)
+    {
+        uint8_t os = m_pressedKeysCopy[i];
+        uint8_t ns = m_pressedKeys[i];
+        if ((os & IsKeyPressed) != (ns & IsKeyPressed))
+        {
+            codes[0] = i;
+            if (!(ns & IsKeyPressed))
+                codes[0] |= 0x80;
+            keyboard.PutScancode(codes[0]);
+        }
+        else if ((os & IsExtKeyPressed) != (ns & IsExtKeyPressed))
+        {
+            codes[0] = 0xE0;
+            codes[1] = i;
+            if (!(ns & IsExtKeyPressed))
+                codes[1] |= 0x80;
+            keyboard.PutScancodes(codes);
+        }
+    }
+}
+
+void UIMachineView::dimImage(QImage &img)
+{
+    for (int y = 0; y < img.height(); ++ y)
+    {
+        if (y % 2)
+        {
+            if (img.depth() == 32)
+            {
+                for (int x = 0; x < img.width(); ++ x)
+                {
+                    int gray = qGray(img.pixel (x, y)) / 2;
+                    img.setPixel(x, y, qRgb (gray, gray, gray));
+                }
+            }
+            else
+            {
+                ::memset(img.scanLine (y), 0, img.bytesPerLine());
+            }
+        }
+        else
+        {
+            if (img.depth() == 32)
+            {
+                for (int x = 0; x < img.width(); ++ x)
+                {
+                    int gray = (2 * qGray (img.pixel (x, y))) / 3;
+                    img.setPixel(x, y, qRgb (gray, gray, gray));
+                }
+            }
+        }
+    }
+}
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+void UIMachineView::scrollContentsBy(int dx, int dy)
+{
+    if (m_pFrameBuffer)
+    {
+        m_pFrameBuffer->viewportScrolled(dx, dy);
+    }
+    QAbstractScrollArea::scrollContentsBy(dx, dy);
+}
+#endif /* VBOX_WITH_VIDEOHWACCEL */
+
+#ifdef Q_WS_MAC
+void UIMachineView::updateDockIcon()
+{
+    machineLogic()->updateDockIcon();
+}
+
+CGImageRef UIMachineView::vmContentImage()
+{
+    if (!m_pauseShot.isNull())
+    {
+        CGImageRef pauseImg = ::darwinToCGImageRef(&m_pauseShot);
+        /* Use the pause image as background */
+        return pauseImg;
+    }
+    else
+    {
+# ifdef VBOX_GUI_USE_QUARTZ2D
+        if (vboxGlobal().vmRenderMode() == VBoxDefs::Quartz2DMode)
+        {
+            /* If the render mode is Quartz2D we could use the CGImageRef
+             * of the framebuffer for the dock icon creation. This saves
+             * some conversion time. */
+            CGImageRef image = static_cast<UIFrameBufferQuartz2D*>(m_pFrameBuffer)->imageRef();
+            CGImageRetain(image); /* Retain it, cause the consumer will release it. */
+            return image;
+        }
+        else
+# endif /* VBOX_GUI_USE_QUARTZ2D */
+            /* In image mode we have to create the image ref out of the
+             * framebuffer */
+            return frameBuffertoCGImageRef(m_pFrameBuffer);
+    }
+    return 0;
+}
+
+CGImageRef UIMachineView::frameBuffertoCGImageRef(UIFrameBuffer *pFrameBuffer)
+{
+    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
+    Assert(cs);
+    /* Create the image copy of the framebuffer */
+    CGDataProviderRef dp = CGDataProviderCreateWithData(pFrameBuffer, pFrameBuffer->address(), pFrameBuffer->bitsPerPixel() / 8 * pFrameBuffer->width() * pFrameBuffer->height(), NULL);
+    Assert(dp);
+    CGImageRef ir = CGImageCreate(pFrameBuffer->width(), pFrameBuffer->height(), 8, 32, pFrameBuffer->bytesPerLine(), cs,
+                                  kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
+                                  kCGRenderingIntentDefault);
+    Assert(ir);
+    CGDataProviderRelease(dp);
+    CGColorSpaceRelease(cs);
+
+    return ir;
+}
+#endif /* Q_WS_MAC */
+
 bool UIMachineView::event(QEvent *pEvent)
 {
@@ -706,5 +1134,5 @@
             return true;
         }
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
 
         case QEvent::KeyPress:
@@ -849,5 +1277,5 @@
             return true;
         }
-#endif
+#endif /* Q_WS_MAC */
 
         default:
@@ -936,81 +1364,13 @@
 }
 
-void UIMachineView::sltMachineStateChanged()
-{
-    /* Get machine state: */
-    KMachineState state = uisession()->machineState();
-    switch (state)
-    {
-        case KMachineState_Paused:
-        case KMachineState_TeleportingPausedVM:
-        {
-            if (vboxGlobal().vmRenderMode() != VBoxDefs::TimerMode &&  m_pFrameBuffer &&
-                (state != KMachineState_TeleportingPausedVM || m_previousState != KMachineState_Teleporting))
-            {
-                /* Take a screen snapshot. Note that TakeScreenShot() always needs a 32bpp image: */
-                QImage shot = QImage(m_pFrameBuffer->width(), m_pFrameBuffer->height(), QImage::Format_RGB32);
-                /* If TakeScreenShot fails or returns no image, just show a black image. */
-                shot.fill(0);
-                CDisplay dsp = session().GetConsole().GetDisplay();
-                dsp.TakeScreenShot(screenId(), shot.bits(), shot.width(), shot.height());
-                /* TakeScreenShot() may fail if, e.g. the Paused notification was delivered
-                 * after the machine execution was resumed. It's not fatal: */
-                if (dsp.isOk())
-                {
-                    dimImage(shot);
-                }
-                m_pauseShot = QPixmap::fromImage(shot);
-                /* Fully repaint to pick up m_pauseShot: */
-                viewport()->repaint();
-            }
-            /* Reuse the focus event handler to uncapture keyboard: */
-            if (hasFocus())
-                focusEvent(false /* aHasFocus*/, false /* aReleaseHostKey */);
-            break;
-        }
-        case KMachineState_Stuck:
-        {
-            /* Reuse the focus event handler to uncapture keyboard: */
-            if (hasFocus())
-                focusEvent(false /* aHasFocus*/, false /* aReleaseHostKey */);
-            break;
-        }
-        case KMachineState_Running:
-        {
-            if (   m_previousState == KMachineState_Paused
-                || m_previousState == KMachineState_TeleportingPausedVM
-                || m_previousState == KMachineState_Restoring)
-            {
-                if (vboxGlobal().vmRenderMode() != VBoxDefs::TimerMode && m_pFrameBuffer)
-                {
-                    /* Reset the pixmap to free memory: */
-                    m_pauseShot = QPixmap();
-                    /* Ask for full guest display update (it will also update
-                     * the viewport through IFramebuffer::NotifyUpdate): */
-                    CDisplay dsp = session().GetConsole().GetDisplay();
-                    dsp.InvalidateAndUpdate();
-                }
-            }
-            /* Reuse the focus event handler to capture keyboard: */
-            if (hasFocus())
-                focusEvent(true /* aHasFocus */);
-            break;
-        }
-        default:
-            break;
-    }
-
-    m_previousState = state;
-}
-
 void UIMachineView::focusEvent(bool fHasFocus, bool fReleaseHostKey /* = true */)
 {
     if (fHasFocus)
     {
-#ifdef Q_WS_WIN32
+#ifdef Q_WS_WIN
         if (!uisession()->isAutoCaptureDisabled() && m_globalSettings.autoCapture() && GetAncestor(winId(), GA_ROOT) == GetForegroundWindow())
-#else
+#else /* Q_WS_WIN */
         if (!uisession()->isAutoCaptureDisabled() && m_globalSettings.autoCapture())
-#endif
+#endif /* !Q_WS_WIN */
         {
             captureKbd(true);
@@ -1211,5 +1571,5 @@
                                  * mouse is immediately ungrabbed. */
                                 qApp->processEvents();
-#endif
+#endif /* Q_WS_X11 */
                                 if (m_bIsKeyboardCaptured)
                                     machineLogic()->mouseHandler()->captureMouse(screenId());
@@ -1244,5 +1604,5 @@
     {
         bool processed = false;
-#if defined (Q_WS_WIN32)
+#if defined (Q_WS_WIN)
         NOREF(pUniKey);
         int n = GetKeyboardLayoutList(0, NULL);
@@ -1300,8 +1660,8 @@
     Assert(!keyboard.isNull());
 
-#if defined (Q_WS_WIN32)
+#ifdef Q_WS_WIN
     /* send pending WM_PAINT events */
     ::UpdateWindow(viewport()->winId());
-#endif
+#endif /* Q_WS_WIN */
 
     std::vector <LONG> scancodes(codes, &codes[count]);
@@ -1362,5 +1722,5 @@
 }
 
-#if defined(Q_WS_WIN32)
+#if defined(Q_WS_WIN)
 
 LRESULT CALLBACK UIMachineView::lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
@@ -1686,4 +2046,48 @@
 #elif defined(Q_WS_MAC)
 
+void UIMachineView::darwinGrabKeyboardEvents(bool fGrab)
+{
+    m_fKeyboardGrabbed = fGrab;
+    if (fGrab)
+    {
+        /* Disable mouse and keyboard event compression/delaying to make sure we *really* get all of the events. */
+        ::CGSetLocalEventsSuppressionInterval(0.0);
+        machineLogic()->mouseHandler()->setMouseCoalescingEnabled(false);
+
+        /* Register the event callback/hook and grab the keyboard. */
+        UICocoaApplication::instance()->registerForNativeEvents(RT_BIT_32(10) | RT_BIT_32(11) | RT_BIT_32(12) /* NSKeyDown  | NSKeyUp | | NSFlagsChanged */,
+                                                                UIMachineView::darwinEventHandlerProc, this);
+
+        ::DarwinGrabKeyboard (false);
+    }
+    else
+    {
+        ::DarwinReleaseKeyboard();
+        UICocoaApplication::instance()->unregisterForNativeEvents(RT_BIT_32(10) | RT_BIT_32(11) | RT_BIT_32(12) /* NSKeyDown  | NSKeyUp | | NSFlagsChanged */,
+                                                                  UIMachineView::darwinEventHandlerProc, this);
+    }
+}
+
+bool UIMachineView::darwinEventHandlerProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser)
+{
+    UIMachineView *view = (UIMachineView*)pvUser;
+    EventRef inEvent = (EventRef)pvCarbonEvent;
+    UInt32 eventClass = ::GetEventClass(inEvent);
+
+    /* Check if this is an application key combo. In that case we will not pass
+     * the event to the guest, but let the host process it. */
+    if (::darwinIsApplicationCommand(pvCocoaEvent))
+        return false;
+
+    /* All keyboard class events needs to be handled. */
+    if (eventClass == kEventClassKeyboard)
+    {
+        if (view->darwinKeyboardEvent (pvCocoaEvent, inEvent))
+            return true;
+    }
+    /* Pass the event along. */
+    return false;
+}
+
 bool UIMachineView::darwinKeyboardEvent(const void *pvCocoaEvent, EventRef inEvent)
 {
@@ -1770,408 +2174,4 @@
 }
 
-void UIMachineView::darwinGrabKeyboardEvents(bool fGrab)
-{
-    m_fKeyboardGrabbed = fGrab;
-    if (fGrab)
-    {
-        /* Disable mouse and keyboard event compression/delaying to make sure we *really* get all of the events. */
-        ::CGSetLocalEventsSuppressionInterval(0.0);
-        machineLogic()->mouseHandler()->setMouseCoalescingEnabled(false);
-
-        /* Register the event callback/hook and grab the keyboard. */
-        UICocoaApplication::instance()->registerForNativeEvents(RT_BIT_32(10) | RT_BIT_32(11) | RT_BIT_32(12) /* NSKeyDown  | NSKeyUp | | NSFlagsChanged */,
-                                                                UIMachineView::darwinEventHandlerProc, this);
-
-        ::DarwinGrabKeyboard (false);
-    }
-    else
-    {
-        ::DarwinReleaseKeyboard();
-        UICocoaApplication::instance()->unregisterForNativeEvents(RT_BIT_32(10) | RT_BIT_32(11) | RT_BIT_32(12) /* NSKeyDown  | NSKeyUp | | NSFlagsChanged */,
-                                                                  UIMachineView::darwinEventHandlerProc, this);
-    }
-}
-
-bool UIMachineView::darwinEventHandlerProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser)
-{
-    UIMachineView *view = (UIMachineView*)pvUser;
-    EventRef inEvent = (EventRef)pvCarbonEvent;
-    UInt32 eventClass = ::GetEventClass(inEvent);
-
-    /* Check if this is an application key combo. In that case we will not pass
-     * the event to the guest, but let the host process it. */
-    if (::darwinIsApplicationCommand(pvCocoaEvent))
-        return false;
-
-    /* All keyboard class events needs to be handled. */
-    if (eventClass == kEventClassKeyboard)
-    {
-        if (view->darwinKeyboardEvent (pvCocoaEvent, inEvent))
-            return true;
-    }
-    /* Pass the event along. */
-    return false;
-}
-
 #endif
 
-void UIMachineView::fixModifierState(LONG *piCodes, uint *puCount)
-{
-    /* Synchronize the views of the host and the guest to the modifier keys.
-     * This function will add up to 6 additional keycodes to codes. */
-
-#if defined(Q_WS_X11)
-
-    Window   wDummy1, wDummy2;
-    int      iDummy3, iDummy4, iDummy5, iDummy6;
-    unsigned uMask;
-    unsigned uKeyMaskNum = 0, uKeyMaskCaps = 0, uKeyMaskScroll = 0;
-
-    uKeyMaskCaps          = LockMask;
-    XModifierKeymap* map  = XGetModifierMapping(QX11Info::display());
-    KeyCode keyCodeNum    = XKeysymToKeycode(QX11Info::display(), XK_Num_Lock);
-    KeyCode keyCodeScroll = XKeysymToKeycode(QX11Info::display(), XK_Scroll_Lock);
-
-    for (int i = 0; i < 8; ++ i)
-    {
-        if (keyCodeNum != NoSymbol && map->modifiermap[map->max_keypermod * i] == keyCodeNum)
-            uKeyMaskNum = 1 << i;
-        else if (keyCodeScroll != NoSymbol && map->modifiermap[map->max_keypermod * i] == keyCodeScroll)
-            uKeyMaskScroll = 1 << i;
-    }
-    XQueryPointer(QX11Info::display(), DefaultRootWindow(QX11Info::display()), &wDummy1, &wDummy2,
-                  &iDummy3, &iDummy4, &iDummy5, &iDummy6, &uMask);
-    XFreeModifiermap(map);
-
-    if (uisession()->numLockAdaptionCnt() && (uisession()->isNumLock() ^ !!(uMask & uKeyMaskNum)))
-    {
-        uisession()->setNumLockAdaptionCnt(uisession()->numLockAdaptionCnt() - 1);
-        piCodes[(*puCount)++] = 0x45;
-        piCodes[(*puCount)++] = 0x45 | 0x80;
-    }
-    if (uisession()->capsLockAdaptionCnt() && (uisession()->isCapsLock() ^ !!(uMask & uKeyMaskCaps)))
-    {
-        uisession()->setCapsLockAdaptionCnt(uisession()->capsLockAdaptionCnt() - 1);
-        piCodes[(*puCount)++] = 0x3a;
-        piCodes[(*puCount)++] = 0x3a | 0x80;
-        /* Some keyboard layouts require shift to be pressed to break
-         * capslock.  For simplicity, only do this if shift is not
-         * already held down. */
-        if (uisession()->isCapsLock() && !(m_pressedKeys[0x2a] & IsKeyPressed))
-        {
-            piCodes[(*puCount)++] = 0x2a;
-            piCodes[(*puCount)++] = 0x2a | 0x80;
-        }
-    }
-
-#elif defined(Q_WS_WIN32)
-
-    if (uisession()->numLockAdaptionCnt() && (uisession()->isNumLock() ^ !!(GetKeyState(VK_NUMLOCK))))
-    {
-        uisession()->setNumLockAdaptionCnt(uisession()->numLockAdaptionCnt() - 1);
-        piCodes[(*puCount)++] = 0x45;
-        piCodes[(*puCount)++] = 0x45 | 0x80;
-    }
-    if (uisession()->capsLockAdaptionCnt() && (uisession()->isCapsLock() ^ !!(GetKeyState(VK_CAPITAL))))
-    {
-        uisession()->setCapsLockAdaptionCnt(uisession()->capsLockAdaptionCnt() - 1);
-        piCodes[(*puCount)++] = 0x3a;
-        piCodes[(*puCount)++] = 0x3a | 0x80;
-        /* Some keyboard layouts require shift to be pressed to break
-         * capslock.  For simplicity, only do this if shift is not
-         * already held down. */
-        if (uisession()->isCapsLock() && !(m_pressedKeys[0x2a] & IsKeyPressed))
-        {
-            piCodes[(*puCount)++] = 0x2a;
-            piCodes[(*puCount)++] = 0x2a | 0x80;
-        }
-    }
-
-#elif defined(Q_WS_MAC)
-
-    /* if (uisession()->numLockAdaptionCnt()) ... - NumLock isn't implemented by Mac OS X so ignore it. */
-    if (uisession()->capsLockAdaptionCnt() && (uisession()->isCapsLock() ^ !!(::GetCurrentEventKeyModifiers() & alphaLock)))
-    {
-        uisession()->setCapsLockAdaptionCnt(uisession()->capsLockAdaptionCnt() - 1);
-        piCodes[(*puCount)++] = 0x3a;
-        piCodes[(*puCount)++] = 0x3a | 0x80;
-        /* Some keyboard layouts require shift to be pressed to break
-         * capslock.  For simplicity, only do this if shift is not
-         * already held down. */
-        if (uisession()->isCapsLock() && !(m_pressedKeys[0x2a] & IsKeyPressed))
-        {
-            piCodes[(*puCount)++] = 0x2a;
-            piCodes[(*puCount)++] = 0x2a | 0x80;
-        }
-    }
-
-#else
-
-//#warning Adapt UIMachineView::fixModifierState
-
-#endif
-}
-
-QPoint UIMachineView::viewportToContents(const QPoint &vp) const
-{
-    return QPoint(vp.x() + contentsX(), vp.y() + contentsY());
-}
-
-void UIMachineView::scrollBy(int dx, int dy)
-{
-    horizontalScrollBar()->setValue(horizontalScrollBar()->value() + dx);
-    verticalScrollBar()->setValue(verticalScrollBar()->value() + dy);
-}
-
-#ifdef VBOX_WITH_VIDEOHWACCEL
-void UIMachineView::scrollContentsBy(int dx, int dy)
-{
-    if (m_pFrameBuffer)
-    {
-        m_pFrameBuffer->viewportScrolled(dx, dy);
-    }
-    QAbstractScrollArea::scrollContentsBy(dx, dy);
-}
-#endif
-
-void UIMachineView::emitKeyboardStateChanged()
-{
-    emit keyboardStateChanged(keyboardState());
-}
-
-void UIMachineView::captureKbd(bool fCapture, bool fEmitSignal /* = true */)
-{
-    if (m_bIsKeyboardCaptured == fCapture)
-        return;
-
-#if defined(Q_WS_WIN32)
-    /* On Win32, keyboard grabbing is ineffective, a low-level keyboard hook is used instead. */
-#elif defined(Q_WS_X11)
-    /* On X11, we are using passive XGrabKey for normal (windowed) mode
-     * instead of XGrabKeyboard (called by QWidget::grabKeyboard())
-     * because XGrabKeyboard causes a problem under metacity - a window cannot be moved
-     * using the mouse if it is currently actively grabing the keyboard;
-     * For static modes we are using usual (active) keyboard grabbing. */
-    switch (machineLogic()->visualStateType())
-    {
-        /* If window is moveable we are making passive keyboard grab: */
-        case UIVisualStateType_Normal:
-        {
-            if (fCapture)
-                XGrabKey(QX11Info::display(), AnyKey, AnyModifier, machineWindowWrapper()->machineWindow()->winId(), False, GrabModeAsync, GrabModeAsync);
-            else
-                XUngrabKey(QX11Info::display(), AnyKey, AnyModifier, machineWindowWrapper()->machineWindow()->winId());
-            break;
-        }
-        /* If window is NOT moveable we are making active keyboard grab: */
-        case UIVisualStateType_Fullscreen:
-        case UIVisualStateType_Seamless:
-        {
-            if (fCapture)
-            {
-                /* Keyboard grabbing can fail because of some keyboard shortcut is still grabbed by window manager.
-                 * We can't be sure this shortcut will be released at all, so we will retry to grab keyboard for 50 times,
-                 * and after we will just ignore that issue: */
-                int cTriesLeft = 50;
-                while (cTriesLeft && XGrabKeyboard(QX11Info::display(), machineWindowWrapper()->machineWindow()->winId(), False, GrabModeAsync, GrabModeAsync, CurrentTime)) { --cTriesLeft; }
-            }
-            else
-                XUngrabKeyboard(QX11Info::display(), CurrentTime);
-            break;
-        }
-        /* Should we try to grab keyboard in default case? I think - NO. */
-        default:
-            break;
-    }
-#elif defined(Q_WS_MAC)
-    /* On Mac OS X, we use the Qt methods + disabling global hot keys + watching modifiers
-     * (for right/left separation). */
-    if (fCapture)
-    {
-        ::DarwinDisableGlobalHotKeys(true);
-        grabKeyboard();
-    }
-    else
-    {
-        ::DarwinDisableGlobalHotKeys(false);
-        releaseKeyboard();
-    }
-#else
-    if (fCapture)
-        grabKeyboard();
-    else
-        releaseKeyboard();
-#endif
-
-    m_bIsKeyboardCaptured = fCapture;
-
-    if (fEmitSignal)
-        emitKeyboardStateChanged();
-}
-
-void UIMachineView::saveKeyStates()
-{
-    ::memcpy(m_pressedKeysCopy, m_pressedKeys, sizeof(m_pressedKeys));
-}
-
-void UIMachineView::releaseAllPressedKeys(bool aReleaseHostKey /* = true */)
-{
-    CKeyboard keyboard = session().GetConsole().GetKeyboard();
-    bool fSentRESEND = false;
-
-    /* Send a dummy scan code (RESEND) to prevent the guest OS from recognizing
-     * a single key click (for ex., Alt) and performing an unwanted action
-     * (for ex., activating the menu) when we release all pressed keys below.
-     * Note, that it's just a guess that sending RESEND will give the desired
-     * effect :), but at least it works with NT and W2k guests. */
-    for (uint i = 0; i < SIZEOF_ARRAY (m_pressedKeys); i++)
-    {
-        if (m_pressedKeys[i] & IsKeyPressed)
-        {
-            if (!fSentRESEND)
-            {
-                keyboard.PutScancode (0xFE);
-                fSentRESEND = true;
-            }
-            keyboard.PutScancode(i | 0x80);
-        }
-        else if (m_pressedKeys[i] & IsExtKeyPressed)
-        {
-            if (!fSentRESEND)
-            {
-                keyboard.PutScancode(0xFE);
-                fSentRESEND = true;
-            }
-            QVector <LONG> codes(2);
-            codes[0] = 0xE0;
-            codes[1] = i | 0x80;
-            keyboard.PutScancodes(codes);
-        }
-        m_pressedKeys[i] = 0;
-    }
-
-    if (aReleaseHostKey)
-        m_bIsHostkeyPressed = false;
-
-#ifdef Q_WS_MAC
-    /* Clear most of the modifiers: */
-    m_darwinKeyModifiers &=
-        alphaLock | kEventKeyModifierNumLockMask |
-        (aReleaseHostKey ? 0 : ::DarwinKeyCodeToDarwinModifierMask (m_globalSettings.hostKey()));
-#endif
-
-    emitKeyboardStateChanged();
-}
-
-void UIMachineView::sendChangedKeyStates()
-{
-    QVector <LONG> codes(2);
-    CKeyboard keyboard = session().GetConsole().GetKeyboard();
-    for (uint i = 0; i < SIZEOF_ARRAY(m_pressedKeys); ++ i)
-    {
-        uint8_t os = m_pressedKeysCopy[i];
-        uint8_t ns = m_pressedKeys[i];
-        if ((os & IsKeyPressed) != (ns & IsKeyPressed))
-        {
-            codes[0] = i;
-            if (!(ns & IsKeyPressed))
-                codes[0] |= 0x80;
-            keyboard.PutScancode(codes[0]);
-        }
-        else if ((os & IsExtKeyPressed) != (ns & IsExtKeyPressed))
-        {
-            codes[0] = 0xE0;
-            codes[1] = i;
-            if (!(ns & IsExtKeyPressed))
-                codes[1] |= 0x80;
-            keyboard.PutScancodes(codes);
-        }
-    }
-}
-
-void UIMachineView::dimImage(QImage &img)
-{
-    for (int y = 0; y < img.height(); ++ y)
-    {
-        if (y % 2)
-        {
-            if (img.depth() == 32)
-            {
-                for (int x = 0; x < img.width(); ++ x)
-                {
-                    int gray = qGray(img.pixel (x, y)) / 2;
-                    img.setPixel(x, y, qRgb (gray, gray, gray));
-                }
-            }
-            else
-            {
-                ::memset(img.scanLine (y), 0, img.bytesPerLine());
-            }
-        }
-        else
-        {
-            if (img.depth() == 32)
-            {
-                for (int x = 0; x < img.width(); ++ x)
-                {
-                    int gray = (2 * qGray (img.pixel (x, y))) / 3;
-                    img.setPixel(x, y, qRgb (gray, gray, gray));
-                }
-            }
-        }
-    }
-}
-
-#ifdef Q_WS_MAC
-CGImageRef UIMachineView::vmContentImage()
-{
-    if (!m_pauseShot.isNull())
-    {
-        CGImageRef pauseImg = ::darwinToCGImageRef(&m_pauseShot);
-        /* Use the pause image as background */
-        return pauseImg;
-    }
-    else
-    {
-# ifdef VBOX_GUI_USE_QUARTZ2D
-        if (vboxGlobal().vmRenderMode() == VBoxDefs::Quartz2DMode)
-        {
-            /* If the render mode is Quartz2D we could use the CGImageRef
-             * of the framebuffer for the dock icon creation. This saves
-             * some conversion time. */
-            CGImageRef image = static_cast<UIFrameBufferQuartz2D*>(m_pFrameBuffer)->imageRef();
-            CGImageRetain(image); /* Retain it, cause the consumer will release it. */
-            return image;
-        }
-        else
-# endif /* VBOX_GUI_USE_QUARTZ2D */
-            /* In image mode we have to create the image ref out of the
-             * framebuffer */
-            return frameBuffertoCGImageRef(m_pFrameBuffer);
-    }
-    return 0;
-}
-
-CGImageRef UIMachineView::frameBuffertoCGImageRef(UIFrameBuffer *pFrameBuffer)
-{
-    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
-    Assert(cs);
-    /* Create the image copy of the framebuffer */
-    CGDataProviderRef dp = CGDataProviderCreateWithData(pFrameBuffer, pFrameBuffer->address(), pFrameBuffer->bitsPerPixel() / 8 * pFrameBuffer->width() * pFrameBuffer->height(), NULL);
-    Assert(dp);
-    CGImageRef ir = CGImageCreate(pFrameBuffer->width(), pFrameBuffer->height(), 8, 32, pFrameBuffer->bytesPerLine(), cs,
-                                  kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
-                                  kCGRenderingIntentDefault);
-    Assert(ir);
-    CGDataProviderRelease(dp);
-    CGColorSpaceRelease(cs);
-
-    return ir;
-}
-
-void UIMachineView::updateDockIcon()
-{
-    machineLogic()->updateDockIcon();
-}
-#endif /* Q_WS_MAC */
-
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 30548)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 30549)
@@ -54,5 +54,5 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
                                  , bool bAccelerate2DVideo
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
     );
     /* Factory function to destroy required machine-view: */
@@ -68,4 +68,9 @@
     virtual void normalizeGeometry(bool /* bAdjustPosition = false */) = 0;
 
+protected slots:
+
+    /* Console callback handlers: */
+    virtual void sltMachineStateChanged();
+
 signals:
 
@@ -83,10 +88,26 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
                   , bool bAccelerate2DVideo
-#endif
+#endif /* VBOX_WITH_VIDEOHWACCEL */
     );
     /* Machine-view destructor: */
     virtual ~UIMachineView();
 
+    /* Prepare routines: */
+    virtual void prepareFrameBuffer();
+    virtual void prepareCommon();
+    virtual void prepareFilters();
+    virtual void prepareConsoleConnections();
+    virtual void loadMachineViewSettings();
+
+    /* Cleanup routines: */
+    //virtual void saveMachineViewSettings() {}
+    //virtual void cleanupConsoleConnections() {}
+    //virtual void cleanupFilters() {}
+    virtual void cleanupCommon();
+    virtual void cleanupFrameBuffer();
+
     /* Protected getters: */
+    UIMachineWindow* machineWindowWrapper() const { return m_pMachineWindow; }
+    UIMachineLogic* machineLogic() const;
     UISession* uisession() const;
     CSession& session();
@@ -100,6 +121,4 @@
     ulong screenId() const { return m_uScreenId; }
     UIFrameBuffer* frameBuffer() const { return m_pFrameBuffer; }
-    UIMachineWindow* machineWindowWrapper() const { return m_pMachineWindow; }
-    UIMachineLogic* machineLogic() const;
     bool isHostKeyPressed() const { return m_bIsHostkeyPressed; }
     bool isMachineWindowResizeIgnored() const { return m_bIsMachineWindowResizeIgnored; }
@@ -126,5 +145,16 @@
     virtual void maybeRestrictMinimumSize() = 0;
     virtual void updateSliders();
-
+    void fixModifierState(LONG *piCodes, uint *puCount);
+    QPoint viewportToContents(const QPoint &vp) const;
+    void scrollBy(int dx, int dy);
+    void emitKeyboardStateChanged();
+    void captureKbd(bool fCapture, bool fEmitSignal = true);
+    void saveKeyStates();
+    void releaseAllPressedKeys(bool aReleaseHostKey = true);
+    void sendChangedKeyStates();
+    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();
@@ -133,33 +163,7 @@
 #endif /* Q_WS_MAC */
 
-    /* Prepare routines: */
-    virtual void prepareFrameBuffer();
-    virtual void prepareCommon();
-    virtual void prepareFilters();
-    virtual void prepareConsoleConnections();
-    virtual void loadMachineViewSettings();
-
-    /* Cleanup routines: */
-    //virtual void saveMachineViewSettings() {}
-    //virtual void cleanupConsoleConnections() {}
-    //virtual void cleanupFilters() {}
-    virtual void cleanupCommon();
-    virtual void cleanupFrameBuffer();
-
     /* Cross-platforms event processors: */
     bool event(QEvent *pEvent);
     bool eventFilter(QObject *pWatched, QEvent *pEvent);
-
-    /* Protected variables: */
-    QSize m_desktopGeometry;
-
-protected slots:
-
-    /* Console callback handlers: */
-    virtual void sltMachineStateChanged();
-
-private:
-
-    /* Cross-platforms event processors: */
     void focusEvent(bool aHasFocus, bool aReleaseHostKey = true);
     bool keyEvent(int aKey, uint8_t aScan, int aFlags, wchar_t *aUniKey = NULL);
@@ -169,5 +173,5 @@
 
     /* Platform specific event processors: */
-#if defined(Q_WS_WIN32)
+#if defined(Q_WS_WIN)
     static LRESULT CALLBACK lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
     bool winLowKeyboardEvent(UINT msg, const KBDLLHOOKSTRUCT &event);
@@ -178,23 +182,8 @@
     bool x11Event(XEvent *event);
 #elif defined(Q_WS_MAC)
-    bool darwinKeyboardEvent(const void *pvCocoaEvent, EventRef inEvent);
     void darwinGrabKeyboardEvents(bool fGrab);
     static bool darwinEventHandlerProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser);
+    bool darwinKeyboardEvent(const void *pvCocoaEvent, EventRef inEvent);
 #endif
-
-    /* Private helpers: */
-    void fixModifierState(LONG *piCodes, uint *puCount);
-    QPoint viewportToContents(const QPoint &vp) const;
-    void scrollBy(int dx, int dy);
-#ifdef VBOX_WITH_VIDEOHWACCEL
-    void scrollContentsBy(int dx, int dy);
-#endif
-    void emitKeyboardStateChanged();
-    void captureKbd(bool fCapture, bool fEmitSignal = true);
-    void saveKeyStates();
-    void releaseAllPressedKeys(bool aReleaseHostKey = true);
-    void sendChangedKeyStates();
-
-    static void dimImage(QImage &img);
 
     /* Private members: */
@@ -206,4 +195,5 @@
 
     DesktopGeo m_desktopGeometryType;
+    QSize m_desktopGeometry;
     QSize m_storedConsoleSize;
 
@@ -218,6 +208,6 @@
     bool m_fPassCAD : 1;
 #ifdef VBOX_WITH_VIDEOHWACCEL
-    bool m_fAccelerate2DVideo;
-#endif
+    bool m_fAccelerate2DVideo : 1;
+#endif /* VBOX_WITH_VIDEOHWACCEL */
 
 #ifdef Q_WS_MAC
