Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 53000)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 53001)
@@ -159,4 +159,738 @@
     delete pSession;
     pSession = 0;
+}
+
+void UISession::powerUp()
+{
+    /* Prepare powerup: */
+    bool fPrepared = preparePowerUp();
+    if (!fPrepared)
+        return;
+
+    /* Get current machine/console: */
+    CMachine machine = session().GetMachine();
+    CConsole console = session().GetConsole();
+
+    /* Apply debug settings from the command line. */
+    CMachineDebugger debugger = console.GetDebugger();
+    if (debugger.isOk())
+    {
+        if (vboxGlobal().isPatmDisabled())
+            debugger.SetPATMEnabled(false);
+        if (vboxGlobal().isCsamDisabled())
+            debugger.SetCSAMEnabled(false);
+        if (vboxGlobal().isSupervisorCodeExecedRecompiled())
+            debugger.SetRecompileSupervisor(true);
+        if (vboxGlobal().isUserCodeExecedRecompiled())
+            debugger.SetRecompileUser(true);
+        if (vboxGlobal().areWeToExecuteAllInIem())
+            debugger.SetExecuteAllInIEM(true);
+        if (!vboxGlobal().isDefaultWarpPct())
+            debugger.SetVirtualTimeRate(vboxGlobal().getWarpPct());
+    }
+
+    if (!vboxGlobal().isSeparateProcess())
+    {
+        /* Power UP machine: */
+#ifdef VBOX_WITH_DEBUGGER_GUI
+        CProgress progress = vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled() ?
+                             console.PowerUpPaused() : console.PowerUp();
+#else /* !VBOX_WITH_DEBUGGER_GUI */
+        CProgress progress = console.PowerUp();
+#endif /* !VBOX_WITH_DEBUGGER_GUI */
+
+        /* Check for immediate failure: */
+        if (!console.isOk())
+        {
+            if (vboxGlobal().showStartVMErrors())
+                msgCenter().cannotStartMachine(console, machine.GetName());
+            closeRuntimeUI();
+            return;
+        }
+
+        /* Guard progressbar warnings from auto-closing: */
+        if (uimachine()->machineLogic())
+            uimachine()->machineLogic()->setPreventAutoClose(true);
+
+        /* Show "Starting/Restoring" progress dialog: */
+        if (isSaved())
+        {
+            msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_restore_90px.png", 0, 0);
+            /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
+            machineLogic()->adjustMachineWindowsGeometry();
+        }
+        else
+            msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_start_90px.png");
+
+        /* Check for a progress failure: */
+        if (!progress.isOk() || progress.GetResultCode() != 0)
+        {
+            if (vboxGlobal().showStartVMErrors())
+                msgCenter().cannotStartMachine(progress, machine.GetName());
+            closeRuntimeUI();
+            return;
+        }
+
+        /* Allow further auto-closing: */
+        if (uimachine()->machineLogic())
+            uimachine()->machineLogic()->setPreventAutoClose(false);
+    }
+    else
+    {
+        /* Fetch the current state: */
+        CMouse mouse = console.GetMouse();
+        m_fIsMouseSupportsAbsolute = mouse.GetAbsoluteSupported();
+        m_fIsMouseSupportsRelative = mouse.GetRelativeSupported();
+        m_fIsMouseSupportsMultiTouch = mouse.GetMultiTouchSupported();
+        m_fIsMouseHostCursorNeeded = mouse.GetNeedsHostCursor();
+
+        sltAdditionsChange();
+    }
+
+    /* Check if we missed a really quick termination after successful startup, and process it if we did: */
+    if (isTurnedOff())
+    {
+        closeRuntimeUI();
+        return;
+    }
+
+    /* Check if the required virtualization features are active. We get this
+     * info only when the session is active. */
+    bool fIs64BitsGuest = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetIs64Bit();
+    bool fRecommendVirtEx = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetRecommendedVirtEx();
+    AssertMsg(!fIs64BitsGuest || fRecommendVirtEx, ("Virtualization support missed for 64bit guest!\n"));
+    bool fIsVirtEnabled = console.GetDebugger().GetHWVirtExEnabled();
+    if (fRecommendVirtEx && !fIsVirtEnabled)
+    {
+        bool fShouldWeClose;
+
+        bool fVTxAMDVSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
+
+        QApplication::processEvents();
+        setPause(true);
+
+        if (fIs64BitsGuest)
+            fShouldWeClose = msgCenter().warnAboutVirtNotEnabled64BitsGuest(fVTxAMDVSupported);
+        else
+            fShouldWeClose = msgCenter().warnAboutVirtNotEnabledGuestRequired(fVTxAMDVSupported);
+
+        if (fShouldWeClose)
+        {
+            /* At this point the console is powered up. So we have to close
+             * this session again. */
+            CProgress progress = console.PowerDown();
+            if (console.isOk())
+            {
+                /* Guard progressbar warnings from auto-closing: */
+                if (uimachine()->machineLogic())
+                    uimachine()->machineLogic()->setPreventAutoClose(true);
+                /* Show the power down progress dialog */
+                msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
+                if (!progress.isOk() || progress.GetResultCode() != 0)
+                    msgCenter().cannotPowerDownMachine(progress, machine.GetName());
+                /* Allow further auto-closing: */
+                if (uimachine()->machineLogic())
+                    uimachine()->machineLogic()->setPreventAutoClose(false);
+            }
+            else
+                msgCenter().cannotPowerDownMachine(console);
+            closeRuntimeUI();
+            return;
+        }
+
+        setPause(false);
+    }
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    LogRel(("2D video acceleration is %s.\n",
+           machine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()
+                 ? "enabled"
+                 : "disabled"));
+#endif
+
+/* Check if HID LEDs sync is enabled and add a log message about it. */
+#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
+    if(uimachine()->machineLogic()->isHidLedsSyncEnabled())
+        LogRel(("HID LEDs sync is enabled.\n"));
+    else
+        LogRel(("HID LEDs sync is disabled.\n"));
+#else
+    LogRel(("HID LEDs sync is not supported on this platform.\n"));
+#endif
+
+#ifdef VBOX_GUI_WITH_PIDFILE
+    vboxGlobal().createPidfile();
+#endif
+
+    /* Warn listeners about machine was started: */
+    emit sigStarted();
+}
+
+bool UISession::saveState()
+{
+    /* Prepare the saving progress: */
+    CMachine machine = m_session.GetMachine();
+    CConsole console = m_session.GetConsole();
+    CProgress progress = console.SaveState();
+    if (console.isOk())
+    {
+        /* Show the saving progress: */
+        msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_save_90px.png");
+        if (!progress.isOk() || progress.GetResultCode() != 0)
+        {
+            /* Failed in progress: */
+            msgCenter().cannotSaveMachineState(progress, machine.GetName());
+            return false;
+        }
+    }
+    else
+    {
+        /* Failed in console: */
+        msgCenter().cannotSaveMachineState(console);
+        return false;
+    }
+    /* Passed: */
+    return true;
+}
+
+bool UISession::shutdown()
+{
+    /* Send ACPI shutdown signal if possible: */
+    CConsole console = m_session.GetConsole();
+    console.PowerButton();
+    if (!console.isOk())
+    {
+        /* Failed in console: */
+        msgCenter().cannotACPIShutdownMachine(console);
+        return false;
+    }
+    /* Passed: */
+    return true;
+}
+
+bool UISession::powerOff(bool fIncludingDiscard, bool &fServerCrashed)
+{
+    /* Prepare the power-off progress: */
+    CMachine machine = m_session.GetMachine();
+    CConsole console = m_session.GetConsole();
+    CProgress progress = console.PowerDown();
+    if (console.isOk())
+    {
+        /* Show the power-off progress: */
+        msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
+        if (progress.isOk() && progress.GetResultCode() == 0)
+        {
+            /* Discard the current state if requested: */
+            if (fIncludingDiscard)
+            {
+                /* Prepare the snapshot-discard progress: */
+                CSnapshot snapshot = machine.GetCurrentSnapshot();
+                CProgress progress = console.RestoreSnapshot(snapshot);
+                if (!console.isOk())
+                    return msgCenter().cannotRestoreSnapshot(console, snapshot.GetName(), machine.GetName());
+
+                /* Show the snapshot-discard progress: */
+                msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_discard_90px.png");
+                if (progress.GetResultCode() != 0)
+                    return msgCenter().cannotRestoreSnapshot(progress, snapshot.GetName(), machine.GetName());
+            }
+        }
+        else
+        {
+            /* Failed in progress: */
+            msgCenter().cannotPowerDownMachine(progress, machine.GetName());
+            return false;
+        }
+    }
+    else
+    {
+        /* Check the machine state, it might be already gone: */
+        if (!console.isNull())
+        {
+           /* Failed in console: */
+           COMResult res(console);
+           /* This can happen if VBoxSVC is not running: */
+           if (FAILED_DEAD_INTERFACE(res.rc()))
+               fServerCrashed = true;
+           else
+               msgCenter().cannotPowerDownMachine(console);
+           return false;
+        }
+    }
+    /* Passed: */
+    return true;
+}
+
+void UISession::closeRuntimeUI()
+{
+    /* Start corresponding slot asynchronously: */
+    emit sigCloseRuntimeUI();
+}
+
+UIMachineLogic* UISession::machineLogic() const
+{
+    return uimachine()->machineLogic();
+}
+
+QWidget* UISession::mainMachineWindow() const
+{
+    return machineLogic()->mainMachineWindow();
+}
+
+bool UISession::isVisualStateAllowed(UIVisualStateType state) const
+{
+    return m_pMachine->isVisualStateAllowed(state);
+}
+
+void UISession::changeVisualState(UIVisualStateType visualStateType)
+{
+    m_pMachine->asyncChangeVisualState(visualStateType);
+}
+
+bool UISession::setPause(bool fOn)
+{
+    CConsole console = session().GetConsole();
+    if (console.isNull())
+        return true;
+
+    if (fOn)
+        console.Pause();
+    else
+        console.Resume();
+
+    bool ok = console.isOk();
+    if (!ok)
+    {
+        if (fOn)
+            msgCenter().cannotPauseMachine(console);
+        else
+            msgCenter().cannotResumeMachine(console);
+    }
+
+    return ok;
+}
+
+void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
+{
+    /* This flag indicates whether we want to do the usual .ISO mounting or not.
+     * First try updating the Guest Additions directly without mounting the .ISO. */
+    bool fDoMount = false;
+
+    /* Auto-update in GUI currently is disabled. */
+#ifndef VBOX_WITH_ADDITIONS_AUTOUPDATE_UI
+    fDoMount = true;
+#else /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
+    CGuest guest = session().GetConsole().GetGuest();
+    QVector<KAdditionsUpdateFlag> aFlagsUpdate;
+    QVector<QString> aArgs;
+    CProgress progressInstall = guest.UpdateGuestAdditions(strSource,
+                                                           aArgs, aFlagsUpdate);
+    bool fResult = guest.isOk();
+    if (fResult)
+    {
+        msgCenter().showModalProgressDialog(progressInstall, tr("Updating Guest Additions"),
+                                            ":/progress_install_guest_additions_90px.png",
+                                            0, 500 /* 500ms delay. */);
+        if (progressInstall.GetCanceled())
+            return;
+
+        HRESULT rc = progressInstall.GetResultCode();
+        if (!progressInstall.isOk() || rc != S_OK)
+        {
+            /* If we got back a VBOX_E_NOT_SUPPORTED we don't complain (guest OS
+             * simply isn't supported yet), so silently fall back to "old" .ISO
+             * mounting method. */
+            if (   !SUCCEEDED_WARNING(rc)
+                && rc != VBOX_E_NOT_SUPPORTED)
+            {
+                msgCenter().cannotUpdateGuestAdditions(progressInstall);
+
+                /* Log the error message in the release log. */
+                QString strErr = progressInstall.GetErrorInfo().GetText();
+                if (!strErr.isEmpty())
+                    LogRel(("%s\n", strErr.toLatin1().constData()));
+            }
+            fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
+        }
+    }
+#endif /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
+
+    /* Do we still want mounting? */
+    if (!fDoMount)
+        return;
+
+    /* Open corresponding medium: */
+    QString strMediumID;
+    CVirtualBox vbox = vboxGlobal().virtualBox();
+    CMedium image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
+    if (vbox.isOk() && !image.isNull())
+        strMediumID = image.GetId();
+    else
+    {
+        msgCenter().cannotOpenMedium(vbox, UIMediumType_DVD, strSource, mainMachineWindow());
+        return;
+    }
+
+    /* Make sure GA medium ID is valid: */
+    AssertReturnVoid(!strMediumID.isNull());
+
+    /* Get machine: */
+    CMachine machine = session().GetMachine();
+
+    /* Searching for the first suitable controller/slot: */
+    QString strControllerName;
+    LONG iCntPort = -1, iCntDevice = -1;
+    foreach (const CStorageController &controller, machine.GetStorageControllers())
+    {
+        foreach (const CMediumAttachment &attachment, machine.GetMediumAttachmentsOfController(controller.GetName()))
+        {
+            if (attachment.GetType() == KDeviceType_DVD)
+            {
+                strControllerName = controller.GetName();
+                iCntPort = attachment.GetPort();
+                iCntDevice = attachment.GetDevice();
+                break;
+            }
+        }
+        if (!strControllerName.isNull())
+            break;
+    }
+
+    /* Make sure suitable controller/slot were found: */
+    if (strControllerName.isNull())
+    {
+        msgCenter().cannotMountGuestAdditions(machine.GetName());
+        return;
+    }
+
+    /* Try to find UIMedium among cached: */
+    UIMedium medium = vboxGlobal().medium(strMediumID);
+    if (medium.isNull())
+    {
+        /* Create new one if necessary: */
+        medium = UIMedium(image, UIMediumType_DVD, KMediumState_Created);
+        vboxGlobal().createMedium(medium);
+    }
+
+    /* Mount medium to corresponding controller/slot: */
+    machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), false /* force */);
+    if (!machine.isOk())
+    {
+        /* Ask for force mounting: */
+        if (msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
+                                            true /* retry? */, mainMachineWindow()))
+        {
+            /* Force mount medium to the predefined port/device: */
+            machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), true /* force */);
+            if (!machine.isOk())
+                msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
+                                                false /* retry? */, mainMachineWindow());
+        }
+    }
+}
+
+void UISession::sltCloseRuntimeUI()
+{
+    /* First, we have to hide any opened modal/popup widgets.
+     * They then should unlock their event-loops synchronously.
+     * If all such loops are unlocked, we can close Runtime UI: */
+    if (QWidget *pWidget = QApplication::activeModalWidget() ?
+                           QApplication::activeModalWidget() :
+                           QApplication::activePopupWidget() ?
+                           QApplication::activePopupWidget() : 0)
+    {
+        /* First we should try to close this widget: */
+        pWidget->close();
+        /* If widget rejected the 'close-event' we can
+         * still hide it and hope it will behave correctly
+         * and unlock his event-loop if any: */
+        if (!pWidget->isHidden())
+            pWidget->hide();
+        /* Restart this slot: */
+        emit sigCloseRuntimeUI();
+        return;
+    }
+
+    /* Finally close the Runtime UI: */
+    UIMachine::destroy();
+}
+
+#ifdef RT_OS_DARWIN
+void UISession::sltHandleMenuBarConfigurationChange()
+{
+    /* Update Mac OS X menu-bar: */
+    updateMenu();
+}
+#endif /* RT_OS_DARWIN */
+
+void UISession::sltMousePointerShapeChange(bool fVisible, bool fAlpha, QPoint hotCorner, QSize size, QVector<uint8_t> shape)
+{
+    /* In case of shape data is present: */
+    if (shape.size() > 0)
+    {
+        /* We are ignoring visibility flag: */
+        m_fIsHidingHostPointer = false;
+
+        /* And updating current cursor shape: */
+        setPointerShape(shape.data(), fAlpha,
+                        hotCorner.x(), hotCorner.y(),
+                        size.width(), size.height());
+    }
+    /* In case of shape data is NOT present: */
+    else
+    {
+        /* Remember if we should hide the cursor: */
+        m_fIsHidingHostPointer = !fVisible;
+    }
+
+    /* Notify listeners about mouse capability changed: */
+    emit sigMousePointerShapeChange();
+
+}
+
+void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative, bool fSupportsMultiTouch, bool fNeedsHostCursor)
+{
+    LogRelFlow(("UISession::sltMouseCapabilityChange: "
+                "Supports absolute: %s, Supports relative: %s, "
+                "Supports multi-touch: %s, Needs host cursor: %s\n",
+                fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
+                fSupportsMultiTouch ? "TRUE" : "FALSE", fNeedsHostCursor ? "TRUE" : "FALSE"));
+
+    /* Check if something had changed: */
+    if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
+        || m_fIsMouseSupportsRelative != fSupportsRelative
+        || m_fIsMouseSupportsMultiTouch != fSupportsMultiTouch
+        || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
+    {
+        /* Store new data: */
+        m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
+        m_fIsMouseSupportsRelative = fSupportsRelative;
+        m_fIsMouseSupportsMultiTouch = fSupportsMultiTouch;
+        m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
+
+        /* Notify listeners about mouse capability changed: */
+        emit sigMouseCapabilityChange();
+    }
+}
+
+void UISession::sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
+{
+    /* Check if something had changed: */
+    if (   m_fNumLock != fNumLock
+        || m_fCapsLock != fCapsLock
+        || m_fScrollLock != fScrollLock)
+    {
+        /* Store new num lock data: */
+        if (m_fNumLock != fNumLock)
+        {
+            m_fNumLock = fNumLock;
+            m_uNumLockAdaptionCnt = 2;
+        }
+
+        /* Store new caps lock data: */
+        if (m_fCapsLock != fCapsLock)
+        {
+            m_fCapsLock = fCapsLock;
+            m_uCapsLockAdaptionCnt = 2;
+        }
+
+        /* Store new scroll lock data: */
+        if (m_fScrollLock != fScrollLock)
+        {
+            m_fScrollLock = fScrollLock;
+        }
+
+        /* Notify listeners about mouse capability changed: */
+        emit sigKeyboardLedsChange();
+    }
+}
+
+void UISession::sltStateChange(KMachineState state)
+{
+    /* Check if something had changed: */
+    if (m_machineState != state)
+    {
+        /* Store new data: */
+        m_machineStatePrevious = m_machineState;
+        m_machineState = state;
+
+        /* Notify listeners about machine state changed: */
+        emit sigMachineStateChange();
+    }
+}
+
+void UISession::sltVRDEChange()
+{
+    /* Get machine: */
+    const CMachine machine = session().GetMachine();
+    /* Get VRDE server: */
+    const CVRDEServer &server = machine.GetVRDEServer();
+    bool fIsVRDEServerAvailable = !server.isNull();
+    /* Show/Hide VRDE action depending on VRDE server availability status: */
+    // TODO: Is this status can be changed at runtime?
+    //       Because if no => the place for that stuff is in prepareActions().
+    actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setVisible(fIsVRDEServerAvailable);
+    /* Check/Uncheck VRDE action depending on VRDE server activity status: */
+    if (fIsVRDEServerAvailable)
+        actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setChecked(server.GetEnabled());
+    /* Notify listeners about VRDE change: */
+    emit sigVRDEChange();
+}
+
+void UISession::sltVideoCaptureChange()
+{
+    /* Get machine: */
+    const CMachine machine = session().GetMachine();
+    /* Check/Uncheck Video Capture action depending on feature status: */
+    actionPool()->action(UIActionIndexRT_M_Devices_M_VideoCapture_T_Start)->setChecked(machine.GetVideoCaptureEnabled());
+    /* Notify listeners about Video Capture change: */
+    emit sigVideoCaptureChange();
+}
+
+void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
+{
+    /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
+    if (changeType == KGuestMonitorChangedEventType_NewOrigin)
+        return;
+    /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
+    AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
+    if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
+        return;
+
+    /* Process KGuestMonitorChangedEventType_Enabled change event: */
+    if (   !isScreenVisible(uScreenId)
+        && changeType == KGuestMonitorChangedEventType_Enabled)
+        setScreenVisible(uScreenId, true);
+    /* Process KGuestMonitorChangedEventType_Disabled change event: */
+    else if (   isScreenVisible(uScreenId)
+             && changeType == KGuestMonitorChangedEventType_Disabled)
+        setScreenVisible(uScreenId, false);
+
+    /* Notify listeners about the change: */
+    emit sigGuestMonitorChange(changeType, uScreenId, screenGeo);
+}
+
+#ifdef RT_OS_DARWIN
+/**
+ * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
+ * @note Watchdog is trying to determine display reconfiguration in
+ *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
+ */
+void UISession::sltHandleHostDisplayAboutToChange()
+{
+    LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
+
+    if (m_pWatchdogDisplayChange->isActive())
+        m_pWatchdogDisplayChange->stop();
+    m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
+    m_pWatchdogDisplayChange->start();
+}
+
+/**
+ * MacOS X: Determines display reconfiguration.
+ * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
+ * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
+ */
+void UISession::sltCheckIfHostDisplayChanged()
+{
+    LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
+
+    /* Acquire desktop wrapper: */
+    QDesktopWidget *pDesktop = QApplication::desktop();
+
+    /* Check if display count changed: */
+    if (pDesktop->screenCount() != m_hostScreens.size())
+    {
+        /* Reset watchdog: */
+        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
+        /* Notify listeners about screen-count changed: */
+        return sltHandleHostScreenCountChange();
+    }
+    else
+    {
+        /* Check if at least one display geometry changed: */
+        for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
+        {
+            if (pDesktop->screenGeometry(iScreenIndex) != m_hostScreens.at(iScreenIndex))
+            {
+                /* Reset watchdog: */
+                m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
+                /* Notify listeners about screen-geometry changed: */
+                return sltHandleHostScreenGeometryChange();
+            }
+        }
+    }
+
+    /* Check if watchdog expired, restart if not: */
+    int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
+    if (cTryNumber > 0 && cTryNumber < 40)
+    {
+        /* Restart watchdog again: */
+        m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
+        m_pWatchdogDisplayChange->start();
+    }
+    else
+    {
+        /* Reset watchdog: */
+        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
+    }
+}
+#endif /* RT_OS_DARWIN */
+
+void UISession::sltHandleHostScreenCountChange()
+{
+    LogRelFlow(("UISession: Host-screen count changed.\n"));
+
+    /* Recache display data: */
+    updateHostScreenData();
+
+    /* Notify current machine-logic: */
+    emit sigHostScreenCountChange();
+}
+
+void UISession::sltHandleHostScreenGeometryChange()
+{
+    LogRelFlow(("UISession: Host-screen geometry changed.\n"));
+
+    /* Recache display data: */
+    updateHostScreenData();
+
+    /* Notify current machine-logic: */
+    emit sigHostScreenGeometryChange();
+}
+
+void UISession::sltHandleHostScreenAvailableAreaChange()
+{
+    LogRelFlow(("UISession: Host-screen available-area changed.\n"));
+
+    /* Notify current machine-logic: */
+    emit sigHostScreenAvailableAreaChange();
+}
+
+void UISession::sltAdditionsChange()
+{
+    /* Get our guest: */
+    CGuest guest = session().GetConsole().GetGuest();
+
+    /* Variable flags: */
+    ULONG ulGuestAdditionsRunLevel = guest.GetAdditionsRunLevel();
+    LONG64 lLastUpdatedIgnored;
+    bool fIsGuestSupportsGraphics = guest.GetFacilityStatus(KAdditionsFacilityType_Graphics, lLastUpdatedIgnored)
+                                    == KAdditionsFacilityStatus_Active;
+    bool fIsGuestSupportsSeamless = guest.GetFacilityStatus(KAdditionsFacilityType_Seamless, lLastUpdatedIgnored)
+                                    == KAdditionsFacilityStatus_Active;
+    /* Check if something had changed: */
+    if (m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel ||
+        m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
+        m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
+    {
+        /* Store new data: */
+        m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
+        m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
+        m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
+
+        /* Notify listeners about guest additions state changed: */
+        emit sigAdditionsStateChange();
+    }
 }
 
@@ -215,4 +949,8 @@
 }
 
+UISession::~UISession()
+{
+}
+
 bool UISession::prepare()
 {
@@ -251,769 +989,4 @@
 }
 
-UISession::~UISession()
-{
-}
-
-void UISession::cleanup()
-{
-#ifdef Q_WS_WIN
-    /* Destroy alpha cursor: */
-    if (m_alphaCursor)
-        DestroyIcon(m_alphaCursor);
-#endif /* Q_WS_WIN */
-
-    /* Save settings: */
-    saveSessionSettings();
-
-    /* Cleanup framebuffers: */
-    cleanupFramebuffers();
-
-    /* Cleanup console event-handlers: */
-    cleanupConsoleEventHandlers();
-
-    /* Cleanup connections: */
-    cleanupConnections();
-
-    /* Cleanup actions: */
-    cleanupActions();
-
-    /* Cleanup session: */
-    cleanupSession();
-}
-
-void UISession::powerUp()
-{
-    /* Prepare powerup: */
-    bool fPrepared = preparePowerUp();
-    if (!fPrepared)
-        return;
-
-    /* Get current machine/console: */
-    CMachine machine = session().GetMachine();
-    CConsole console = session().GetConsole();
-
-    /* Apply debug settings from the command line. */
-    CMachineDebugger debugger = console.GetDebugger();
-    if (debugger.isOk())
-    {
-        if (vboxGlobal().isPatmDisabled())
-            debugger.SetPATMEnabled(false);
-        if (vboxGlobal().isCsamDisabled())
-            debugger.SetCSAMEnabled(false);
-        if (vboxGlobal().isSupervisorCodeExecedRecompiled())
-            debugger.SetRecompileSupervisor(true);
-        if (vboxGlobal().isUserCodeExecedRecompiled())
-            debugger.SetRecompileUser(true);
-        if (vboxGlobal().areWeToExecuteAllInIem())
-            debugger.SetExecuteAllInIEM(true);
-        if (!vboxGlobal().isDefaultWarpPct())
-            debugger.SetVirtualTimeRate(vboxGlobal().getWarpPct());
-    }
-
-    if (!vboxGlobal().isSeparateProcess())
-    {
-        /* Power UP machine: */
-#ifdef VBOX_WITH_DEBUGGER_GUI
-        CProgress progress = vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled() ?
-                             console.PowerUpPaused() : console.PowerUp();
-#else /* !VBOX_WITH_DEBUGGER_GUI */
-        CProgress progress = console.PowerUp();
-#endif /* !VBOX_WITH_DEBUGGER_GUI */
-
-        /* Check for immediate failure: */
-        if (!console.isOk())
-        {
-            if (vboxGlobal().showStartVMErrors())
-                msgCenter().cannotStartMachine(console, machine.GetName());
-            closeRuntimeUI();
-            return;
-        }
-
-        /* Guard progressbar warnings from auto-closing: */
-        if (uimachine()->machineLogic())
-            uimachine()->machineLogic()->setPreventAutoClose(true);
-
-        /* Show "Starting/Restoring" progress dialog: */
-        if (isSaved())
-        {
-            msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_restore_90px.png", 0, 0);
-            /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
-            machineLogic()->adjustMachineWindowsGeometry();
-        }
-        else
-            msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_start_90px.png");
-
-        /* Check for a progress failure: */
-        if (!progress.isOk() || progress.GetResultCode() != 0)
-        {
-            if (vboxGlobal().showStartVMErrors())
-                msgCenter().cannotStartMachine(progress, machine.GetName());
-            closeRuntimeUI();
-            return;
-        }
-
-        /* Allow further auto-closing: */
-        if (uimachine()->machineLogic())
-            uimachine()->machineLogic()->setPreventAutoClose(false);
-    }
-    else
-    {
-        /* Fetch the current state: */
-        CMouse mouse = console.GetMouse();
-        m_fIsMouseSupportsAbsolute = mouse.GetAbsoluteSupported();
-        m_fIsMouseSupportsRelative = mouse.GetRelativeSupported();
-        m_fIsMouseSupportsMultiTouch = mouse.GetMultiTouchSupported();
-        m_fIsMouseHostCursorNeeded = mouse.GetNeedsHostCursor();
-
-        sltAdditionsChange();
-    }
-
-    /* Check if we missed a really quick termination after successful startup, and process it if we did: */
-    if (isTurnedOff())
-    {
-        closeRuntimeUI();
-        return;
-    }
-
-    /* Check if the required virtualization features are active. We get this
-     * info only when the session is active. */
-    bool fIs64BitsGuest = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetIs64Bit();
-    bool fRecommendVirtEx = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetRecommendedVirtEx();
-    AssertMsg(!fIs64BitsGuest || fRecommendVirtEx, ("Virtualization support missed for 64bit guest!\n"));
-    bool fIsVirtEnabled = console.GetDebugger().GetHWVirtExEnabled();
-    if (fRecommendVirtEx && !fIsVirtEnabled)
-    {
-        bool fShouldWeClose;
-
-        bool fVTxAMDVSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
-
-        QApplication::processEvents();
-        setPause(true);
-
-        if (fIs64BitsGuest)
-            fShouldWeClose = msgCenter().warnAboutVirtNotEnabled64BitsGuest(fVTxAMDVSupported);
-        else
-            fShouldWeClose = msgCenter().warnAboutVirtNotEnabledGuestRequired(fVTxAMDVSupported);
-
-        if (fShouldWeClose)
-        {
-            /* At this point the console is powered up. So we have to close
-             * this session again. */
-            CProgress progress = console.PowerDown();
-            if (console.isOk())
-            {
-                /* Guard progressbar warnings from auto-closing: */
-                if (uimachine()->machineLogic())
-                    uimachine()->machineLogic()->setPreventAutoClose(true);
-                /* Show the power down progress dialog */
-                msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
-                if (!progress.isOk() || progress.GetResultCode() != 0)
-                    msgCenter().cannotPowerDownMachine(progress, machine.GetName());
-                /* Allow further auto-closing: */
-                if (uimachine()->machineLogic())
-                    uimachine()->machineLogic()->setPreventAutoClose(false);
-            }
-            else
-                msgCenter().cannotPowerDownMachine(console);
-            closeRuntimeUI();
-            return;
-        }
-
-        setPause(false);
-    }
-
-#ifdef VBOX_WITH_VIDEOHWACCEL
-    LogRel(("2D video acceleration is %s.\n",
-           machine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()
-                 ? "enabled"
-                 : "disabled"));
-#endif
-
-/* Check if HID LEDs sync is enabled and add a log message about it. */
-#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
-    if(uimachine()->machineLogic()->isHidLedsSyncEnabled())
-        LogRel(("HID LEDs sync is enabled.\n"));
-    else
-        LogRel(("HID LEDs sync is disabled.\n"));
-#else
-    LogRel(("HID LEDs sync is not supported on this platform.\n"));
-#endif
-
-#ifdef VBOX_GUI_WITH_PIDFILE
-    vboxGlobal().createPidfile();
-#endif
-
-    /* Warn listeners about machine was started: */
-    emit sigStarted();
-}
-
-bool UISession::saveState()
-{
-    /* Prepare the saving progress: */
-    CMachine machine = m_session.GetMachine();
-    CConsole console = m_session.GetConsole();
-    CProgress progress = console.SaveState();
-    if (console.isOk())
-    {
-        /* Show the saving progress: */
-        msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_save_90px.png");
-        if (!progress.isOk() || progress.GetResultCode() != 0)
-        {
-            /* Failed in progress: */
-            msgCenter().cannotSaveMachineState(progress, machine.GetName());
-            return false;
-        }
-    }
-    else
-    {
-        /* Failed in console: */
-        msgCenter().cannotSaveMachineState(console);
-        return false;
-    }
-    /* Passed: */
-    return true;
-}
-
-bool UISession::shutdown()
-{
-    /* Send ACPI shutdown signal if possible: */
-    CConsole console = m_session.GetConsole();
-    console.PowerButton();
-    if (!console.isOk())
-    {
-        /* Failed in console: */
-        msgCenter().cannotACPIShutdownMachine(console);
-        return false;
-    }
-    /* Passed: */
-    return true;
-}
-
-bool UISession::powerOff(bool fIncludingDiscard, bool &fServerCrashed)
-{
-    /* Prepare the power-off progress: */
-    CMachine machine = m_session.GetMachine();
-    CConsole console = m_session.GetConsole();
-    CProgress progress = console.PowerDown();
-    if (console.isOk())
-    {
-        /* Show the power-off progress: */
-        msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
-        if (progress.isOk() && progress.GetResultCode() == 0)
-        {
-            /* Discard the current state if requested: */
-            if (fIncludingDiscard)
-            {
-                /* Prepare the snapshot-discard progress: */
-                CSnapshot snapshot = machine.GetCurrentSnapshot();
-                CProgress progress = console.RestoreSnapshot(snapshot);
-                if (!console.isOk())
-                    return msgCenter().cannotRestoreSnapshot(console, snapshot.GetName(), machine.GetName());
-
-                /* Show the snapshot-discard progress: */
-                msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_discard_90px.png");
-                if (progress.GetResultCode() != 0)
-                    return msgCenter().cannotRestoreSnapshot(progress, snapshot.GetName(), machine.GetName());
-            }
-        }
-        else
-        {
-            /* Failed in progress: */
-            msgCenter().cannotPowerDownMachine(progress, machine.GetName());
-            return false;
-        }
-    }
-    else
-    {
-        /* Check the machine state, it might be already gone: */
-        if (!console.isNull())
-        {
-           /* Failed in console: */
-           COMResult res(console);
-           /* This can happen if VBoxSVC is not running: */
-           if (FAILED_DEAD_INTERFACE(res.rc()))
-               fServerCrashed = true;
-           else
-               msgCenter().cannotPowerDownMachine(console);
-           return false;
-        }
-    }
-    /* Passed: */
-    return true;
-}
-
-void UISession::closeRuntimeUI()
-{
-    /* Start corresponding slot asynchronously: */
-    emit sigCloseRuntimeUI();
-}
-
-UIMachineLogic* UISession::machineLogic() const
-{
-    return uimachine()->machineLogic();
-}
-
-QWidget* UISession::mainMachineWindow() const
-{
-    return machineLogic()->mainMachineWindow();
-}
-
-bool UISession::isVisualStateAllowed(UIVisualStateType state) const
-{
-    return m_pMachine->isVisualStateAllowed(state);
-}
-
-void UISession::changeVisualState(UIVisualStateType visualStateType)
-{
-    m_pMachine->asyncChangeVisualState(visualStateType);
-}
-
-bool UISession::setPause(bool fOn)
-{
-    CConsole console = session().GetConsole();
-    if (console.isNull())
-        return true;
-
-    if (fOn)
-        console.Pause();
-    else
-        console.Resume();
-
-    bool ok = console.isOk();
-    if (!ok)
-    {
-        if (fOn)
-            msgCenter().cannotPauseMachine(console);
-        else
-            msgCenter().cannotResumeMachine(console);
-    }
-
-    return ok;
-}
-
-void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
-{
-    /* This flag indicates whether we want to do the usual .ISO mounting or not.
-     * First try updating the Guest Additions directly without mounting the .ISO. */
-    bool fDoMount = false;
-
-    /* Auto-update in GUI currently is disabled. */
-#ifndef VBOX_WITH_ADDITIONS_AUTOUPDATE_UI
-    fDoMount = true;
-#else /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
-    CGuest guest = session().GetConsole().GetGuest();
-    QVector<KAdditionsUpdateFlag> aFlagsUpdate;
-    QVector<QString> aArgs;
-    CProgress progressInstall = guest.UpdateGuestAdditions(strSource,
-                                                           aArgs, aFlagsUpdate);
-    bool fResult = guest.isOk();
-    if (fResult)
-    {
-        msgCenter().showModalProgressDialog(progressInstall, tr("Updating Guest Additions"),
-                                            ":/progress_install_guest_additions_90px.png",
-                                            0, 500 /* 500ms delay. */);
-        if (progressInstall.GetCanceled())
-            return;
-
-        HRESULT rc = progressInstall.GetResultCode();
-        if (!progressInstall.isOk() || rc != S_OK)
-        {
-            /* If we got back a VBOX_E_NOT_SUPPORTED we don't complain (guest OS
-             * simply isn't supported yet), so silently fall back to "old" .ISO
-             * mounting method. */
-            if (   !SUCCEEDED_WARNING(rc)
-                && rc != VBOX_E_NOT_SUPPORTED)
-            {
-                msgCenter().cannotUpdateGuestAdditions(progressInstall);
-
-                /* Log the error message in the release log. */
-                QString strErr = progressInstall.GetErrorInfo().GetText();
-                if (!strErr.isEmpty())
-                    LogRel(("%s\n", strErr.toLatin1().constData()));
-            }
-            fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
-        }
-    }
-#endif /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
-
-    /* Do we still want mounting? */
-    if (!fDoMount)
-        return;
-
-    /* Open corresponding medium: */
-    QString strMediumID;
-    CVirtualBox vbox = vboxGlobal().virtualBox();
-    CMedium image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
-    if (vbox.isOk() && !image.isNull())
-        strMediumID = image.GetId();
-    else
-    {
-        msgCenter().cannotOpenMedium(vbox, UIMediumType_DVD, strSource, mainMachineWindow());
-        return;
-    }
-
-    /* Make sure GA medium ID is valid: */
-    AssertReturnVoid(!strMediumID.isNull());
-
-    /* Get machine: */
-    CMachine machine = session().GetMachine();
-
-    /* Searching for the first suitable controller/slot: */
-    QString strControllerName;
-    LONG iCntPort = -1, iCntDevice = -1;
-    foreach (const CStorageController &controller, machine.GetStorageControllers())
-    {
-        foreach (const CMediumAttachment &attachment, machine.GetMediumAttachmentsOfController(controller.GetName()))
-        {
-            if (attachment.GetType() == KDeviceType_DVD)
-            {
-                strControllerName = controller.GetName();
-                iCntPort = attachment.GetPort();
-                iCntDevice = attachment.GetDevice();
-                break;
-            }
-        }
-        if (!strControllerName.isNull())
-            break;
-    }
-
-    /* Make sure suitable controller/slot were found: */
-    if (strControllerName.isNull())
-    {
-        msgCenter().cannotMountGuestAdditions(machine.GetName());
-        return;
-    }
-
-    /* Try to find UIMedium among cached: */
-    UIMedium medium = vboxGlobal().medium(strMediumID);
-    if (medium.isNull())
-    {
-        /* Create new one if necessary: */
-        medium = UIMedium(image, UIMediumType_DVD, KMediumState_Created);
-        vboxGlobal().createMedium(medium);
-    }
-
-    /* Mount medium to corresponding controller/slot: */
-    machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), false /* force */);
-    if (!machine.isOk())
-    {
-        /* Ask for force mounting: */
-        if (msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
-                                            true /* retry? */, mainMachineWindow()))
-        {
-            /* Force mount medium to the predefined port/device: */
-            machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), true /* force */);
-            if (!machine.isOk())
-                msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
-                                                false /* retry? */, mainMachineWindow());
-        }
-    }
-}
-
-void UISession::sltCloseRuntimeUI()
-{
-    /* First, we have to hide any opened modal/popup widgets.
-     * They then should unlock their event-loops synchronously.
-     * If all such loops are unlocked, we can close Runtime UI: */
-    if (QWidget *pWidget = QApplication::activeModalWidget() ?
-                           QApplication::activeModalWidget() :
-                           QApplication::activePopupWidget() ?
-                           QApplication::activePopupWidget() : 0)
-    {
-        /* First we should try to close this widget: */
-        pWidget->close();
-        /* If widget rejected the 'close-event' we can
-         * still hide it and hope it will behave correctly
-         * and unlock his event-loop if any: */
-        if (!pWidget->isHidden())
-            pWidget->hide();
-        /* Restart this slot: */
-        emit sigCloseRuntimeUI();
-        return;
-    }
-
-    /* Finally close the Runtime UI: */
-    UIMachine::destroy();
-}
-
-#ifdef RT_OS_DARWIN
-void UISession::sltHandleMenuBarConfigurationChange()
-{
-    /* Update Mac OS X menu-bar: */
-    updateMenu();
-}
-#endif /* RT_OS_DARWIN */
-
-void UISession::sltMousePointerShapeChange(bool fVisible, bool fAlpha, QPoint hotCorner, QSize size, QVector<uint8_t> shape)
-{
-    /* In case of shape data is present: */
-    if (shape.size() > 0)
-    {
-        /* We are ignoring visibility flag: */
-        m_fIsHidingHostPointer = false;
-
-        /* And updating current cursor shape: */
-        setPointerShape(shape.data(), fAlpha,
-                        hotCorner.x(), hotCorner.y(),
-                        size.width(), size.height());
-    }
-    /* In case of shape data is NOT present: */
-    else
-    {
-        /* Remember if we should hide the cursor: */
-        m_fIsHidingHostPointer = !fVisible;
-    }
-
-    /* Notify listeners about mouse capability changed: */
-    emit sigMousePointerShapeChange();
-
-}
-
-void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative, bool fSupportsMultiTouch, bool fNeedsHostCursor)
-{
-    LogRelFlow(("UISession::sltMouseCapabilityChange: "
-                "Supports absolute: %s, Supports relative: %s, "
-                "Supports multi-touch: %s, Needs host cursor: %s\n",
-                fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
-                fSupportsMultiTouch ? "TRUE" : "FALSE", fNeedsHostCursor ? "TRUE" : "FALSE"));
-
-    /* Check if something had changed: */
-    if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
-        || m_fIsMouseSupportsRelative != fSupportsRelative
-        || m_fIsMouseSupportsMultiTouch != fSupportsMultiTouch
-        || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
-    {
-        /* Store new data: */
-        m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
-        m_fIsMouseSupportsRelative = fSupportsRelative;
-        m_fIsMouseSupportsMultiTouch = fSupportsMultiTouch;
-        m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
-
-        /* Notify listeners about mouse capability changed: */
-        emit sigMouseCapabilityChange();
-    }
-}
-
-void UISession::sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
-{
-    /* Check if something had changed: */
-    if (   m_fNumLock != fNumLock
-        || m_fCapsLock != fCapsLock
-        || m_fScrollLock != fScrollLock)
-    {
-        /* Store new num lock data: */
-        if (m_fNumLock != fNumLock)
-        {
-            m_fNumLock = fNumLock;
-            m_uNumLockAdaptionCnt = 2;
-        }
-
-        /* Store new caps lock data: */
-        if (m_fCapsLock != fCapsLock)
-        {
-            m_fCapsLock = fCapsLock;
-            m_uCapsLockAdaptionCnt = 2;
-        }
-
-        /* Store new scroll lock data: */
-        if (m_fScrollLock != fScrollLock)
-        {
-            m_fScrollLock = fScrollLock;
-        }
-
-        /* Notify listeners about mouse capability changed: */
-        emit sigKeyboardLedsChange();
-    }
-}
-
-void UISession::sltStateChange(KMachineState state)
-{
-    /* Check if something had changed: */
-    if (m_machineState != state)
-    {
-        /* Store new data: */
-        m_machineStatePrevious = m_machineState;
-        m_machineState = state;
-
-        /* Notify listeners about machine state changed: */
-        emit sigMachineStateChange();
-    }
-}
-
-void UISession::sltVRDEChange()
-{
-    /* Get machine: */
-    const CMachine machine = session().GetMachine();
-    /* Get VRDE server: */
-    const CVRDEServer &server = machine.GetVRDEServer();
-    bool fIsVRDEServerAvailable = !server.isNull();
-    /* Show/Hide VRDE action depending on VRDE server availability status: */
-    // TODO: Is this status can be changed at runtime?
-    //       Because if no => the place for that stuff is in prepareActions().
-    actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setVisible(fIsVRDEServerAvailable);
-    /* Check/Uncheck VRDE action depending on VRDE server activity status: */
-    if (fIsVRDEServerAvailable)
-        actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setChecked(server.GetEnabled());
-    /* Notify listeners about VRDE change: */
-    emit sigVRDEChange();
-}
-
-void UISession::sltVideoCaptureChange()
-{
-    /* Get machine: */
-    const CMachine machine = session().GetMachine();
-    /* Check/Uncheck Video Capture action depending on feature status: */
-    actionPool()->action(UIActionIndexRT_M_Devices_M_VideoCapture_T_Start)->setChecked(machine.GetVideoCaptureEnabled());
-    /* Notify listeners about Video Capture change: */
-    emit sigVideoCaptureChange();
-}
-
-void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
-{
-    /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
-    if (changeType == KGuestMonitorChangedEventType_NewOrigin)
-        return;
-    /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
-    AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
-    if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
-        return;
-
-    /* Process KGuestMonitorChangedEventType_Enabled change event: */
-    if (   !isScreenVisible(uScreenId)
-        && changeType == KGuestMonitorChangedEventType_Enabled)
-        setScreenVisible(uScreenId, true);
-    /* Process KGuestMonitorChangedEventType_Disabled change event: */
-    else if (   isScreenVisible(uScreenId)
-             && changeType == KGuestMonitorChangedEventType_Disabled)
-        setScreenVisible(uScreenId, false);
-
-    /* Notify listeners about the change: */
-    emit sigGuestMonitorChange(changeType, uScreenId, screenGeo);
-}
-
-#ifdef RT_OS_DARWIN
-/**
- * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
- * @note Watchdog is trying to determine display reconfiguration in
- *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
- */
-void UISession::sltHandleHostDisplayAboutToChange()
-{
-    LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
-
-    if (m_pWatchdogDisplayChange->isActive())
-        m_pWatchdogDisplayChange->stop();
-    m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
-    m_pWatchdogDisplayChange->start();
-}
-
-/**
- * MacOS X: Determines display reconfiguration.
- * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
- * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
- */
-void UISession::sltCheckIfHostDisplayChanged()
-{
-    LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
-
-    /* Acquire desktop wrapper: */
-    QDesktopWidget *pDesktop = QApplication::desktop();
-
-    /* Check if display count changed: */
-    if (pDesktop->screenCount() != m_hostScreens.size())
-    {
-        /* Reset watchdog: */
-        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
-        /* Notify listeners about screen-count changed: */
-        return sltHandleHostScreenCountChange();
-    }
-    else
-    {
-        /* Check if at least one display geometry changed: */
-        for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
-        {
-            if (pDesktop->screenGeometry(iScreenIndex) != m_hostScreens.at(iScreenIndex))
-            {
-                /* Reset watchdog: */
-                m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
-                /* Notify listeners about screen-geometry changed: */
-                return sltHandleHostScreenGeometryChange();
-            }
-        }
-    }
-
-    /* Check if watchdog expired, restart if not: */
-    int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
-    if (cTryNumber > 0 && cTryNumber < 40)
-    {
-        /* Restart watchdog again: */
-        m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
-        m_pWatchdogDisplayChange->start();
-    }
-    else
-    {
-        /* Reset watchdog: */
-        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
-    }
-}
-#endif /* RT_OS_DARWIN */
-
-void UISession::sltHandleHostScreenCountChange()
-{
-    LogRelFlow(("UISession: Host-screen count changed.\n"));
-
-    /* Recache display data: */
-    updateHostScreenData();
-
-    /* Notify current machine-logic: */
-    emit sigHostScreenCountChange();
-}
-
-void UISession::sltHandleHostScreenGeometryChange()
-{
-    LogRelFlow(("UISession: Host-screen geometry changed.\n"));
-
-    /* Recache display data: */
-    updateHostScreenData();
-
-    /* Notify current machine-logic: */
-    emit sigHostScreenGeometryChange();
-}
-
-void UISession::sltHandleHostScreenAvailableAreaChange()
-{
-    LogRelFlow(("UISession: Host-screen available-area changed.\n"));
-
-    /* Notify current machine-logic: */
-    emit sigHostScreenAvailableAreaChange();
-}
-
-void UISession::sltAdditionsChange()
-{
-    /* Get our guest: */
-    CGuest guest = session().GetConsole().GetGuest();
-
-    /* Variable flags: */
-    ULONG ulGuestAdditionsRunLevel = guest.GetAdditionsRunLevel();
-    LONG64 lLastUpdatedIgnored;
-    bool fIsGuestSupportsGraphics = guest.GetFacilityStatus(KAdditionsFacilityType_Graphics, lLastUpdatedIgnored)
-                                    == KAdditionsFacilityStatus_Active;
-    bool fIsGuestSupportsSeamless = guest.GetFacilityStatus(KAdditionsFacilityType_Seamless, lLastUpdatedIgnored)
-                                    == KAdditionsFacilityStatus_Active;
-    /* Check if something had changed: */
-    if (m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel ||
-        m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
-        m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
-    {
-        /* Store new data: */
-        m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
-        m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
-        m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
-
-        /* Notify listeners about guest additions state changed: */
-        emit sigAdditionsStateChange();
-    }
-}
-
 bool UISession::prepareSession()
 {
@@ -1030,61 +1003,4 @@
     /* True by default: */
     return true;
-}
-
-void UISession::prepareConsoleEventHandlers()
-{
-    /* Create console event-handler: */
-    UIConsoleEventHandler::create(this);
-
-    /* Add console event connections: */
-    connect(gConsoleEvents, SIGNAL(sigMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)),
-            this, SLOT(sltMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)));
-
-    connect(gConsoleEvents, SIGNAL(sigMouseCapabilityChange(bool, bool, bool, bool)),
-            this, SLOT(sltMouseCapabilityChange(bool, bool, bool, bool)));
-
-    connect(gConsoleEvents, SIGNAL(sigKeyboardLedsChangeEvent(bool, bool, bool)),
-            this, SLOT(sltKeyboardLedsChangeEvent(bool, bool, bool)));
-
-    connect(gConsoleEvents, SIGNAL(sigStateChange(KMachineState)),
-            this, SLOT(sltStateChange(KMachineState)));
-
-    connect(gConsoleEvents, SIGNAL(sigAdditionsChange()),
-            this, SLOT(sltAdditionsChange()));
-
-    connect(gConsoleEvents, SIGNAL(sigVRDEChange()),
-            this, SLOT(sltVRDEChange()));
-
-    connect(gConsoleEvents, SIGNAL(sigVideoCaptureChange()),
-            this, SLOT(sltVideoCaptureChange()));
-
-    connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
-            this, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)));
-
-    connect(gConsoleEvents, SIGNAL(sigMediumChange(CMediumAttachment)),
-            this, SIGNAL(sigMediumChange(CMediumAttachment)));
-
-    connect(gConsoleEvents, SIGNAL(sigUSBControllerChange()),
-            this, SIGNAL(sigUSBControllerChange()));
-
-    connect(gConsoleEvents, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)),
-            this, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)));
-
-    connect(gConsoleEvents, SIGNAL(sigSharedFolderChange()),
-            this, SIGNAL(sigSharedFolderChange()));
-
-    connect(gConsoleEvents, SIGNAL(sigRuntimeError(bool, QString, QString)),
-            this, SIGNAL(sigRuntimeError(bool, QString, QString)));
-
-#ifdef Q_WS_MAC
-    connect(gConsoleEvents, SIGNAL(sigShowWindow()),
-            this, SIGNAL(sigShowWindows()), Qt::QueuedConnection);
-#endif /* Q_WS_MAC */
-
-    connect(gConsoleEvents, SIGNAL(sigCPUExecutionCapChange()),
-            this, SIGNAL(sigCPUExecutionCapChange()));
-
-    connect(gConsoleEvents, SIGNAL(sigGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)),
-            this, SLOT(sltGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)));
 }
 
@@ -1200,4 +1116,61 @@
 }
 
+void UISession::prepareConsoleEventHandlers()
+{
+    /* Create console event-handler: */
+    UIConsoleEventHandler::create(this);
+
+    /* Add console event connections: */
+    connect(gConsoleEvents, SIGNAL(sigMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)),
+            this, SLOT(sltMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)));
+
+    connect(gConsoleEvents, SIGNAL(sigMouseCapabilityChange(bool, bool, bool, bool)),
+            this, SLOT(sltMouseCapabilityChange(bool, bool, bool, bool)));
+
+    connect(gConsoleEvents, SIGNAL(sigKeyboardLedsChangeEvent(bool, bool, bool)),
+            this, SLOT(sltKeyboardLedsChangeEvent(bool, bool, bool)));
+
+    connect(gConsoleEvents, SIGNAL(sigStateChange(KMachineState)),
+            this, SLOT(sltStateChange(KMachineState)));
+
+    connect(gConsoleEvents, SIGNAL(sigAdditionsChange()),
+            this, SLOT(sltAdditionsChange()));
+
+    connect(gConsoleEvents, SIGNAL(sigVRDEChange()),
+            this, SLOT(sltVRDEChange()));
+
+    connect(gConsoleEvents, SIGNAL(sigVideoCaptureChange()),
+            this, SLOT(sltVideoCaptureChange()));
+
+    connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
+            this, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)));
+
+    connect(gConsoleEvents, SIGNAL(sigMediumChange(CMediumAttachment)),
+            this, SIGNAL(sigMediumChange(CMediumAttachment)));
+
+    connect(gConsoleEvents, SIGNAL(sigUSBControllerChange()),
+            this, SIGNAL(sigUSBControllerChange()));
+
+    connect(gConsoleEvents, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)),
+            this, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)));
+
+    connect(gConsoleEvents, SIGNAL(sigSharedFolderChange()),
+            this, SIGNAL(sigSharedFolderChange()));
+
+    connect(gConsoleEvents, SIGNAL(sigRuntimeError(bool, QString, QString)),
+            this, SIGNAL(sigRuntimeError(bool, QString, QString)));
+
+#ifdef Q_WS_MAC
+    connect(gConsoleEvents, SIGNAL(sigShowWindow()),
+            this, SIGNAL(sigShowWindows()), Qt::QueuedConnection);
+#endif /* Q_WS_MAC */
+
+    connect(gConsoleEvents, SIGNAL(sigCPUExecutionCapChange()),
+            this, SIGNAL(sigCPUExecutionCapChange()));
+
+    connect(gConsoleEvents, SIGNAL(sigGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)),
+            this, SLOT(sltGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)));
+}
+
 void UISession::prepareScreens()
 {
@@ -1399,4 +1372,31 @@
         m_session.detach();
     }
+}
+
+void UISession::cleanup()
+{
+#ifdef Q_WS_WIN
+    /* Destroy alpha cursor: */
+    if (m_alphaCursor)
+        DestroyIcon(m_alphaCursor);
+#endif /* Q_WS_WIN */
+
+    /* Save settings: */
+    saveSessionSettings();
+
+    /* Cleanup framebuffers: */
+    cleanupFramebuffers();
+
+    /* Cleanup console event-handlers: */
+    cleanupConsoleEventHandlers();
+
+    /* Cleanup connections: */
+    cleanupConnections();
+
+    /* Cleanup actions: */
+    cleanupActions();
+
+    /* Cleanup session: */
+    cleanupSession();
 }
 
