Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 26636)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 26637)
@@ -39,4 +39,7 @@
 VBOX_WITH_UPDATE_REQUEST := 1
 
+# Build new VirtualBox FE/Qt4 GUI runtime core.
+# Currently its not used, you can build it for developing purposes.
+#VBOX_WITH_NEW_RUNTIME_CORE := 1
 
 #
@@ -224,4 +227,9 @@
 	./src/X11 \
 	./src/darwin
+ifdef VBOX_WITH_NEW_RUNTIME_CORE
+VBOX_GUI_INC_DIRS += \
+    ./src/runtime \
+	./src/runtime/normal
+endif
 
 VirtualBox_INCS = \
@@ -360,4 +368,15 @@
 	src/widgets/VBoxSpecialControls.h \
 	src/widgets/VBoxWarningPane.h
+ifdef VBOX_WITH_NEW_RUNTIME_CORE
+VirtualBox_QT_MOCHDRS += \
+	src/runtime/UIActionsPool.h \
+	src/runtime/UIIndicatorsPool.h \
+	src/runtime/UIMachine.h \
+	src/runtime/UIMachineLogic.h \
+	src/runtime/UIMachineView.h \
+	src/runtime/normal/UIMachineLogicNormal.h \
+	src/runtime/normal/UIMachineWindowNormal.h \
+	src/runtime/normal/UIMachineViewNormal.h
+endif
 
 # Sources containing local definitions of classes that use the Q_OBJECT macro.
@@ -367,4 +386,11 @@
 	src/VBoxMediaManagerDlg.cpp \
 	src/wizards/registration/UIRegistrationWzd.cpp
+ifdef VBOX_WITH_NEW_RUNTIME_CORE
+VirtualBox_QT_MOCSRCS += \
+	src/runtime/UIActionsPool.cpp \
+	src/runtime/UIIndicatorsPool.cpp \
+	src/runtime/UIMachine.cpp \
+	src/runtime/UIMachineLogic.cpp
+endif
 ifdef VBOX_WITH_XPCOM
  VirtualBox_QT_MOCSRCS += \
@@ -463,4 +489,17 @@
 	src/widgets/VBoxSpecialControls.cpp \
 	src/widgets/VBoxWarningPane.cpp
+ifdef VBOX_WITH_NEW_RUNTIME_CORE
+VirtualBox_SOURCES += \
+	src/runtime/UIActionsPool.cpp \
+	src/runtime/UIIndicatorsPool.cpp \
+	src/runtime/UIFrameBuffer.cpp \
+	src/runtime/UIMachine.cpp \
+	src/runtime/UIMachineLogic.cpp \
+	src/runtime/UIMachineWindow.cpp \
+	src/runtime/UIMachineView.cpp \
+	src/runtime/normal/UIMachineLogicNormal.cpp \
+	src/runtime/normal/UIMachineWindowNormal.cpp \
+	src/runtime/normal/UIMachineViewNormal.cpp
+endif
 
 ifeq ($(filter-out freebsd linux netbsd openbsd solaris,$(KBUILD_TARGET)),) # X11
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp	(revision 26637)
@@ -0,0 +1,855 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIActionsPool class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Local includes */
+#include "UIActionsPool.h"
+#include "VBoxGlobal.h"
+
+UIAction::UIAction(QObject *pParent, UIActionType type)
+    : QIWithRetranslateUI3<QAction>(pParent)
+    , m_type(type)
+{
+}
+
+UIActionType UIAction::type() const
+{
+    return m_type;
+}
+
+class UISeparatorAction : public UIAction
+{
+    Q_OBJECT;
+
+public:
+
+    UISeparatorAction(QObject *pParent)
+        : UIAction(pParent, UIActionType_Separator)
+    {
+        setSeparator(true);
+    }
+};
+
+class UISimpleAction : public UIAction
+{
+    Q_OBJECT;
+
+public:
+
+    UISimpleAction(QObject *pParent,
+                   const QString &strIcon = QString(), const QString &strIconDis = QString())
+        : UIAction(pParent, UIActionType_Simple)
+    {
+        setIcon(VBoxGlobal::iconSet(strIcon.toLatin1().data(), strIconDis.toLatin1().data()));
+    }
+};
+
+class UIToggleAction : public UIAction
+{
+    Q_OBJECT;
+
+public:
+
+    UIToggleAction(QObject *pParent,
+                   const QString &strIcon = QString(), const QString &strIconDis = QString())
+        : UIAction(pParent, UIActionType_Toggle)
+    {
+        setIcon(VBoxGlobal::iconSet(strIcon.toLatin1().data(), strIconDis.toLatin1().data()));
+        init();
+    }
+
+    UIToggleAction(QObject *pParent,
+                   const QString &strIconOn, const QString &strIconOff,
+                   const QString &strIconOnDis, const QString &strIconOffDis)
+        : UIAction(pParent, UIActionType_Toggle)
+    {
+        setIcon(VBoxGlobal::iconSetOnOff(strIconOn.toLatin1().data(), strIconOff.toLatin1().data(),
+                                         strIconOnDis.toLatin1().data(), strIconOffDis.toLatin1().data()));
+        init();
+    }
+
+private slots:
+
+    void sltUpdateAppearance()
+    {
+        retranslateUi();
+    }
+
+private:
+
+    void init()
+    {
+        setCheckable(true);
+        connect(this, SIGNAL(triggered(bool)), this, SLOT(sltUpdateAppearance()));
+    }
+};
+
+class UIMenuAction : public UIAction
+{
+    Q_OBJECT;
+
+public:
+
+    UIMenuAction(QObject *pParent,
+                 const QString &strIcon = QString(), const QString &strIconDis = QString())
+        : UIAction(pParent, UIActionType_Menu)
+    {
+        setIcon(VBoxGlobal::iconSet(strIcon, strIconDis));
+        setMenu(new QMenu);
+    }
+};
+
+class SeparatorAction : public UISeparatorAction
+{
+    Q_OBJECT;
+
+public:
+
+    SeparatorAction(QObject *pParent)
+        : UISeparatorAction(pParent)
+    {
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+    }
+};
+
+class MenuMachineAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuMachineAction(QObject *pParent)
+        : UIMenuAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(tr("&Machine"));
+    }
+};
+
+class ToggleFullscreenModeAction : public UIToggleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ToggleFullscreenModeAction(QObject *pParent)
+        : UIToggleAction(pParent,
+                         ":/fullscreen_on_16px.png", ":/fullscreen_16px.png",
+                         ":/fullscreen_on_disabled_16px.png", ":/fullscreen_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("&Fullscreen Mode"), "F"));
+        setStatusTip(tr("Switch to fullscreen mode"));
+    }
+};
+
+class ToggleSeamlessModeAction : public UIToggleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ToggleSeamlessModeAction(QObject *pParent)
+        : UIToggleAction(pParent,
+                         ":/seamless_on_16px.png", ":/seamless_16px.png",
+                         ":/seamless_on_disabled_16px.png", ":/seamless_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("Seam&less Mode"), "L"));
+        setStatusTip(tr("Switch to seamless desktop integration mode"));
+    }
+};
+
+class ToggleGuestAutoresizeAction : public UIToggleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ToggleGuestAutoresizeAction(QObject *pParent)
+        : UIToggleAction(pParent,
+                         ":/auto_resize_on_on_16px.png", ":/auto_resize_on_16px.png",
+                         ":/auto_resize_on_on_disabled_16px.png", ":/auto_resize_on_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("Auto-resize &Guest Display"), "G"));
+        setStatusTip(tr("Automatically resize the guest display when the window is resized (requires Guest Additions)"));
+    }
+};
+
+class PerformWindowAdjustAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformWindowAdjustAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/adjust_win_size_16px.png", ":/adjust_win_size_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("&Adjust Window Size"), "A"));
+        setStatusTip(tr("Adjust window size and position to best fit the guest display"));
+    }
+};
+
+class MenuMouseIntegrationAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuMouseIntegrationAction(QObject *pParent)
+        : UIMenuAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+    }
+};
+
+class ToggleMouseIntegrationAction : public UIToggleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ToggleMouseIntegrationAction(QObject *pParent)
+        : UIToggleAction(pParent,
+                         ":/mouse_can_seamless_on_16px.png", ":/mouse_can_seamless_16px.png",
+                         ":/mouse_can_seamless_on_disabled_16px.png", ":/mouse_can_seamless_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        if (!isChecked())
+        {
+            setText(VBoxGlobal::insertKeyToActionText(tr("Disable &Mouse Integration"), "I"));
+            setStatusTip(tr("Temporarily disable host mouse pointer integration"));
+        }
+        else
+        {
+            setText(VBoxGlobal::insertKeyToActionText(tr("Enable &Mouse Integration"), "I"));
+            setStatusTip(tr("Enable temporarily disabled host mouse pointer integration"));
+        }
+    }
+};
+
+class PerformTypeCADAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformTypeCADAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("&Insert Ctrl-Alt-Del"), "Del"));
+        setStatusTip(tr("Send the Ctrl-Alt-Del sequence to the virtual machine"));
+    }
+};
+
+#ifdef Q_WS_X11
+class PerformTypeCABSAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformTypeCABSAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("&Insert Ctrl-Alt-Backspace"), "Backspace"));
+        setStatusTip(tr("Send the Ctrl-Alt-Backspace sequence to the virtual machine"));
+    }
+};
+#endif
+
+class PerformTakeSnapshotAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformTakeSnapshotAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/take_snapshot_16px.png", ":/take_snapshot_dis_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("Take &Snapshot..."), "S"));
+        setStatusTip(tr("Take a snapshot of the virtual machine"));
+    }
+};
+
+class ShowInformationDialogAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ShowInformationDialogAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/session_info_16px.png", ":/session_info_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("Session I&nformation Dialog"), "N"));
+        setStatusTip(tr("Show Session Information Dialog"));
+    }
+};
+
+class PerformResetAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformResetAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/reset_16px.png", ":/reset_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr ("&Reset"), "R"));
+        setStatusTip(tr("Reset the virtual machine"));
+    }
+};
+
+class TogglePauseAction : public UIToggleAction
+{
+    Q_OBJECT;
+
+public:
+
+    TogglePauseAction(QObject *pParent)
+        : UIToggleAction(pParent,
+                         ":/pause_16px.png", ":/pause_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        if (!isChecked())
+        {
+            setText(VBoxGlobal::insertKeyToActionText(tr ("&Pause"), "P"));
+            setStatusTip(tr("Suspend the execution of the virtual machine"));
+        }
+        else
+        {
+            setText(VBoxGlobal::insertKeyToActionText(tr ("R&esume"), "P"));
+            setStatusTip(tr("Resume the execution of the virtual machine"));
+        }
+    }
+};
+
+class PerformShutdownAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformShutdownAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/acpi_16px.png", ":/acpi_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+#ifdef Q_WS_MAC
+        /* Host+H is Hide on the mac */
+        setText(VBoxGlobal::insertKeyToActionText(tr ("ACPI Sh&utdown"), "U"));
+#else /* Q_WS_MAC */
+        setText(VBoxGlobal::insertKeyToActionText(tr ("ACPI S&hutdown"), "H"));
+#endif /* !Q_WS_MAC */
+        setStatusTip(tr("Send the ACPI Power Button press event to the virtual machine"));
+    }
+};
+
+class PerformCloseAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformCloseAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/exit_16px.png")
+    {
+        setMenuRole(QAction::QuitRole);
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("&Close..." ), "Q"));
+        setStatusTip(tr("Close the virtual machine"));
+    }
+};
+
+class MenuDevicesAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuDevicesAction(QObject *pParent)
+        : UIMenuAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(tr("&Devices"));
+    }
+};
+
+class MenuOpticalDevicesAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuOpticalDevicesAction(QObject *pParent)
+        : UIMenuAction(pParent,
+                       ":/cd_16px.png", ":/cd_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(tr("&CD/DVD Devices"));
+    }
+};
+
+class MenuFloppyDevicesAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuFloppyDevicesAction(QObject *pParent)
+        : UIMenuAction(pParent,
+                       ":/fd_16px.png", ":/fd_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(tr("&Floppy Devices"));
+    }
+};
+
+class MenuNetworkAdaptersAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuNetworkAdaptersAction(QObject *pParent)
+        : UIMenuAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+    }
+};
+
+class ShowNetworkAdaptersDialogAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ShowNetworkAdaptersDialogAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/nw_16px.png", ":/nw_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(tr("&Network Adapters..."));
+        setStatusTip(tr("Change the settings of network adapters"));
+    }
+};
+
+class MenuSharedFoldersAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuSharedFoldersAction(QObject *pParent)
+        : UIMenuAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+    }
+};
+
+class ShowSharedFoldersDialogAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ShowSharedFoldersDialogAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/shared_folder_16px.png", ":/shared_folder_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(tr("&Shared Folders..."));
+        setStatusTip(tr("Create or modify shared folders"));
+    }
+};
+
+class MenuUSBDevicesAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuUSBDevicesAction(QObject *pParent)
+        : UIMenuAction(pParent,
+                       ":/usb_16px.png", ":/usb_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(tr("&USB Devices"));
+    }
+};
+
+class ToggleVRDPAction : public UIToggleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ToggleVRDPAction(QObject *pParent)
+        : UIToggleAction(pParent,
+                         ":/vrdp_on_16px.png", ":/vrdp_16px.png",
+                         ":/vrdp_on_disabled_16px.png", ":/vrdp_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(tr("&Remote Display"));
+        setStatusTip(tr("Enable or disable remote desktop (RDP) connections to this machine"));
+    }
+};
+
+class PerformInstallGuestToolsAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    PerformInstallGuestToolsAction(QObject *pParent)
+        : UISimpleAction(pParent,
+                         ":/guesttools_16px.png", ":/guesttools_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(VBoxGlobal::insertKeyToActionText(tr("&Install Guest Additions..."), "D"));
+        setStatusTip(tr("Mount the Guest Additions installation image"));
+    }
+};
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+class MenuDebugAction : public UIMenuAction
+{
+    Q_OBJECT;
+
+public:
+
+    MenuDebugAction(QObject *pParent)
+        : UIMenuAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(tr("De&bug"));
+    }
+};
+
+class ShowStatisticsAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ShowStatisticsAction(QObject *pParent)
+        : UISimpleAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(tr("&Statistics...", "debug action"));
+    }
+};
+
+class ShowCommandLineAction : public UISimpleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ShowCommandLineAction(QObject *pParent)
+        : UISimpleAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(tr("&Command Line...", "debug action"));
+    }
+};
+
+class ToggleLoggingAction : public UIToggleAction
+{
+    Q_OBJECT;
+
+public:
+
+    ToggleLoggingAction(QObject *pParent)
+        : UIToggleAction(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(tr("&Logging...", "debug action"));
+    }
+};
+#endif
+
+UIActionsPool::UIActionsPool(QObject *pParent)
+    : QObject(pParent)
+{
+    /* Resize & clean actions vector */
+    m_actionsPool.resize(UIActionIndex_Max);
+    for (int i = 0; i < m_actionsPool.size(); ++ i)
+        m_actionsPool[i] = 0;
+
+    /* Common actions: */
+    m_actionsPool[UIActionIndex_Separator] = new SeparatorAction(this);
+
+    /* "Machine" menu actions: */
+    m_actionsPool[UIActionIndex_Menu_Machine] = new MenuMachineAction(this);
+    m_actionsPool[UIActionIndex_Toggle_Fullscreen] = new ToggleFullscreenModeAction(this);
+    m_actionsPool[UIActionIndex_Toggle_Seamless] = new ToggleSeamlessModeAction(this);
+    m_actionsPool[UIActionIndex_Toggle_GuestAutoresize] = new ToggleGuestAutoresizeAction(this);
+    m_actionsPool[UIActionIndex_Simple_AdjustWindow] = new PerformWindowAdjustAction(this);
+    m_actionsPool[UIActionIndex_Menu_MouseIntegration] = new MenuMouseIntegrationAction(this);
+    m_actionsPool[UIActionIndex_Toggle_MouseIntegration] = new ToggleMouseIntegrationAction(this);
+    m_actionsPool[UIActionIndex_Simple_TypeCAD] = new PerformTypeCADAction(this);
+#ifdef Q_WS_X11
+    m_actionsPool[UIActionIndex_Simple_TypeCABS] = new PerformTypeCABSAction(this);
+#endif
+    m_actionsPool[UIActionIndex_Simple_TakeSnapshot] = new PerformTakeSnapshotAction(this);
+    m_actionsPool[UIActionIndex_Simple_InformationDialog] = new ShowInformationDialogAction(this);
+    m_actionsPool[UIActionIndex_Simple_Reset] = new PerformResetAction(this);
+    m_actionsPool[UIActionIndex_Toggle_Pause] = new TogglePauseAction(this);
+    m_actionsPool[UIActionIndex_Simple_Shutdown] = new PerformShutdownAction(this);
+    m_actionsPool[UIActionIndex_Simple_Close] = new PerformCloseAction(this);
+
+    /* "Devices" menu actions: */
+    m_actionsPool[UIActionIndex_Menu_Devices] = new MenuDevicesAction(this);
+    m_actionsPool[UIActionIndex_Menu_OpticalDevices] = new MenuOpticalDevicesAction(this);
+    m_actionsPool[UIActionIndex_Menu_FloppyDevices] = new MenuFloppyDevicesAction(this);
+    m_actionsPool[UIActionIndex_Menu_NetworkAdapters] = new MenuNetworkAdaptersAction(this);
+    m_actionsPool[UIActionIndex_Simple_NetworkAdaptersDialog] = new ShowNetworkAdaptersDialogAction(this);
+    m_actionsPool[UIActionIndex_Menu_SharedFolders] = new MenuSharedFoldersAction(this);
+    m_actionsPool[UIActionIndex_Simple_SharedFoldersDialog] = new ShowSharedFoldersDialogAction(this);
+    m_actionsPool[UIActionIndex_Menu_USBDevices] = new MenuUSBDevicesAction(this);
+    m_actionsPool[UIActionIndex_Toggle_VRDP] = new ToggleVRDPAction(this);
+    m_actionsPool[UIActionIndex_Simple_InstallGuestTools] = new PerformInstallGuestToolsAction(this);
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    /* "Debugger" menu actions: */
+    m_actionsPool[UIActionIndex_Menu_Debug] = new MenuDebugAction(this);
+    m_actionsPool[UIActionIndex_Simple_Statistics] = new ShowStatisticsAction(this);
+    m_actionsPool[UIActionIndex_Simple_CommandLine] = new ShowCommandLineAction(this);
+    m_actionsPool[UIActionIndex_Toggle_Logging] = new ToggleLoggingAction(this);
+#endif
+
+    /* Test all actions were initialized */
+    for (int i = 0; i < m_actionsPool.size(); ++ i)
+    {
+        if (!m_actionsPool[i])
+        {
+            AssertMsgFailed(("Action #%d is not created!\n", i));
+        }
+    }
+}
+
+UIActionsPool::~UIActionsPool()
+{
+    for (int i = 0; i < m_actionsPool.size(); ++ i)
+        delete m_actionsPool[i];
+    m_actionsPool.clear();
+}
+
+UIAction* UIActionsPool::action(UIActionIndex index) const
+{
+    return m_actionsPool[index];
+}
+
+#include "UIActionsPool.moc"
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h	(revision 26637)
@@ -0,0 +1,118 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIActionsPool class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIActionsPool_h__
+#define __UIActionsPool_h__
+
+/* Global includes */
+#include <QAction>
+
+/* Local includes */
+#include "QIWithRetranslateUI.h"
+
+enum UIActionType
+{
+    UIActionType_Separator,
+    UIActionType_Simple,
+    UIActionType_Toggle,
+    UIActionType_Menu
+};
+
+class UIAction : public QIWithRetranslateUI3<QAction>
+{
+    Q_OBJECT;
+
+public:
+
+    UIAction(QObject *pParent, UIActionType type);
+
+    UIActionType type() const;
+
+private:
+
+    UIActionType m_type;
+};
+
+enum UIActionIndex
+{
+    /* Common actions */
+    UIActionIndex_Separator,
+
+    /* "Machine" menu actions: */
+    UIActionIndex_Menu_Machine,
+    UIActionIndex_Toggle_Fullscreen,
+    UIActionIndex_Toggle_Seamless,
+    UIActionIndex_Toggle_GuestAutoresize,
+    UIActionIndex_Simple_AdjustWindow,
+    UIActionIndex_Menu_MouseIntegration,
+    UIActionIndex_Toggle_MouseIntegration,
+    UIActionIndex_Simple_TypeCAD,
+#ifdef Q_WS_X11
+    UIActionIndex_Simple_TypeCABS,
+#endif
+    UIActionIndex_Simple_TakeSnapshot,
+    UIActionIndex_Simple_InformationDialog,
+    UIActionIndex_Simple_Reset,
+    UIActionIndex_Toggle_Pause,
+    UIActionIndex_Simple_Shutdown,
+    UIActionIndex_Simple_Close,
+
+    /* "Devices" menu actions: */
+    UIActionIndex_Menu_Devices,
+    UIActionIndex_Menu_OpticalDevices,
+    UIActionIndex_Menu_FloppyDevices,
+    UIActionIndex_Menu_NetworkAdapters,
+    UIActionIndex_Simple_NetworkAdaptersDialog,
+    UIActionIndex_Menu_SharedFolders,
+    UIActionIndex_Simple_SharedFoldersDialog,
+    UIActionIndex_Menu_USBDevices,
+    UIActionIndex_Toggle_VRDP,
+    UIActionIndex_Simple_InstallGuestTools,
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    /* "Debugger" menu actions: */
+    UIActionIndex_Menu_Debug,
+    UIActionIndex_Simple_Statistics,
+    UIActionIndex_Simple_CommandLine,
+    UIActionIndex_Toggle_Logging,
+#endif
+
+    UIActionIndex_Max
+};
+
+class UIActionsPool : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionsPool(QObject *pParent);
+    virtual ~UIActionsPool();
+
+    UIAction* action(UIActionIndex index) const;
+
+private:
+
+    QVector<UIAction*> m_actionsPool;
+};
+
+#endif // __UIActionsPool_h__
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 26637)
@@ -0,0 +1,682 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIFrameBuffer class and subclasses implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifdef VBOX_WITH_PRECOMPILED_HEADERS
+# include "precomp.h"
+#else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
+/* Global includes */
+#include <QPainter>
+/* Local includes */
+#include "UIMachineView.h"
+#include "UIFrameBuffer.h"
+#include "VBoxProblemReporter.h"
+#include "VBoxGlobal.h"
+#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
+
+#if defined (Q_OS_WIN32)
+static CComModule _Module;
+#else
+NS_DECL_CLASSINFO (UIFrameBuffer)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI (UIFrameBuffer, IFramebuffer)
+#endif
+
+UIFrameBuffer::UIFrameBuffer(UIMachineView *pMachineView)
+    : m_pMachineView(pMachineView)
+    , m_width(0), m_height(0)
+#if defined (Q_OS_WIN32)
+    , m_iRefCnt(0)
+#endif
+{
+    AssertMsg(m_pMachineView, ("UIMachineView must not be null\n"));
+    m_uWinId = (m_pMachineView && m_pMachineView->viewport()) ? (ULONG64)m_pMachineView->viewport()->winId() : 0;
+    int rc = RTCritSectInit(&m_critSect);
+    AssertRC(rc);
+}
+
+UIFrameBuffer::~UIFrameBuffer()
+{
+    RTCritSectDelete(&m_critSect);
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(Address) (BYTE **ppAddress)
+{
+    if (!ppAddress)
+        return E_POINTER;
+    *ppAddress = address();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(Width) (ULONG *puWidth)
+{
+    if (!puWidth)
+        return E_POINTER;
+    *puWidth = (ULONG)width();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(Height) (ULONG *puHeight)
+{
+    if (!puHeight)
+        return E_POINTER;
+    *puHeight = (ULONG)height();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(BitsPerPixel) (ULONG *puBitsPerPixel)
+{
+    if (!puBitsPerPixel)
+        return E_POINTER;
+    *puBitsPerPixel = bitsPerPixel();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(BytesPerLine) (ULONG *puBytesPerLine)
+{
+    if (!puBytesPerLine)
+        return E_POINTER;
+    *puBytesPerLine = bytesPerLine();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(PixelFormat) (ULONG *puPixelFormat)
+{
+    if (!puPixelFormat)
+        return E_POINTER;
+    *puPixelFormat = pixelFormat();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(UsesGuestVRAM) (BOOL *pbUsesGuestVRAM)
+{
+    if (!pbUsesGuestVRAM)
+        return E_POINTER;
+    *pbUsesGuestVRAM = usesGuestVRAM();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(HeightReduction) (ULONG *puHeightReduction)
+{
+    if (!puHeightReduction)
+        return E_POINTER;
+    *puHeightReduction = 0;
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(Overlay) (IFramebufferOverlay **ppOverlay)
+{
+    if (!ppOverlay)
+        return E_POINTER;
+    /* not yet implemented */
+    *ppOverlay = 0;
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::COMGETTER(WinId) (ULONG64 *puWinId)
+{
+    if (!puWinId)
+        return E_POINTER;
+    *puWinId = m_uWinId;
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::Lock()
+{
+    this->lock();
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::Unlock()
+{
+    this->unlock();
+    return S_OK;
+}
+
+/** @note This method is called on EMT from under this object's lock */
+STDMETHODIMP UIFrameBuffer::RequestResize(ULONG uScreenId, ULONG uPixelFormat,
+                                          BYTE *pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine,
+                                          ULONG uWidth, ULONG uHeight,
+                                          BOOL *pbFinished)
+{
+    NOREF(uScreenId);
+    QApplication::postEvent (m_pMachineView,
+                             new UIResizeEvent(uPixelFormat, pVRAM, uBitsPerPixel,
+                                               uBytesPerLine, uWidth, uHeight));
+
+    *pbFinished = FALSE;
+    return S_OK;
+}
+
+/**
+ * Returns whether we like the given video mode.
+ *
+ * @returns COM status code
+ * @param   width     video mode width in pixels
+ * @param   height    video mode height in pixels
+ * @param   bpp       video mode bit depth in bits per pixel
+ * @param   supported pointer to result variable
+ */
+STDMETHODIMP UIFrameBuffer::VideoModeSupported(ULONG uWidth, ULONG uHeight, ULONG uBPP, BOOL *pbSupported)
+{
+    NOREF(uBPP);
+    LogFlowThisFunc(("width=%lu, height=%lu, BPP=%lu\n",
+                    (unsigned long)uWidth, (unsigned long)uHeight, (unsigned long)uBPP));
+    if (!pbSupported)
+        return E_POINTER;
+    *pbSupported = TRUE;
+    QRect screen = m_pMachineView->desktopGeometry();
+    if ((screen.width() != 0) && (uWidth > (ULONG)screen.width()))
+        *pbSupported = FALSE;
+    if ((screen.height() != 0) && (uHeight > (ULONG)screen.height()))
+        *pbSupported = FALSE;
+    LogFlowThisFunc(("screenW=%lu, screenH=%lu -> aSupported=%s\n",
+                    screen.width(), screen.height(), *pbSupported ? "TRUE" : "FALSE"));
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::GetVisibleRegion(BYTE *pRectangles, ULONG uCount, ULONG *puCountCopied)
+{
+    PRTRECT rects = (PRTRECT)pRectangles;
+
+    if (!rects)
+        return E_POINTER;
+
+    NOREF(uCount);
+    NOREF(puCountCopied);
+
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::SetVisibleRegion(BYTE *pRectangles, ULONG uCount)
+{
+    PRTRECT rects = (PRTRECT)pRectangles;
+
+    if (!rects)
+        return E_POINTER;
+
+    QRegion reg;
+    for (ULONG ind = 0; ind < uCount; ++ ind)
+    {
+        QRect rect;
+        rect.setLeft(rects->xLeft);
+        rect.setTop(rects->yTop);
+        /* QRect are inclusive */
+        rect.setRight(rects->xRight - 1);
+        rect.setBottom(rects->yBottom - 1);
+        reg += rect;
+        ++ rects;
+    }
+    QApplication::postEvent(m_pMachineView, new UISetRegionEvent(reg));
+
+    return S_OK;
+}
+
+STDMETHODIMP UIFrameBuffer::ProcessVHWACommand(BYTE *pCommand)
+{
+    Q_UNUSED(pCommand);
+    return E_NOTIMPL;
+}
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+void UIFrameBuffer::doProcessVHWACommand(QEvent *pEvent)
+{
+    Q_UNUSED(pEvent);
+    /* should never be here */
+    AssertBreakpoint();
+}
+#endif
+
+#if defined (VBOX_GUI_USE_QIMAGE)
+/** @class UIFrameBufferQImage
+ *
+ *  The UIFrameBufferQImage class is a class that implements the IFrameBuffer
+ *  interface and uses QImage as the direct storage for VM display data. QImage
+ *  is then converted to QPixmap and blitted to the console view widget.
+ */
+UIFrameBufferQImage::UIFrameBufferQImage(UIMachineView *pMachineView)
+    : UIFrameBuffer(pMachineView)
+{
+    /* Initialize the framebuffer the first time */
+    resizeEvent(new UIResizeEvent(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480));
+}
+
+/** @note This method is called on EMT from under this object's lock */
+STDMETHODIMP UIFrameBufferQImage::NotifyUpdate(ULONG uX, ULONG uY, ULONG uW, ULONG uH)
+{
+    /* We're not on the GUI thread and update() isn't thread safe in
+     * Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is),
+     * on Linux (didn't check Qt 4.x there) and probably on other
+     * non-DOS platforms, so post the event instead. */
+    QApplication::postEvent(m_pMachineView, new UIRepaintEvent(uX, uY, uW, uH));
+
+    return S_OK;
+}
+
+void UIFrameBufferQImage::paintEvent(QPaintEvent *pEvent)
+{
+    const QRect &r = pEvent->rect().intersected(m_pMachineView->viewport()->rect());
+
+    /* Some outdated rectangle during processing UIResizeEvent */
+    if (r.isEmpty())
+        return;
+
+#if 0
+    LogFlowFunc (("%dx%d-%dx%d (img=%dx%d)\n", r.x(), r.y(), r.width(), r.height(), img.width(), img.height()));
+#endif
+
+    QPainter painter(m_pMachineView->viewport());
+
+    if (r.width() < m_width * 2 / 3)
+    {
+        /* This method is faster for narrow updates */
+        m_PM = QPixmap::fromImage(m_img.copy(r.x() + m_pMachineView->contentsX(),
+                                             r.y() + m_pMachineView->contentsY(),
+                                             r.width(), r.height()));
+        painter.drawPixmap(r.x(), r.y(), m_PM);
+    }
+    else
+    {
+        /* This method is faster for wide updates */
+        m_PM = QPixmap::fromImage(QImage(m_img.scanLine (r.y() + m_pMachineView->contentsY()),
+                                  m_img.width(), r.height(), m_img.bytesPerLine(),
+                                  QImage::Format_RGB32));
+        painter.drawPixmap(r.x(), r.y(), m_PM, r.x() + m_pMachineView->contentsX(), 0, 0, 0);
+    }
+}
+
+void UIFrameBufferQImage::resizeEvent(UIResizeEvent *pEvent)
+{
+#if 0
+    LogFlowFunc (("fmt=%d, vram=%p, bpp=%d, bpl=%d, width=%d, height=%d\n",
+                  pEvent->pixelFormat(), pEvent->VRAM(),
+                  pEvent->bitsPerPixel(), pEvent->bytesPerLine(),
+                  pEvent->width(), pEvent->height()));
+#endif
+
+    m_width = pEvent->width();
+    m_height = pEvent->height();
+
+    bool bRemind = false;
+    bool bFallback = false;
+    ulong bitsPerLine = pEvent->bytesPerLine() * 8;
+
+    /* check if we support the pixel format and can use the guest VRAM directly */
+    if (pEvent->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
+    {
+        QImage::Format format;
+        switch (pEvent->bitsPerPixel())
+        {
+            /* 32-, 8- and 1-bpp are the only depths supported by QImage */
+            case 32:
+                format = QImage::Format_RGB32;
+                break;
+            case 8:
+                format = QImage::Format_Indexed8;
+                bRemind = true;
+                break;
+            case 1:
+                format = QImage::Format_Mono;
+                bRemind = true;
+                break;
+            default:
+                format = QImage::Format_Invalid; /* set it to something so gcc keeps quiet. */
+                bRemind = true;
+                bFallback = true;
+                break;
+        }
+
+        if (!bFallback)
+        {
+            /* QImage only supports 32-bit aligned scan lines... */
+            Assert ((pEvent->bytesPerLine() & 3) == 0);
+            bFallback = ((pEvent->bytesPerLine() & 3) != 0);
+        }
+        if (!bFallback)
+        {
+            /* ...and the scan lines ought to be a whole number of pixels. */
+            Assert ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) == 0);
+            bFallback = ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) != 0);
+        }
+        if (!bFallback)
+        {
+            ulong virtWdt = bitsPerLine / pEvent->bitsPerPixel();
+            m_img = QImage ((uchar *) pEvent->VRAM(), virtWdt, m_height, format);
+            m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
+            m_bUsesGuestVRAM = true;
+        }
+    }
+    else
+    {
+        bFallback = true;
+    }
+
+    if (bFallback)
+    {
+        /* we don't support either the pixel format or the color depth,
+         * bFallback to a self-provided 32bpp RGB buffer */
+        m_img = QImage (m_width, m_height, QImage::Format_RGB32);
+        m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
+        m_bUsesGuestVRAM = false;
+    }
+
+    if (bRemind)
+    {
+        class RemindEvent : public VBoxAsyncEvent
+        {
+            ulong mRealBPP;
+        public:
+            RemindEvent (ulong aRealBPP)
+                : mRealBPP (aRealBPP) {}
+            void handle()
+            {
+                vboxProblem().remindAboutWrongColorDepth (mRealBPP, 32);
+            }
+        };
+        (new RemindEvent (pEvent->bitsPerPixel()))->post();
+    }
+}
+#endif
+
+#if 0
+#if defined (VBOX_GUI_USE_QGL)
+UIFrameBufferQGL::UIFrameBufferQGL(UIMachineView *pMachineView)
+    : UIFrameBuffer(pMachineView)
+    , m_cmdPipe(pMachineView)
+{
+#ifndef VBOXQGL_PROF_BASE
+    resizeEvent(new UIResizeEvent(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480));
+#else
+    resizeEvent(new UIResizeEvent(FramebufferPixelFormat_Opaque, NULL, 0, 0, VBOXQGL_PROF_WIDTH, VBOXQGL_PROF_HEIGHT));
+#endif
+}
+
+/** @note This method is called on EMT from under this object's lock */
+STDMETHODIMP UIFrameBufferQGL::NotifyUpdate (ULONG uX, ULONG uY, ULONG uW, ULONG uH)
+{
+#ifdef VBOXQGL_PROF_BASE
+    QApplication::postEvent(m_pMachineView, new UIRepaintEvent(uX, uY, uW, uH));
+#else
+    QRect r(uX, uY, uW, uH);
+    m_cmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r, 0);
+#endif
+    return S_OK;
+}
+
+#ifdef VBOXQGL_PROF_BASE
+STDMETHODIMP UIFrameBufferQGL::RequestResize(ULONG uScreenId, ULONG uPixelFormat,
+                                             BYTE *pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine,
+                                             ULONG uWidth, ULONG uHeight,
+                                             BOOL *pbFinished)
+{
+    uWidth = VBOXQGL_PROF_WIDTH;
+    uHeight = VBOXQGL_PROF_HEIGHT;
+    UIFrameBuffer::RequestResize(uScreenId, uPixelFormat, aVRAM, uBitsPerPixel, uBytesPerLine, uWidth, uHeight, pbFinished);
+
+    for(;;)
+    {
+        ULONG uX = 0;
+        ULONG uY = 0;
+        ULONG uW = aWidth;
+        ULONG uH = aHeight;
+        NotifyUpdate(uX, uY, uW, uH);
+        RTThreadSleep(40);
+    }
+    return S_OK;
+}
+#endif
+
+VBoxGLWidget* UIFrameBufferQGL::vboxWidget()
+{
+    return (VBoxGLWidget*)m_pMachineView->viewport();
+}
+
+void UIFrameBufferQGL::paintEvent(QPaintEvent *pEvent)
+{
+    Q_UNUSED(pEvent);
+    VBoxGLWidget *pWidget = vboxWidget();
+    pWidget->makeCurrent();
+
+    QRect vp(m_pMachineView->contentsX(), m_pMachineView->contentsY(), pWidget->width(), pWidget->height());
+    if (vp != pWidget->vboxViewport())
+    {
+        pWidget->vboxDoUpdateViewport(vp);
+    }
+
+    pWidget->performDisplayAndSwap(true);
+}
+
+void UIFrameBufferQGL::resizeEvent(UIResizeEvent *pEvent)
+{
+    m_width = pEvent->width();
+    m_height = pEvent->height();
+
+    vboxWidget()->vboxResizeEvent(pEvent);
+}
+
+/* processing the VHWA command, called from the GUI thread */
+void UIFrameBufferQGL::doProcessVHWACommand(QEvent *pEvent)
+{
+    Q_UNUSED(pEvent);
+    vboxWidget()->vboxProcessVHWACommands(&m_cmdPipe);
+}
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+STDMETHODIMP UIFrameBufferQGL::ProcessVHWACommand(BYTE *pCommand)
+{
+    VBOXVHWACMD *pCmd = (VBOXVHWACMD*)pCommand;
+    /* indicate that we process and complete the command asynchronously */
+    pCmd->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH;
+    /* post the command to the GUI thread for processing */
+    m_cmdPipe.postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd, 0);
+    return S_OK;
+}
+#endif
+#endif
+
+#if defined (VBOX_GUI_USE_SDL)
+#include "VBoxX11Helper.h"
+
+/** @class UIFrameBufferSDL
+ *
+ *  The UIFrameBufferSDL class is a class that implements the IFrameBuffer
+ *  interface and uses SDL to store and render VM display data.
+ */
+UIFrameBufferSDL::UIFrameBufferSDL(UIMachineView *pMachineView)
+    : UIFrameBuffer(pMachineView)
+{
+    m_pScreen = NULL;
+    m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
+    m_pSurfVRAM = NULL;
+
+    X11ScreenSaverSettingsInit();
+    resizeEvent(new UIResizeEvent(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480));
+}
+
+UIFrameBufferSDL::~UIFrameBufferSDL()
+{
+    if (m_pSurfVRAM)
+    {
+        SDL_FreeSurface(m_pSurfVRAM);
+        m_pSurfVRAM = NULL;
+    }
+    X11ScreenSaverSettingsSave();
+    SDL_QuitSubSystem(SDL_INIT_VIDEO);
+    X11ScreenSaverSettingsRestore();
+}
+
+/** @note This method is called on EMT from under this object's lock */
+STDMETHODIMP UIFrameBufferSDL::NotifyUpdate(ULONG uX, ULONG uY, ULONG uW, ULONG uH)
+{
+#if !defined (Q_WS_WIN) && !defined (Q_WS_PM)
+    /* we're not on the GUI thread and update() isn't thread safe in Qt 3.3.x
+       on the Mac (4.2.x is), on Linux (didn't check Qt 4.x there) and
+       probably on other non-DOS platforms, so post the event instead. */
+    QApplication::postEvent (m_pMachineView, new UIRepaintEvent(uX, uY, uW, UH));
+#else
+    /* we're not on the GUI thread, so update() instead of repaint()! */
+    m_pMachineView->viewport()->update(uX - m_pMachineView->contentsX(), uY - m_pMachineView->contentsY(), uW, uH);
+#endif
+    return S_OK;
+}
+
+void UIFrameBufferSDL::paintEvent(QPaintEvent *pEvent)
+{
+    if (m_pScreen)
+    {
+        if (m_pScreen->pixels)
+        {
+            QRect r = pEvent->rect();
+
+            if (m_pSurfVRAM)
+            {
+                SDL_Rect rect = { (Sint16)r.x(), (Sint16)r.y(), (Sint16)r.width(), (Sint16)r.height() };
+                SDL_BlitSurface(m_pSurfVRAM, &rect, m_pScreen, &rect);
+                /** @todo may be: if ((m_pScreen->flags & SDL_HWSURFACE) == 0) */
+                SDL_UpdateRect(m_pScreen, r.x(), r.y(), r.width(), r.height());
+            }
+            else
+            {
+                SDL_UpdateRect(m_pScreen, r.x(), r.y(), r.width(), r.height());
+            }
+        }
+    }
+}
+
+void UIFrameBufferSDL::resizeEvent(UIResizeEvent *pEvent)
+{
+    /* Check whether the guest resolution has not been changed. */
+    bool fSameResolutionRequested = (width()  == pEvent->width() && height() == pEvent->height());
+
+    /* Check if the guest VRAM can be used as the source bitmap. */
+    bool bFallback = false;
+
+    Uint32 Rmask = 0;
+    Uint32 Gmask = 0;
+    Uint32 Bmask = 0;
+
+    if (pEvent->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
+    {
+        switch (pEvent->bitsPerPixel())
+        {
+            case 32:
+                Rmask = 0x00FF0000;
+                Gmask = 0x0000FF00;
+                Bmask = 0x000000FF;
+                break;
+            case 24:
+                Rmask = 0x00FF0000;
+                Gmask = 0x0000FF00;
+                Bmask = 0x000000FF;
+                break;
+            case 16:
+                Rmask = 0xF800;
+                Gmask = 0x07E0;
+                Bmask = 0x001F;
+                break;
+            default:
+                /* Unsupported format leads to the indirect buffer */
+                bFallback = true;
+                break;
+        }
+    }
+    else
+    {
+        /* Unsupported format leads to the indirect buffer */
+        bFallback = true;
+    }
+
+    m_width = pEvent->width();
+    m_height = pEvent->height();
+
+    /* Recreate the source surface. */
+    if (m_pSurfVRAM)
+    {
+        SDL_FreeSurface(m_pSurfVRAM);
+        m_pSurfVRAM = NULL;
+    }
+
+    if (!bFallback)
+    {
+        /* It is OK to create the source surface from the guest VRAM. */
+        m_pSurfVRAM = SDL_CreateRGBSurfaceFrom(pEvent->VRAM(), pEvent->width(), pEvent->height(),
+                                               pEvent->bitsPerPixel(),
+                                               pEvent->bytesPerLine(),
+                                               Rmask, Gmask, Bmask, 0);
+        LogFlowFunc(("Created VRAM surface %p\n", m_pSurfVRAM));
+        if (m_pSurfVRAM == NULL)
+        {
+            bFallback = true;
+        }
+    }
+
+    if (fSameResolutionRequested)
+    {
+        LogFlowFunc(("the same resolution requested, skipping the resize.\n"));
+        return;
+    }
+
+    /* close SDL so we can init it again */
+    if (m_pScreen)
+    {
+        X11ScreenSaverSettingsSave();
+        SDL_QuitSubSystem(SDL_INIT_VIDEO);
+        X11ScreenSaverSettingsRestore();
+        m_pScreen = NULL;
+    }
+
+    /*
+     *  initialize the SDL library, use its super hack to integrate it with our client window
+     */
+    static char sdlHack[64];
+    LogFlowFunc(("Using client window 0x%08lX to initialize SDL\n", m_pMachineView->viewport()->winId()));
+    /* Note: SDL_WINDOWID must be decimal (not hex) to work on Win32 */
+    sprintf(sdlHack, "SDL_WINDOWID=%lu", m_pMachineView->viewport()->winId());
+    putenv(sdlHack);
+    X11ScreenSaverSettingsSave();
+    int rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
+    X11ScreenSaverSettingsRestore();
+    AssertMsg(rc == 0, ("SDL initialization failed: %s\n", SDL_GetError()));
+    NOREF(rc);
+
+#ifdef Q_WS_X11
+    /* undo signal redirections from SDL, it'd steal keyboard events from us! */
+    signal(SIGINT, SIG_DFL);
+    signal(SIGQUIT, SIG_DFL);
+#endif
+
+    LogFlowFunc(("Setting SDL video mode to %d x %d\n", m_width, m_height));
+
+    /* Pixel format is RGB in any case */
+    m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
+
+    m_pScreen = SDL_SetVideoMode(m_width, m_height, 0, SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL);
+    AssertMsg(m_pScreen, ("SDL video mode could not be set!\n"));
+}
+#endif
+
+#if defined (VBOX_GUI_USE_DDRAW)
+/* The class is defined in VBoxFBDDRAW.cpp */
+#endif
+
+#if defined (VBOX_GUI_USE_QUARTZ2D)
+/* The class is defined in VBoxQuartz2D.cpp */
+#endif
+#endif
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h	(revision 26637)
@@ -0,0 +1,500 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIFrameBuffer class and subclasses declarations
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef ___UIFrameBuffer_h___
+#define ___UIFrameBuffer_h___
+
+/* Global includes */
+//#include <QImage>
+#include <QPixmap>
+//#include <QMutex>
+#include <QPaintEvent>
+//#include <QMoveEvent>
+//#if defined (VBOX_GUI_USE_QGL)
+//#include "VBoxFBOverlay.h"
+//#endif
+
+/* Local includes */
+#include "COMDefs.h"
+#include <iprt/critsect.h>
+
+//#if defined (VBOX_GUI_USE_SDL)
+//#include <SDL.h>
+//#include <signal.h>
+//#endif
+
+//#if defined (Q_WS_WIN) && defined (VBOX_GUI_USE_DDRAW)
+// VBox/cdefs.h defines these:
+//#undef LOWORD
+//#undef HIWORD
+//#undef LOBYTE
+//#undef HIBYTE
+//#include <ddraw.h>
+//#endif
+
+class UIMachineView;
+
+/**
+ *  Frame buffer resize event.
+ */
+class UIResizeEvent : public QEvent
+{
+public:
+
+    UIResizeEvent(ulong uPixelFormat, uchar *pVRAM,
+                  ulong uBitsPerPixel, ulong uBytesPerLine,
+                  ulong uWidth, ulong uHeight)
+        : QEvent((QEvent::Type)VBoxDefs::ResizeEventType)
+        , m_uPixelFormat(uPixelFormat), m_pVRAM(pVRAM), m_uBitsPerPixel(uBitsPerPixel)
+        , m_uBytesPerLine(uBytesPerLine), m_uWidth(uWidth), m_uHeight(uHeight) {}
+    ulong pixelFormat() { return m_uPixelFormat; }
+    uchar *VRAM() { return m_pVRAM; }
+    ulong bitsPerPixel() { return m_uBitsPerPixel; }
+    ulong bytesPerLine() { return m_uBytesPerLine; }
+    ulong width() { return m_uWidth; }
+    ulong height() { return m_uHeight; }
+
+private:
+
+    ulong m_uPixelFormat;
+    uchar *m_pVRAM;
+    ulong m_uBitsPerPixel;
+    ulong m_uBytesPerLine;
+    ulong m_uWidth;
+    ulong m_uHeight;
+};
+
+/**
+ *  Frame buffer repaint event.
+ */
+class UIRepaintEvent : public QEvent
+{
+public:
+
+    UIRepaintEvent(int iX, int iY, int iW, int iH)
+        : QEvent((QEvent::Type)VBoxDefs::RepaintEventType)
+        , m_iX(iX), m_iY(iY), m_iW(iW), m_iH(iH) {}
+    int x() { return m_iX; }
+    int y() { return m_iY; }
+    int width() { return m_iW; }
+    int height() { return m_iH; }
+
+private:
+
+    int m_iX, m_iY, m_iW, m_iH;
+};
+
+/**
+ *  Frame buffer set region event.
+ */
+class UISetRegionEvent : public QEvent
+{
+public:
+
+    UISetRegionEvent(const QRegion &region)
+        : QEvent((QEvent::Type)VBoxDefs::SetRegionEventType)
+        , m_region(region) {}
+    QRegion region() { return m_region; }
+
+private:
+
+    QRegion m_region;
+};
+
+/**
+ *  Common IFramebuffer implementation for all methods used by GUI to maintain
+ *  the VM display video memory.
+ *
+ *  Note that although this class can be called from multiple threads
+ *  (in particular, the GUI thread and EMT) it doesn't protect access to every
+ *  data field using its mutex lock. This is because all synchronization between
+ *  the GUI and the EMT thread is supposed to be done using the
+ *  IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
+ *  (in particular, the \a aFinished parameter of these methods is responsible
+ *  for the synchronization). These methods are always called on EMT and
+ *  therefore always follow one another but never in parallel.
+ *
+ *  Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
+ *  IFramebuffer::Unlock() implementations) usually makes sense only if some
+ *  third-party thread (i.e. other than GUI or EMT) needs to make sure that
+ *  *no* VM display update or resize event can occur while it is accessing
+ *  IFramebuffer properties or the underlying display memory storage area.
+ *
+ *  See IFramebuffer documentation for more info.
+ */
+class UIFrameBuffer : VBOX_SCRIPTABLE_IMPL(IFramebuffer)
+{
+public:
+
+    UIFrameBuffer(UIMachineView *aView);
+    virtual ~UIFrameBuffer();
+
+    NS_DECL_ISUPPORTS
+
+#if defined (Q_OS_WIN32)
+    STDMETHOD_(ULONG, AddRef)()
+    {
+        return ::InterlockedIncrement(&m_iRefCnt);
+    }
+
+    STDMETHOD_(ULONG, Release)()
+    {
+        long cnt = ::InterlockedDecrement(&m_iRefCnt);
+        if (cnt == 0)
+            delete this;
+        return cnt;
+    }
+#endif
+
+    VBOX_SCRIPTABLE_DISPATCH_IMPL(IFramebuffer)
+
+    /* IFramebuffer COM methods */
+    STDMETHOD(COMGETTER(Address)) (BYTE **ppAddress);
+    STDMETHOD(COMGETTER(Width)) (ULONG *puWidth);
+    STDMETHOD(COMGETTER(Height)) (ULONG *puHeight);
+    STDMETHOD(COMGETTER(BitsPerPixel)) (ULONG *puBitsPerPixel);
+    STDMETHOD(COMGETTER(BytesPerLine)) (ULONG *puBytesPerLine);
+    STDMETHOD(COMGETTER(PixelFormat)) (ULONG *puPixelFormat);
+    STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *pbUsesGuestVRAM);
+    STDMETHOD(COMGETTER(HeightReduction)) (ULONG *puHeightReduction);
+    STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **ppOverlay);
+    STDMETHOD(COMGETTER(WinId)) (ULONG64 *pWinId);
+
+    STDMETHOD(Lock)();
+    STDMETHOD(Unlock)();
+
+    STDMETHOD(RequestResize) (ULONG uScreenId, ULONG uPixelFormat,
+                              BYTE *pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine,
+                              ULONG uWidth, ULONG uHeight,
+                              BOOL *pbFinished);
+
+    STDMETHOD(VideoModeSupported) (ULONG uWidth, ULONG uHeight, ULONG uBPP,
+                                   BOOL *pbSupported);
+
+    STDMETHOD(GetVisibleRegion)(BYTE *pRectangles, ULONG uCount, ULONG *puCountCopied);
+    STDMETHOD(SetVisibleRegion)(BYTE *pRectangles, ULONG uCount);
+
+    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
+
+    ulong width() { return m_width; }
+    ulong height() { return m_height; }
+
+    virtual ulong pixelFormat()
+    {
+        return FramebufferPixelFormat_FOURCC_RGB;
+    }
+
+    virtual bool usesGuestVRAM()
+    {
+        return false;
+    }
+
+    void lock() { RTCritSectEnter(&m_critSect); }
+    void unlock() { RTCritSectLeave(&m_critSect); }
+
+    virtual uchar *address() = 0;
+    virtual ulong bitsPerPixel() = 0;
+    virtual ulong bytesPerLine() = 0;
+
+    /**
+     *  Called on the GUI thread (from VBoxConsoleView) when some part of the
+     *  VM display viewport needs to be repainted on the host screen.
+     */
+    virtual void paintEvent(QPaintEvent *pEvent) = 0;
+
+    /**
+     *  Called on the GUI thread (from VBoxConsoleView) after it gets a
+     *  UIResizeEvent posted from the RequestResize() method implementation.
+     */
+    virtual void resizeEvent(UIResizeEvent *pEvent)
+    {
+        m_width = pEvent->width();
+        m_height = pEvent->height();
+    }
+
+    /**
+     *  Called on the GUI thread (from VBoxConsoleView) when the VM console
+     *  window is moved.
+     */
+    virtual void moveEvent(QMoveEvent * /* pEvent */) {}
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    /* this method is called from the GUI thread
+     * to perform the actual Video HW Acceleration command processing
+     * the event is framebuffer implementation specific */
+    virtual void doProcessVHWACommand(QEvent * pEvent);
+
+    virtual void viewportResized(QResizeEvent * /* pEvent */) {}
+
+    virtual void viewportScrolled(int /* iX */, int /* iY */) {}
+#endif
+
+protected:
+
+    UIMachineView *m_pMachineView;
+    RTCRITSECT m_critSect;
+    int m_width;
+    int m_height;
+    uint64_t m_uWinId;
+
+#if defined (Q_OS_WIN32)
+private:
+
+    long m_iRefCnt;
+#endif
+};
+
+#if defined (VBOX_GUI_USE_QIMAGE)
+class UIFrameBufferQImage : public UIFrameBuffer
+{
+public:
+
+    UIFrameBufferQImage(UIMachineView *pMachineView);
+
+    STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH);
+
+    ulong pixelFormat() { return m_uPixelFormat; }
+    bool usesGuestVRAM() { return m_bUsesGuestVRAM; }
+
+    uchar *address() { return m_img.bits(); }
+    ulong bitsPerPixel() { return m_img.depth(); }
+    ulong bytesPerLine() { return m_img.bytesPerLine(); }
+
+    void paintEvent (QPaintEvent *pEvent);
+    void resizeEvent (UIResizeEvent *pEvent);
+
+private:
+
+    QPixmap m_PM;
+    QImage m_img;
+    ulong m_uPixelFormat;
+    bool m_bUsesGuestVRAM;
+};
+#endif
+
+#if 0
+#if defined (VBOX_GUI_USE_QGL)
+class UIFrameBufferQGL : public UIFrameBuffer
+{
+public:
+
+    UIFrameBufferQGL(UIMachineView *pMachineView);
+
+    STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH);
+#ifdef VBOXQGL_PROF_BASE
+    STDMETHOD(RequestResize) (ULONG uScreenId, ULONG uPixelFormat,
+                              BYTE *pVRAM, ULONG uBitsPerPixel, ULONG uBytesPerLine,
+                              ULONG uWidth, ULONG uHeight, BOOL *pbFinished);
+#endif
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    STDMETHOD(ProcessVHWACommand)(BYTE *pbCommand);
+#endif
+
+    ulong pixelFormat() { return vboxWidget()->vboxPixelFormat(); }
+    bool usesGuestVRAM() { return vboxWidget()->vboxUsesGuestVRAM(); }
+
+    uchar *address() { return vboxWidget()->vboxAddress(); }
+    ulong bitsPerPixel() { return vboxWidget()->vboxBitsPerPixel(); }
+    ulong bytesPerLine() { return vboxWidget()->vboxBytesPerLine(); }
+
+    void paintEvent (QPaintEvent *pEvent);
+    void resizeEvent (UIResizeEvent *pEvent);
+    void doProcessVHWACommand(QEvent *pEvent);
+
+private:
+
+    class VBoxGLWidget* vboxWidget();
+
+    class VBoxVHWACommandElementProcessor m_cmdPipe;
+};
+#endif
+
+#if defined (VBOX_GUI_USE_SDL)
+class UIFrameBufferSDL : public UIFrameBuffer
+{
+public:
+
+    UIFrameBufferSDL (VBoxConsoleView *pMachineView);
+    virtual ~UIFrameBufferSDL();
+
+    STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY, ULONG aW, ULONG aH);
+
+    uchar* address()
+    {
+        SDL_Surface *surf = m_pSurfVRAM ? m_pSurfVRAM : m_pScreen;
+        return surf ? (uchar*) (uintptr_t) surf->pixels : 0;
+    }
+
+    ulong bitsPerPixel()
+    {
+        SDL_Surface *surf = m_pSurfVRAM ? m_pSurfVRAM : m_pScreen;
+        return surf ? surf->format->BitsPerPixel : 0;
+    }
+
+    ulong bytesPerLine()
+    {
+        SDL_Surface *surf = m_pSurfVRAM ? m_pSurfVRAM : m_pScreen;
+        return surf ? surf->pitch : 0;
+    }
+
+    ulong pixelFormat()
+    {
+        return m_uPixelFormat;
+    }
+
+    bool usesGuestVRAM()
+    {
+        return m_pSurfVRAM != NULL;
+    }
+
+    void paintEvent(QPaintEvent *pEvent);
+    void resizeEvent(UIResizeEvent *pEvent);
+
+private:
+
+    SDL_Surface *m_pScreen;
+    SDL_Surface *m_pSurfVRAM;
+
+    ulong m_uPixelFormat;
+};
+#endif
+
+#if defined (VBOX_GUI_USE_DDRAW)
+class UIFrameBufferDDRAW : public UIFrameBuffer
+{
+public:
+
+    UIFrameBufferDDRAW(UIMachineView *pMachineView);
+    virtual ~UIFrameBufferDDRAW();
+
+    STDMETHOD(NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH);
+
+    uchar* address() { return (uchar*) m_surfaceDesc.lpSurface; }
+    ulong bitsPerPixel() { return m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
+    ulong bytesPerLine() { return (ulong) m_surfaceDesc.lPitch; }
+
+    ulong pixelFormat() { return m_uPixelFormat; };
+
+    bool usesGuestVRAM() { return m_bUsesGuestVRAM; }
+
+    void paintEvent(QPaintEvent *pEvent);
+    void resizeEvent(UIResizeEvent *pEvent);
+    void moveEvent(QMoveEvent *pEvent);
+
+private:
+
+    void releaseObjects();
+
+    bool createSurface(ULONG uPixelFormat, uchar *pvVRAM,
+                       ULONG uBitsPerPixel, ULONG uBytesPerLine,
+                       ULONG uWidth, ULONG uHeight);
+    void deleteSurface();
+    void drawRect(ULONG uX, ULONG uY, ULONG uW, ULONG uH);
+    void getWindowPosition(void);
+
+    LPDIRECTDRAW7        m_DDRAW;
+    LPDIRECTDRAWCLIPPER  m_clipper;
+    LPDIRECTDRAWSURFACE7 m_surface;
+    DDSURFACEDESC2       m_surfaceDesc;
+    LPDIRECTDRAWSURFACE7 m_primarySurface;
+
+    ulong m_uPixelFormat;
+
+    bool m_bUsesGuestVRAM;
+
+    int m_iWndX;
+    int m_iWndY;
+
+    bool m_bSynchronousUpdates;
+};
+#endif
+
+#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
+#include <Carbon/Carbon.h>
+
+class UIFrameBufferQuartz2D : public UIFrameBuffer
+{
+public:
+
+    UIFrameBufferQuartz2D(UIMachineView *pMachineView);
+    virtual ~UIFrameBufferQuartz2D();
+
+    STDMETHOD (NotifyUpdate) (ULONG uX, ULONG uY, ULONG uW, ULONG uH);
+    STDMETHOD (SetVisibleRegion) (BYTE *pRectangles, ULONG uCount);
+
+    uchar* address() { return m_pDataAddress; }
+    ulong bitsPerPixel() { return CGImageGetBitsPerPixel(m_image); }
+    ulong bytesPerLine() { return CGImageGetBytesPerRow(m_image); }
+    ulong pixelFormat() { return m_uPixelFormat; };
+    bool usesGuestVRAM() { return m_pBitmapData == NULL; }
+
+    const CGImageRef imageRef() const { return m_image; }
+
+    void paintEvent(QPaintEvent *pEvent);
+    void resizeEvent(UIResizeEvent *pEvent);
+
+#ifndef QT_MAC_USE_COCOA
+    void testAndSetSNCarbonFix();
+#endif /* QT_MAC_USE_COCOA */
+
+private:
+
+    void clean();
+
+    uchar *m_pDataAddress;
+    void *m_pBitmapData;
+    ulong m_uPixelFormat;
+    CGImageRef m_image;
+    typedef struct
+    {
+        /** The size of this structure expressed in rcts entries. */
+        ULONG allocated;
+        /** The number of entries in the rcts array. */
+        ULONG used;
+        /** Variable sized array of the rectangle that makes up the region. */
+        CGRect rcts[1];
+    } RegionRects;
+    /** The current valid region, all access is by atomic cmpxchg or atomic xchg.
+     *
+     * The protocol for updating and using this has to take into account that
+     * the producer (SetVisibleRegion) and consumer (paintEvent) are running
+     * on different threads. Therefore the producer will create a new RegionRects
+     * structure before atomically replace the existing one. While the consumer
+     * will read the value by atomically replace it by NULL, and then when its
+     * done try restore it by cmpxchg. If the producer has already put a new
+     * region there, it will be discarded (see mRegionUnused).
+     */
+    RegionRects volatile *mRegion;
+    /** For keeping the unused region and thus avoid some RTMemAlloc/RTMemFree calls.
+     * This is operated with atomic cmpxchg and atomic xchg. */
+    RegionRects volatile *mRegionUnused;
+
+#ifndef QT_MAC_USE_COCOA
+    bool mSnowLeoCarbonFix;
+    EventHandlerRef mDarwinSNWindowHandlerRef;
+#endif /* QT_MAC_USE_COCOA */
+};
+#endif /* Q_WS_MAC && VBOX_GUI_USE_QUARTZ2D */
+#endif
+
+#endif // !___UIFrameBuffer_h___
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp	(revision 26637)
@@ -0,0 +1,217 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIActionsPool class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Local includes */
+#include "UIIndicatorsPool.h"
+#include "COMDefs.h"
+
+class UIIndicatorHardDisks : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorHardDisks() : QIStateIndicator(KDeviceActivity_Idle)
+    {
+        setStateIcon(KDeviceActivity_Idle, QPixmap(":/hd_16px.png"));
+        setStateIcon(KDeviceActivity_Reading, QPixmap(":/hd_read_16px.png"));
+        setStateIcon(KDeviceActivity_Writing, QPixmap(":/hd_write_16px.png"));
+        setStateIcon(KDeviceActivity_Null, QPixmap(":/hd_disabled_16px.png"));
+    }
+};
+
+class UIIndicatorOpticalDisks : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorOpticalDisks() : QIStateIndicator(KDeviceActivity_Idle)
+    {
+        setStateIcon(KDeviceActivity_Idle, QPixmap(":/cd_16px.png"));
+        setStateIcon(KDeviceActivity_Reading, QPixmap(":/cd_read_16px.png"));
+        setStateIcon(KDeviceActivity_Writing, QPixmap(":/cd_write_16px.png"));
+        setStateIcon(KDeviceActivity_Null, QPixmap(":/cd_disabled_16px.png"));
+    }
+};
+
+class UIIndicatorFloppyDisks : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorFloppyDisks() : QIStateIndicator(KDeviceActivity_Idle)
+    {
+        setStateIcon(KDeviceActivity_Idle, QPixmap(":/fd_16px.png"));
+        setStateIcon(KDeviceActivity_Reading, QPixmap(":/fd_read_16px.png"));
+        setStateIcon(KDeviceActivity_Writing, QPixmap(":/fd_write_16px.png"));
+        setStateIcon(KDeviceActivity_Null, QPixmap(":/fd_disabled_16px.png"));
+    }
+};
+
+class UIIndicatorNetworkAdapters : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorNetworkAdapters() : QIStateIndicator(KDeviceActivity_Idle)
+    {
+        setStateIcon(KDeviceActivity_Idle, QPixmap(":/nw_16px.png"));
+        setStateIcon(KDeviceActivity_Reading, QPixmap(":/nw_read_16px.png"));
+        setStateIcon(KDeviceActivity_Writing, QPixmap(":/nw_write_16px.png"));
+        setStateIcon(KDeviceActivity_Null, QPixmap(":/nw_disabled_16px.png"));
+    }
+};
+
+class UIIndicatorUSBDevices : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorUSBDevices() : QIStateIndicator(KDeviceActivity_Idle)
+    {
+        setStateIcon(KDeviceActivity_Idle, QPixmap(":/usb_16px.png"));
+        setStateIcon(KDeviceActivity_Reading, QPixmap(":/usb_read_16px.png"));
+        setStateIcon(KDeviceActivity_Writing, QPixmap(":/usb_write_16px.png"));
+        setStateIcon(KDeviceActivity_Null, QPixmap(":/usb_disabled_16px.png"));
+    }
+};
+
+class UIIndicatorSharedFolders : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorSharedFolders() : QIStateIndicator(KDeviceActivity_Idle)
+    {
+        setStateIcon(KDeviceActivity_Idle, QPixmap(":/shared_folder_16px.png"));
+        setStateIcon(KDeviceActivity_Reading, QPixmap(":/shared_folder_read_16px.png"));
+        setStateIcon(KDeviceActivity_Writing, QPixmap(":/shared_folder_write_16px.png"));
+        setStateIcon(KDeviceActivity_Null, QPixmap(":/shared_folder_disabled_16px.png"));
+    }
+};
+
+class UIIndicatorVirtualization : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorVirtualization() : QIStateIndicator(0)
+    {
+        setStateIcon(0, QPixmap(":/vtx_amdv_disabled_16px.png"));
+        setStateIcon(1, QPixmap(":/vtx_amdv_16px.png"));
+    }
+};
+
+class UIIndicatorMouse : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorMouse() : QIStateIndicator(0)
+    {
+        setStateIcon(0, QPixmap(":/mouse_disabled_16px.png"));
+        setStateIcon(1, QPixmap(":/mouse_16px.png"));
+        setStateIcon(2, QPixmap(":/mouse_seamless_16px.png"));
+        setStateIcon(3, QPixmap(":/mouse_can_seamless_16px.png"));
+        setStateIcon(4, QPixmap(":/mouse_can_seamless_uncaptured_16px.png"));
+    }
+};
+
+class UIIndicatorHostkey : public QIStateIndicator
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorHostkey() : QIStateIndicator(0)
+    {
+        setStateIcon(0, QPixmap(":/hostkey_16px.png"));
+        setStateIcon(1, QPixmap(":/hostkey_captured_16px.png"));
+        setStateIcon(2, QPixmap(":/hostkey_pressed_16px.png"));
+        setStateIcon(3, QPixmap(":/hostkey_captured_pressed_16px.png"));
+    }
+};
+
+UIIndicatorsPool::UIIndicatorsPool(QObject *pParent)
+    : QObject(pParent)
+{
+    /* Resize & clean actions vector */
+    m_IndicatorsPool.resize(UIIndicatorIndex_Max);
+    for (int i = 0; i < m_IndicatorsPool.size(); ++ i)
+        m_IndicatorsPool[i] = 0;
+}
+
+UIIndicatorsPool::~UIIndicatorsPool()
+{
+    for (int i = 0; i < m_IndicatorsPool.size(); ++ i)
+    {
+        delete m_IndicatorsPool[i];
+        m_IndicatorsPool[i] = 0;
+    }
+    m_IndicatorsPool.clear();
+}
+
+QIStateIndicator* UIIndicatorsPool::indicator(UIIndicatorIndex index)
+{
+    if (!m_IndicatorsPool[index])
+    {
+        switch (index)
+        {
+            case UIIndicatorIndex_HardDisks:
+                m_IndicatorsPool[index] = new UIIndicatorHardDisks;
+                break;
+            case UIIndicatorIndex_OpticalDisks:
+                m_IndicatorsPool[index] = new UIIndicatorOpticalDisks;
+                break;
+            case UIIndicatorIndex_NetworkAdapters:
+                m_IndicatorsPool[index] = new UIIndicatorNetworkAdapters;
+                break;
+            case UIIndicatorIndex_USBDevices:
+                m_IndicatorsPool[index] = new UIIndicatorUSBDevices;
+                break;
+            case UIIndicatorIndex_SharedFolders:
+                m_IndicatorsPool[index] = new UIIndicatorSharedFolders;
+                break;
+            case UIIndicatorIndex_Virtualization:
+                m_IndicatorsPool[index] = new UIIndicatorVirtualization;
+                break;
+            case UIIndicatorIndex_Mouse:
+                m_IndicatorsPool[index] = new UIIndicatorMouse;
+                break;
+            case UIIndicatorIndex_Hostkey:
+                m_IndicatorsPool[index] = new UIIndicatorHostkey;
+                break;
+            default:
+                break;
+        }
+    }
+    return m_IndicatorsPool[index];
+}
+
+#include "UIIndicatorsPool.moc"
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.h	(revision 26637)
@@ -0,0 +1,58 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIIndicatorsPool class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIIndicatorsPool_h__
+#define __UIIndicatorsPool_h__
+
+/* Local includes */
+#include "QIStateIndicator.h"
+
+enum UIIndicatorIndex
+{
+    UIIndicatorIndex_HardDisks,
+    UIIndicatorIndex_OpticalDisks,
+    UIIndicatorIndex_NetworkAdapters,
+    UIIndicatorIndex_USBDevices,
+    UIIndicatorIndex_SharedFolders,
+    UIIndicatorIndex_Virtualization,
+    UIIndicatorIndex_Mouse,
+    UIIndicatorIndex_Hostkey,
+    UIIndicatorIndex_Max
+};
+
+class UIIndicatorsPool : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorsPool(QObject *pParent);
+   ~UIIndicatorsPool();
+
+    QIStateIndicator* indicator(UIIndicatorIndex index);
+
+private:
+
+    QVector<QIStateIndicator*> m_IndicatorsPool;
+};
+
+#endif // __UIIndicatorsPool_h__
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp	(revision 26637)
@@ -0,0 +1,200 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachine class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Local includes */
+#include "VBoxGlobal.h"
+#include "UIMachine.h"
+#include "UIActionsPool.h"
+#include "UIMachineLogic.h"
+
+class UIVisualState : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    UIVisualState(QObject *pParent) : QObject(pParent), m_pMachineLogic(0)
+    {
+        /* Connect state-change handler */
+        connect(this, SIGNAL(sigChangeVisualState(UIVisualStateType)), parent(), SLOT(sltChangeVisualState(UIVisualStateType)));
+    }
+
+signals:
+
+    void sigChangeVisualState(UIVisualStateType visualStateType);
+
+protected:
+
+    UIMachineLogic *m_pMachineLogic;
+};
+
+class UIVisualStateNormal : public UIVisualState
+{
+    Q_OBJECT;
+
+public:
+
+    UIVisualStateNormal(QObject *pParent, const CSession &session, UIActionsPool *pActionsPool)
+        : UIVisualState(pParent)
+    {
+        /* Connect action handlers */
+        connect(pActionsPool->action(UIActionIndex_Toggle_Fullscreen), SIGNAL(triggered(bool)),
+                this, SLOT(sltGoToFullscreenMode()));
+        connect(pActionsPool->action(UIActionIndex_Toggle_Seamless), SIGNAL(triggered(bool)),
+                this, SLOT(sltGoToSeamlessMode()));
+
+        /* Create state logic */
+        m_pMachineLogic = UIMachineLogic::create(this, session, pActionsPool, UIVisualStateType_Normal);
+    }
+
+private slots:
+
+    void sltGoToFullscreenMode()
+    {
+        emit sigChangeVisualState(UIVisualStateType_Fullscreen);
+    }
+
+    void sltGoToSeamlessMode()
+    {
+        emit sigChangeVisualState(UIVisualStateType_Seamless);
+    }
+};
+
+class UIVisualStateFullscreen : public UIVisualState
+{
+    Q_OBJECT;
+
+public:
+
+    UIVisualStateFullscreen(QObject *pParent, const CSession &session, UIActionsPool *pActionsPool)
+        : UIVisualState(pParent)
+    {
+        /* Connect action handlers */
+        connect(pActionsPool->action(UIActionIndex_Toggle_Fullscreen), SIGNAL(triggered(bool)),
+                this, SLOT(sltGoToNormalMode()));
+        connect(pActionsPool->action(UIActionIndex_Toggle_Seamless), SIGNAL(triggered(bool)),
+                this, SLOT(sltGoToSeamlessMode()));
+
+        /* Create state logic */
+        m_pMachineLogic = UIMachineLogic::create(this, session, pActionsPool, UIVisualStateType_Fullscreen);
+    }
+
+private slots:
+
+    void sltGoToNormalMode()
+    {
+        emit sigChangeVisualState(UIVisualStateType_Normal);
+    }
+
+    void sltGoToSeamlessMode()
+    {
+        emit sigChangeVisualState(UIVisualStateType_Seamless);
+    }
+};
+
+class UIVisualStateSeamless : public UIVisualState
+{
+    Q_OBJECT;
+
+public:
+
+    UIVisualStateSeamless(QObject *pParent, const CSession &session, UIActionsPool *pActionsPool)
+        : UIVisualState(pParent)
+    {
+        /* Connect action handlers */
+        connect(pActionsPool->action(UIActionIndex_Toggle_Fullscreen), SIGNAL(triggered(bool)),
+                this, SLOT(sltGoToFullscreenMode()));
+        connect(pActionsPool->action(UIActionIndex_Toggle_Seamless), SIGNAL(triggered(bool)),
+                this, SLOT(sltGoToNormalMode()));
+
+        /* Create state logic */
+        m_pMachineLogic = UIMachineLogic::create(this, session, pActionsPool, UIVisualStateType_Seamless);
+    }
+
+private slots:
+
+    void sltGoToFullscreenMode()
+    {
+        emit sigChangeVisualState(UIVisualStateType_Fullscreen);
+    }
+
+    void sltGoToNormalMode()
+    {
+        emit sigChangeVisualState(UIVisualStateType_Normal);
+    }
+};
+
+UIMachine::UIMachine(UIMachine **ppSelf, const CSession &session)
+    : QObject(0)
+    , m_session(session)
+    , m_pActionsPool(new UIActionsPool(this))
+    , m_pVisualState(0)
+{
+    /* Cache IMedium data: */
+    vboxGlobal().startEnumeratingMedia();
+
+    /* Check CSession object */
+    AssertMsg(!m_session.isNull(), ("CSession is not set!\n"));
+
+    /* Storing self */
+    if (ppSelf)
+        *ppSelf = this;
+
+    /* Enter default (normal) state */
+    enterBaseVisualState();
+}
+
+void UIMachine::sltChangeVisualState(UIVisualStateType visualStateType)
+{
+    /* Delete previous state */
+    delete m_pVisualState;
+    m_pVisualState = 0;
+
+    /* Create new state */
+    switch (visualStateType)
+    {
+        case UIVisualStateType_Normal:
+        {
+            m_pVisualState = new UIVisualStateNormal(this, m_session, m_pActionsPool);
+            break;
+        }
+        case UIVisualStateType_Fullscreen:
+        {
+            m_pVisualState = new UIVisualStateFullscreen(this, m_session, m_pActionsPool);
+            break;
+        }
+        case UIVisualStateType_Seamless:
+        {
+            m_pVisualState = new UIVisualStateSeamless(this, m_session, m_pActionsPool);
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+void UIMachine::enterBaseVisualState()
+{
+    sltChangeVisualState(UIVisualStateType_Normal);
+}
+
+#include "UIMachine.moc"
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.h	(revision 26637)
@@ -0,0 +1,55 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachine class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIMachine_h__
+#define __UIMachine_h__
+
+/* Local includes */
+#include "COMDefs.h"
+#include "UIMachineDefs.h"
+
+/* Local forwards */
+class UIActionsPool;
+class UIVisualState;
+
+class UIMachine : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    UIMachine(UIMachine **ppSelf, const CSession &session);
+
+private slots:
+
+    void sltChangeVisualState(UIVisualStateType visualStateType);
+
+private:
+
+    void enterBaseVisualState();
+
+    CSession m_session;
+    UIActionsPool *m_pActionsPool;
+    UIVisualState *m_pVisualState;
+};
+
+#endif // __UIMachine_h__
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineDefs.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineDefs.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineDefs.h	(revision 26637)
@@ -0,0 +1,67 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * Defines for Virtual Machine classes
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIMachineDefs_h__
+#define __UIMachineDefs_h__
+
+/* Machine states enum: */
+enum UIVisualStateType
+{
+    UIVisualStateType_Normal,
+    UIVisualStateType_Fullscreen,
+    UIVisualStateType_Seamless
+};
+
+/* Machine elements enum: */
+enum UIVisualElement
+{
+    UIVisualElement_WindowCaption         = 0x01,
+    UIVisualElement_MouseIntegrationStuff = 0x02,
+    UIVisualElement_PauseStuff            = 0x04,
+    UIVisualElement_HDStuff               = 0x08,
+    UIVisualElement_CDStuff               = 0x10,
+    UIVisualElement_FDStuff               = 0x20,
+    UIVisualElement_NetworkStuff          = 0x40,
+    UIVisualElement_USBStuff              = 0x80,
+    UIVisualElement_VRDPStuff             = 0x100,
+    UIVisualElement_SharedFolderStuff     = 0x200,
+    UIVisualElement_VirtualizationStuff   = 0x400,
+    UIVisualElement_AllStuff              = 0xFFFF
+};
+
+/* Mouse states enum: */
+enum UIMouseStateType
+{
+    UIMouseStateType_MouseCaptured         = 0x01,
+    UIMouseStateType_MouseAbsolute         = 0x02,
+    UIMouseStateType_MouseAbsoluteDisabled = 0x04,
+    UIMouseStateType_MouseNeedsHostCursor  = 0x08
+};
+
+/* Machine View states enum: */
+enum UIViewStateType
+{
+    UIViewStateType_KeyboardCaptured = 0x01,
+    UIViewStateType_HostKeyPressed   = 0x02
+};
+
+#endif // __UIMachineDefs_h__
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 26637)
@@ -0,0 +1,1833 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineLogic class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Global includes */
+#include <QDir>
+#include <QFileInfo>
+#include <QProgressBar>
+#include <QDesktopWidget>
+
+/* Local includes */
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+
+#include "VBoxMediaManagerDlg.h"
+#include "VBoxTakeSnapshotDlg.h"
+#include "VBoxVMInformationDlg.h"
+#include "VBoxVMSettingsNetwork.h"
+#include "VBoxVMSettingsSF.h"
+//#include "VBoxDownloaderWgt.h"
+
+#include "QIFileDialog.h"
+#include "QIHttp.h"
+
+#include "UIActionsPool.h"
+#include "UIMachineLogic.h"
+#include "UIMachineLogicNormal.h"
+//#include "UIMachineLogicFullscreen.h"
+//#include "UIMachineLogicSeamless.h"
+#include "UIMachineWindow.h"
+#include "UIMachineView.h"
+
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <VBox/VMMDev.h>
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+# include <iprt/ldr.h>
+#endif
+
+#ifdef Q_WS_X11
+# include <XKeyboard.h>
+#endif
+
+#ifdef Q_WS_X11
+# include <QX11Info>
+#endif
+
+struct MountTarget
+{
+    MountTarget() : name(QString("")), port(0), device(0), id(QString()), type(VBoxDefs::MediumType_Invalid) {}
+    MountTarget(const QString &strName, LONG iPort, LONG iDevice)
+        : name(strName), port(iPort), device(iDevice), id(QString()), type(VBoxDefs::MediumType_Invalid) {}
+    MountTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strId)
+        : name(strName), port(iPort), device(iDevice), id(strId), type(VBoxDefs::MediumType_Invalid) {}
+    MountTarget(const QString &strName, LONG iPort, LONG iDevice, VBoxDefs::MediumType eType)
+        : name(strName), port(iPort), device(iDevice), id(QString()), type(eType) {}
+    QString name;
+    LONG port;
+    LONG device;
+    QString id;
+    VBoxDefs::MediumType type;
+};
+Q_DECLARE_METATYPE(MountTarget);
+
+class UINetworkAdaptersDialog : public QIWithRetranslateUI<QDialog>
+{
+    Q_OBJECT;
+
+public:
+
+    UINetworkAdaptersDialog(QWidget *pParent, CSession &session)
+        : QIWithRetranslateUI<QDialog>(pParent)
+        , m_pSettings(0)
+        , m_session(session)
+    {
+        /* Setup Dialog's options */
+        setModal(true);
+        setWindowIcon(QIcon(":/nw_16px.png"));
+        setSizeGripEnabled(true);
+
+        /* Setup main dialog's layout */
+        QVBoxLayout *pMainLayout = new QVBoxLayout(this);
+        VBoxGlobal::setLayoutMargin(pMainLayout, 10);
+        pMainLayout->setSpacing(10);
+
+        /* Setup settings layout */
+        m_pSettings = new VBoxVMSettingsNetworkPage(true);
+        m_pSettings->setOrderAfter(this);
+        VBoxGlobal::setLayoutMargin(m_pSettings->layout(), 0);
+        m_pSettings->getFrom(m_session.GetMachine());
+        pMainLayout->addWidget(m_pSettings);
+
+        /* Setup button's layout */
+        QIDialogButtonBox *pButtonBox = new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help);
+
+        connect(pButtonBox, SIGNAL(helpRequested()), &vboxProblem(), SLOT(showHelpHelpDialog()));
+        connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
+        connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
+        pMainLayout->addWidget(pButtonBox);
+
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setWindowTitle(tr("Network Adapters"));
+    }
+
+protected slots:
+
+    virtual void accept()
+    {
+        m_pSettings->putBackTo();
+        CMachine machine = m_session.GetMachine();
+        machine.SaveSettings();
+        if (!machine.isOk())
+            vboxProblem().cannotSaveMachineSettings(machine);
+        QDialog::accept();
+    }
+
+protected:
+
+    void showEvent(QShowEvent *pEvent)
+    {
+        resize(450, 300);
+        VBoxGlobal::centerWidget(this, parentWidget());
+        setMinimumWidth(400);
+        QDialog::showEvent(pEvent);
+    }
+
+private:
+
+    VBoxSettingsPage *m_pSettings;
+    CSession &m_session;
+};
+
+class UISharedFoldersDialog : public QIWithRetranslateUI<QDialog>
+{
+    Q_OBJECT;
+
+public:
+
+    UISharedFoldersDialog(QWidget *pParent, CSession &session)
+        : QIWithRetranslateUI<QDialog>(pParent)
+        , m_pSettings(0)
+        , m_session(session)
+    {
+        /* Setup Dialog's options */
+        setModal(true);
+        setWindowIcon(QIcon(":/select_file_16px.png"));
+        setSizeGripEnabled(true);
+
+        /* Setup main dialog's layout */
+        QVBoxLayout *pMainLayout = new QVBoxLayout(this);
+        VBoxGlobal::setLayoutMargin(pMainLayout, 10);
+        pMainLayout->setSpacing(10);
+
+        /* Setup settings layout */
+        m_pSettings = new VBoxVMSettingsSF(MachineType | ConsoleType, this);
+        VBoxGlobal::setLayoutMargin(m_pSettings->layout(), 0);
+        m_pSettings->getFromConsole(m_session.GetConsole());
+        m_pSettings->getFromMachine(m_session.GetMachine());
+        pMainLayout->addWidget(m_pSettings);
+
+        /* Setup button's layout */
+        QIDialogButtonBox *pButtonBox = new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help);
+
+        connect(pButtonBox, SIGNAL(helpRequested()), &vboxProblem(), SLOT(showHelpHelpDialog()));
+        connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
+        connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
+        pMainLayout->addWidget(pButtonBox);
+
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setWindowTitle(tr("Shared Folders"));
+    }
+
+protected slots:
+
+    virtual void accept()
+    {
+        m_pSettings->putBackToConsole();
+        m_pSettings->putBackToMachine();
+        CMachine machine = m_session.GetMachine();
+        machine.SaveSettings();
+        if (!machine.isOk())
+            vboxProblem().cannotSaveMachineSettings(machine);
+        QDialog::accept();
+    }
+
+protected:
+
+    void showEvent (QShowEvent *aEvent)
+    {
+        resize(450, 300);
+        VBoxGlobal::centerWidget(this, parentWidget());
+        setMinimumWidth(400);
+        QDialog::showEvent(aEvent);
+    }
+
+private:
+
+    VBoxVMSettingsSF *m_pSettings;
+    CSession &m_session;
+};
+
+#if 0
+class UIAdditionsDownloader : public VBoxDownloaderWgt
+{
+    Q_OBJECT;
+
+public:
+
+    UIAdditionsDownloader (const QString &aSource, const QString &aTarget, QAction *aAction)
+        : VBoxDownloaderWgt (aSource, aTarget)
+        , mAction (aAction)
+    {
+        mAction->setEnabled (false);
+        retranslateUi();
+    }
+
+    void start()
+    {
+        acknowledgeStart();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        mCancelButton->setText (tr ("Cancel"));
+        mProgressBar->setToolTip (tr ("Downloading the VirtualBox Guest Additions "
+                                      "CD image from <nobr><b>%1</b>...</nobr>")
+                                      .arg (mSource.toString()));
+        mCancelButton->setToolTip (tr ("Cancel the VirtualBox Guest "
+                                       "Additions CD image download"));
+    }
+
+private slots:
+
+    void downloadFinished (bool aError)
+    {
+        if (aError)
+            VBoxDownloaderWgt::downloadFinished (aError);
+        else
+        {
+            QByteArray receivedData (mHttp->readAll());
+            /* Serialize the incoming buffer into the .iso image. */
+            while (true)
+            {
+                QFile file (mTarget);
+                if (file.open (QIODevice::WriteOnly))
+                {
+                    file.write (receivedData);
+                    file.close();
+                    //if (vboxProblem().confirmMountAdditions (mSource.toString(),QDir::toNativeSeparators (mTarget)))
+                    //    vboxGlobal().consoleWnd().installGuestAdditionsFrom (mTarget);
+                    QTimer::singleShot (0, this, SLOT (suicide()));
+                    break;
+                }
+                else
+                {
+                    vboxProblem().message (window(), VBoxProblemReporter::Error,
+                        tr ("<p>Failed to save the downloaded file as "
+                            "<nobr><b>%1</b>.</nobr></p>")
+                        .arg (QDir::toNativeSeparators (mTarget)));
+                }
+
+                QString target = QIFileDialog::getExistingDirectory (
+                    QFileInfo (mTarget).absolutePath(), this,
+                    tr ("Select folder to save Guest Additions image to"), true);
+                if (target.isNull())
+                    QTimer::singleShot (0, this, SLOT (suicide()));
+                else
+                    mTarget = QDir (target).absoluteFilePath (QFileInfo (mTarget).fileName());
+            }
+        }
+    }
+
+    void suicide()
+    {
+        QStatusBar *sb = qobject_cast <QStatusBar*> (parent());
+        Assert (sb);
+        sb->removeWidget (this);
+        mAction->setEnabled (true);
+        VBoxDownloaderWgt::suicide();
+    }
+
+private:
+
+    bool confirmDownload()
+    {
+        return vboxProblem().confirmDownloadAdditions (mSource.toString(),
+            mHttp->lastResponse().contentLength());
+    }
+
+    void warnAboutError (const QString &aError)
+    {
+        return vboxProblem().cannotDownloadGuestAdditions (mSource.toString(), aError);
+    }
+
+    QAction *mAction;
+};
+#endif
+
+UIMachineLogic* UIMachineLogic::create(QObject *pParent,
+                                       const CSession &session,
+                                       UIActionsPool *pActionsPool,
+                                       UIVisualStateType visualStateType)
+{
+    UIMachineLogic *logic = 0;
+    switch (visualStateType)
+    {
+        case UIVisualStateType_Normal:
+            logic = new UIMachineLogicNormal(pParent, session, pActionsPool);
+            break;
+        case UIVisualStateType_Fullscreen:
+            // logic = new UIMachineLogicFullscreen(pParent, session, pActionsPool);
+            logic = new UIMachineLogicNormal(pParent, session, pActionsPool);
+            break;
+        case UIVisualStateType_Seamless:
+            // logic = new UIMachineLogicSeamless(pParent, session, pActionsPool);
+            logic = new UIMachineLogicNormal(pParent, session, pActionsPool);
+            break;
+    }
+    return logic;
+}
+
+UIMachineLogic::UIMachineLogic(QObject *pParent,
+                               const CSession &session,
+                               UIActionsPool *pActionsPool,
+                               UIVisualStateType visualStateType)
+    : QObject(pParent)
+    , m_pMachineWindowContainer(0)
+    , m_session(session)
+    , m_pActionsPool(pActionsPool)
+    , m_machineState(KMachineState_Null)
+    , m_visualStateType(visualStateType)
+    , m_pRunningActions(0)
+    , m_pRunningOrPausedActions(0)
+    , m_bIsFirstTimeStarted(false)
+    , m_bIsOpenViewFinished(false)
+    , m_bIsGraphicsSupported(false)
+    , m_bIsSeamlessSupported(false)
+    , m_bIsAutoSaveMedia(true)
+    , m_bIsPreventAutoClose(false)
+{
+    /* Prepare action groups: */
+    prepareActionGroups();
+
+    /* Prepare action connections: */
+    prepareActionConnections();
+
+    /* Check the status of required features: */
+    prepareRequiredFeatures();
+
+    /* Load common logic settings: */
+    loadLogicSettings();
+}
+
+UIMachineLogic::~UIMachineLogic()
+{
+    /* Save common logic settings: */
+    saveLogicSettings();
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    /* Close debugger: */
+    // TODO: Check that logic!
+    //dbgDestroy();
+#endif
+}
+
+void UIMachineLogic::updateAppearanceOf(int iElement)
+{
+    CMachine machine = session().GetMachine();
+
+    bool isRunningOrPaused = machineState() == KMachineState_Running ||
+                             machineState() == KMachineState_Paused ||
+                             machineState() == KMachineState_Teleporting ||
+                             machineState() == KMachineState_LiveSnapshotting;
+
+    if (iElement & UIVisualElement_PauseStuff)
+    {
+        actionsPool()->action(UIActionIndex_Toggle_Pause)->setEnabled(isRunningOrPaused);
+    }
+}
+
+void UIMachineLogic::sltAdjustWindow()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    if (machineWindowWrapper()->machineWindow()->isMaximized())
+        machineWindowWrapper()->machineWindow()->showNormal();
+
+    machineWindowWrapper()->machineView()->normalizeGeometry(true);
+}
+
+void UIMachineLogic::sltToggleMouseIntegration(bool aOff)
+{
+    if (!machineWindowWrapper())
+        return;
+
+    machineWindowWrapper()->machineView()->setMouseIntegrationEnabled(!aOff);
+
+    updateAppearanceOf(UIVisualElement_MouseIntegrationStuff);
+}
+
+void UIMachineLogic::sltTypeCAD()
+{
+    CKeyboard keyboard = session().GetConsole().GetKeyboard();
+    Assert(!keyboard.isNull());
+    keyboard.PutCAD();
+    AssertWrapperOk(keyboard);
+}
+
+#ifdef Q_WS_X11
+void UIMachineLogic::sltTypeCABS()
+{
+    CKeyboard keyboard = session().GetConsole().GetKeyboard();
+    Assert (!keyboard.isNull());
+    static QVector<LONG> aSequence(6);
+    aSequence[0] = 0x1d; /* Ctrl down */
+    aSequence[1] = 0x38; /* Alt down */
+    aSequence[2] = 0x0E; /* Backspace down */
+    aSequence[3] = 0x8E; /* Backspace up */
+    aSequence[4] = 0xb8; /* Alt up */
+    aSequence[5] = 0x9d; /* Ctrl up */
+    keyboard.PutScancodes(aSequence);
+    AssertWrapperOk(keyboard);
+}
+#endif
+
+void UIMachineLogic::sltTakeSnapshot()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    /* Remember the paused state. */
+    bool bWasPaused = m_machineState == KMachineState_Paused;
+    if (!bWasPaused)
+    {
+        /* Suspend the VM and ignore the close event if failed to do so.
+         * pause() will show the error message to the user. */
+        if (!pause(true))
+            return;
+    }
+
+    CMachine machine = session().GetMachine();
+
+    VBoxTakeSnapshotDlg dlg(machineWindowWrapper()->machineWindow(), machine);
+
+    QString strTypeId = machine.GetOSTypeId();
+    dlg.mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(strTypeId));
+
+    /* Search for the max available filter index. */
+    QString strNameTemplate = tr("Snapshot %1");
+    int iMaxSnapshotIndex = searchMaxSnapshotIndex(machine, machine.GetSnapshot(QString()), strNameTemplate);
+    dlg.mLeName->setText(strNameTemplate.arg(++ iMaxSnapshotIndex));
+
+    if (dlg.exec() == QDialog::Accepted)
+    {
+        CConsole console = session().GetConsole();
+
+        CProgress progress = console.TakeSnapshot(dlg.mLeName->text().trimmed(), dlg.mTeDescription->toPlainText());
+
+        if (console.isOk())
+        {
+            /* Show the "Taking Snapshot" progress dialog */
+            vboxProblem().showModalProgressDialog(progress, machine.GetName(), machineWindowWrapper()->machineWindow(), 0);
+
+            if (progress.GetResultCode() != 0)
+                vboxProblem().cannotTakeSnapshot(progress);
+        }
+        else
+            vboxProblem().cannotTakeSnapshot(console);
+    }
+
+    /* Restore the running state if needed. */
+    if (!bWasPaused)
+        pause(false);
+}
+
+void UIMachineLogic::sltShowInformationDialog()
+{
+    // TODO: Call for singleton information dialog for this machine!
+    //VBoxVMInformationDlg::createInformationDlg(session(), machineWindowWrapper()->machineWindow());
+}
+
+void UIMachineLogic::sltReset()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    if (vboxProblem().confirmVMReset(machineWindowWrapper()->machineWindow()))
+        session().GetConsole().Reset();
+}
+
+void UIMachineLogic::sltPause(bool aOn)
+{
+    if (!machineWindowWrapper())
+        return;
+
+    pause(aOn);
+
+    updateAppearanceOf(UIVisualElement_PauseStuff);
+}
+
+void UIMachineLogic::sltACPIShutdown()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    CConsole console = session().GetConsole();
+
+    if (!console.GetGuestEnteredACPIMode())
+        return vboxProblem().cannotSendACPIToMachine();
+
+    console.PowerButton();
+    if (!console.isOk())
+        vboxProblem().cannotACPIShutdownMachine(console);
+}
+
+void UIMachineLogic::sltClose()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    machineWindowWrapper()->machineWindow()->close();
+}
+
+void UIMachineLogic::sltPrepareStorageMenu()
+{
+    QMenu *pMenu = qobject_cast<QMenu*>(sender());
+    AssertMsg(pMenu, ("This slot should only be called on hovering storage menu!\n"));
+    pMenu->clear();
+
+    QMenu *pOpticalDevicesMenu = actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu();
+    QMenu *pFloppyDevicesMenu = actionsPool()->action(UIActionIndex_Menu_FloppyDevices)->menu();
+
+    KDeviceType deviceType = pMenu == pOpticalDevicesMenu ? KDeviceType_DVD :
+                             pMenu == pFloppyDevicesMenu  ? KDeviceType_Floppy :
+                                                            KDeviceType_Null;
+    AssertMsg(deviceType != KDeviceType_Null, ("Incorrect storage device type!\n"));
+
+    VBoxDefs::MediumType mediumType = pMenu == pOpticalDevicesMenu ? VBoxDefs::MediumType_DVD :
+                                      pMenu == pFloppyDevicesMenu  ? VBoxDefs::MediumType_Floppy :
+                                                                     VBoxDefs::MediumType_Invalid;
+    AssertMsg(mediumType != VBoxDefs::MediumType_Invalid, ("Incorrect storage medium type!\n"));
+
+    CMachine machine = session().GetMachine();
+    const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
+    foreach (const CMediumAttachment &attachment, attachments)
+    {
+        CStorageController controller = machine.GetStorageControllerByName(attachment.GetController());
+        if (!controller.isNull() && (attachment.GetType() == deviceType))
+        {
+            /* Attachment menu item */
+            QMenu *pAttachmentMenu = 0;
+            if (pMenu->menuAction()->data().toInt() > 1)
+            {
+                pAttachmentMenu = new QMenu(pMenu);
+                pAttachmentMenu->setTitle(QString("%1 (%2)").arg(controller.GetName())
+                                          .arg (vboxGlobal().toString(StorageSlot(controller.GetBus(),
+                                                                                  attachment.GetPort(),
+                                                                                  attachment.GetDevice()))));
+                switch (controller.GetBus())
+                {
+                    case KStorageBus_IDE:
+                        pAttachmentMenu->setIcon(QIcon(":/ide_16px.png")); break;
+                    case KStorageBus_SATA:
+                        pAttachmentMenu->setIcon(QIcon(":/sata_16px.png")); break;
+                    case KStorageBus_SCSI:
+                        pAttachmentMenu->setIcon(QIcon(":/scsi_16px.png")); break;
+                    case KStorageBus_Floppy:
+                        pAttachmentMenu->setIcon(QIcon(":/floppy_16px.png")); break;
+                    default:
+                        break;
+                }
+                pMenu->addMenu(pAttachmentMenu);
+            }
+            else pAttachmentMenu = pMenu;
+
+            /* Mount Medium actions */
+            CMediumVector mediums;
+            switch (mediumType)
+            {
+                case VBoxDefs::MediumType_DVD:
+                    mediums += vboxGlobal().virtualBox().GetHost().GetDVDDrives();
+                    mediums += vboxGlobal().virtualBox().GetDVDImages();
+                    break;
+                case VBoxDefs::MediumType_Floppy:
+                    mediums += vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
+                    mediums += vboxGlobal().virtualBox().GetFloppyImages();
+                    break;
+                default:
+                    break;
+            }
+
+            int mediumsToBeShown = 0;
+            const int maxMediumsToBeShown = 5;
+            CMedium currentMedium = attachment.GetMedium();
+            QString currentId = currentMedium.isNull() ? QString::null : currentMedium.GetId();
+            bool currentUsed = false;
+            foreach (CMedium medium, mediums)
+            {
+                bool isMediumUsed = false;
+                foreach (const CMediumAttachment &otherAttachment, attachments)
+                {
+                    if (otherAttachment != attachment)
+                    {
+                        CMedium otherMedium = otherAttachment.GetMedium();
+                        if (!otherMedium.isNull() && otherMedium.GetId() == medium.GetId())
+                        {
+                            isMediumUsed = true;
+                            break;
+                        }
+                    }
+                }
+                if (!isMediumUsed)
+                {
+                    if (!currentUsed && !currentMedium.isNull() && mediumsToBeShown == maxMediumsToBeShown - 1)
+                        medium = currentMedium;
+
+                    if (medium.GetId() == currentId)
+                        currentUsed = true;
+
+                    QAction *mountMediumAction = new QAction(VBoxMedium(medium, mediumType).name(), pAttachmentMenu);
+                    mountMediumAction->setCheckable(true);
+                    mountMediumAction->setChecked(!currentMedium.isNull() && medium.GetId() == currentId);
+                    mountMediumAction->setData(QVariant::fromValue(MountTarget(controller.GetName(),
+                                                                               attachment.GetPort(),
+                                                                               attachment.GetDevice(),
+                                                                               medium.GetId())));
+                    connect(mountMediumAction, SIGNAL(triggered(bool)), this, SLOT(sltMountStorageMedium()));
+                    pAttachmentMenu->addAction(mountMediumAction);
+                    ++ mediumsToBeShown;
+                    if (mediumsToBeShown == maxMediumsToBeShown)
+                        break;
+                }
+            }
+
+            /* Virtual Media Manager action */
+            QAction *callVMMAction = new QAction(pAttachmentMenu);
+            callVMMAction->setIcon(QIcon(":/diskimage_16px.png"));
+            callVMMAction->setData(QVariant::fromValue(MountTarget(controller.GetName(),
+                                                                   attachment.GetPort(),
+                                                                   attachment.GetDevice(),
+                                                                   mediumType)));
+            connect(callVMMAction, SIGNAL(triggered(bool)), this, SLOT(sltMountStorageMedium()));
+            pAttachmentMenu->addAction(callVMMAction);
+
+            /* Separator */
+            pAttachmentMenu->addSeparator();
+
+            /* Unmount Medium action */
+            QAction *unmountMediumAction = new QAction(pAttachmentMenu);
+            unmountMediumAction->setEnabled(!currentMedium.isNull());
+            unmountMediumAction->setData(QVariant::fromValue(MountTarget(controller.GetName(),
+                                                                         attachment.GetPort(),
+                                                                         attachment.GetDevice())));
+            connect(unmountMediumAction, SIGNAL(triggered(bool)), this, SLOT(sltMountStorageMedium()));
+            pAttachmentMenu->addAction(unmountMediumAction);
+
+            /* Switch CD/FD naming */
+            switch (mediumType)
+            {
+                case VBoxDefs::MediumType_DVD:
+                    callVMMAction->setText(tr("More CD/DVD Images..."));
+                    unmountMediumAction->setText(tr("Unmount CD/DVD Device"));
+                    unmountMediumAction->setIcon(VBoxGlobal::iconSet(":/cd_unmount_16px.png",
+                                                                     ":/cd_unmount_dis_16px.png"));
+                    break;
+                case VBoxDefs::MediumType_Floppy:
+                    callVMMAction->setText(tr("More Floppy Images..."));
+                    unmountMediumAction->setText(tr("Unmount Floppy Device"));
+                    unmountMediumAction->setIcon(VBoxGlobal::iconSet(":/fd_unmount_16px.png",
+                                                                     ":/fd_unmount_dis_16px.png"));
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    if (pMenu->menuAction()->data().toInt() == 0)
+    {
+        /* Empty menu item */
+        Assert(pMenu->isEmpty());
+        QAction *emptyMenuAction = new QAction(pMenu);
+        emptyMenuAction->setEnabled(false);
+        switch (mediumType)
+        {
+            case VBoxDefs::MediumType_DVD:
+                emptyMenuAction->setText(tr("No CD/DVD Devices Attached"));
+                break;
+            case VBoxDefs::MediumType_Floppy:
+                emptyMenuAction->setText(tr("No Floppy Devices Attached"));
+                break;
+            default:
+                break;
+        }
+        emptyMenuAction->setIcon(VBoxGlobal::iconSet(":/delete_16px.png", ":/delete_dis_16px.png"));
+        pMenu->addAction(emptyMenuAction);
+    }
+}
+
+void UIMachineLogic::sltMountStorageMedium()
+{
+    /* Get sender action */
+    QAction *action = qobject_cast<QAction*>(sender());
+    AssertMsg(action, ("This slot should only be called on selecting storage menu item!\n"));
+
+    /* Get current machine */
+    CMachine machine = session().GetMachine();
+
+    /* Get mount-target */
+    MountTarget target = action->data().value<MountTarget>();
+
+    /* Current mount-target attributes */
+    CMediumAttachment currentAttachment = machine.GetMediumAttachment(target.name, target.port, target.device);
+    CMedium currentMedium = currentAttachment.GetMedium();
+    QString currentId = currentMedium.isNull() ? QString("") : currentMedium.GetId();
+
+    /* New mount-target attributes */
+    QString newId = QString("");
+    bool selectWithMediaManager = target.type != VBoxDefs::MediumType_Invalid;
+
+    /* Open Virtual Media Manager to select image id */
+    if (selectWithMediaManager)
+    {
+        /* Search for already used images */
+        QStringList usedImages;
+        foreach (const CMediumAttachment &attachment, machine.GetMediumAttachments())
+        {
+            CMedium medium = attachment.GetMedium();
+            if (attachment != currentAttachment && !medium.isNull() && !medium.GetHostDrive())
+                usedImages << medium.GetId();
+        }
+        /* Open VMM Dialog */
+        VBoxMediaManagerDlg dlg(machineWindowWrapper()->machineWindow());
+        dlg.setup(target.type, true /* select? */, true /* refresh? */, machine, currentId, true, usedImages);
+        if (dlg.exec() == QDialog::Accepted)
+            newId = dlg.selectedId();
+        else return;
+    }
+    /* Use medium which was sent */
+    else if (!target.id.isNull() && target.id != currentId)
+        newId = target.id;
+
+    bool mount = !newId.isEmpty();
+
+    /* Remount medium to the predefined port/device */
+    bool wasMounted = false;
+    machine.MountMedium(target.name, target.port, target.device, newId, false /* force */);
+    if (machine.isOk())
+        wasMounted = true;
+    else
+    {
+        /* Ask for force remounting */
+        if (vboxProblem().cannotRemountMedium(machineWindowWrapper()->machineWindow(), machine, vboxGlobal().findMedium (mount ? newId : currentId), mount, true /* retry? */) == QIMessageBox::Ok)
+        {
+            /* Force remount medium to the predefined port/device. */
+            machine.MountMedium(target.name, target.port, target.device, newId, true /* force */);
+            if (machine.isOk())
+                wasMounted = true;
+            else
+                vboxProblem().cannotRemountMedium(machineWindowWrapper()->machineWindow(), machine, vboxGlobal().findMedium (mount ? newId : currentId), mount, false /* retry? */);
+        }
+    }
+
+    /* Save medium mounted at runtime */
+    if (wasMounted && m_bIsAutoSaveMedia)
+    {
+        machine.SaveSettings();
+        if (!machine.isOk())
+            vboxProblem().cannotSaveMachineSettings(machine);
+    }
+}
+
+void UIMachineLogic::sltOpenNetworkAdaptersDialog()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    UINetworkAdaptersDialog dlg(machineWindowWrapper()->machineWindow(), session());
+    dlg.exec();
+}
+
+void UIMachineLogic::sltOpenSharedFoldersDialog()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    UISharedFoldersDialog dlg(machineWindowWrapper()->machineWindow(), session());
+    dlg.exec();
+}
+
+void UIMachineLogic::sltPrepareUSBMenu()
+{
+}
+
+void UIMachineLogic::sltAttachUSBDevice()
+{
+}
+
+void UIMachineLogic::sltSwitchVrdp(bool aOn)
+{
+    if (!machineWindowWrapper())
+        return;
+
+    CVRDPServer server = session().GetMachine().GetVRDPServer();
+    AssertMsg(!server.isNull(), ("VRDP Server should not be null!\n"));
+
+    server.SetEnabled(aOn);
+
+    updateAppearanceOf(UIVisualElement_VRDPStuff);
+}
+
+void UIMachineLogic::sltInstallGuestAdditions()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    char strAppPrivPath[RTPATH_MAX];
+    int rc = RTPathAppPrivateNoArch(strAppPrivPath, sizeof(strAppPrivPath));
+    AssertRC (rc);
+
+    QString strSrc1 = QString(strAppPrivPath) + "/VBoxGuestAdditions.iso";
+    QString strSrc2 = qApp->applicationDirPath() + "/additions/VBoxGuestAdditions.iso";
+
+    /* Check the standard image locations */
+    if (QFile::exists(strSrc1))
+        return installGuestAdditionsFrom(strSrc1);
+    else if (QFile::exists(strSrc2))
+        return installGuestAdditionsFrom(strSrc2);
+
+    /* Check for the already registered image */
+    CVirtualBox vbox = vboxGlobal().virtualBox();
+    QString name = QString("VBoxGuestAdditions_%1.iso").arg(vbox.GetVersion().remove("_OSE"));
+
+    CMediumVector vec = vbox.GetDVDImages();
+    for (CMediumVector::ConstIterator it = vec.begin(); it != vec.end(); ++ it)
+    {
+        QString path = it->GetLocation();
+        /* Compare the name part ignoring the file case */
+        QString fn = QFileInfo(path).fileName();
+        if (RTPathCompare(name.toUtf8().constData(), fn.toUtf8().constData()) == 0)
+            return installGuestAdditionsFrom(path);
+    }
+
+    /* Download the required image */
+    int result = vboxProblem().cannotFindGuestAdditions(QDir::toNativeSeparators(strSrc1), QDir::toNativeSeparators(strSrc2));
+    if (result == QIMessageBox::Yes)
+    {
+        QString source = QString("http://download.virtualbox.org/virtualbox/%1/")
+                                 .arg (vbox.GetVersion().remove("_OSE")) + name;
+        QString target = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(name);
+
+        // TODO: Think more about additions downloader...
+        //UIAdditionsDownloader *dl =
+        //    new UIAdditionsDownloader(source, target, mDevicesInstallGuestToolsAction);
+        //machineWindowWrapper()->statusBar()->addWidget(dl, 0);
+        //dl->start();
+    }
+}
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+void UIMachineLogic::sltPrepareDebugMenu()
+{
+    /* The "Logging" item. */
+    bool fEnabled = false;
+    bool fChecked = false;
+    CConsole console = session().GetConsole();
+    if (console.isOk())
+    {
+        CMachineDebugger cdebugger = console.GetDebugger();
+        if (console.isOk())
+        {
+            fEnabled = true;
+            fChecked = cdebugger.GetLogEnabled() != FALSE;
+        }
+    }
+    if (fEnabled != actionsPool()->action(UIActionIndex_Toggle_Logging)->isEnabled())
+        actionsPool()->action(UIActionIndex_Toggle_Logging)->setEnabled(fEnabled);
+    if (fChecked != actionsPool()->action(UIActionIndex_Toggle_Logging)->isChecked())
+        actionsPool()->action(UIActionIndex_Toggle_Logging)->setChecked(fChecked);
+}
+
+void UIMachineLogic::sltShowDebugStatistics()
+{
+    if (dbgCreated())
+        m_dbgGuiVT->pfnShowStatistics(m_dbgGui);
+}
+
+void UIMachineLogic::sltShowDebugCommandLine()
+{
+    if (dbgCreated())
+        m_dbgGuiVT->pfnShowCommandLine(m_dbgGui);
+}
+
+void UIMachineLogic::sltLoggingToggled(bool bState)
+{
+    NOREF(bState);
+    CConsole console = session().GetConsole();
+    if (console.isOk())
+    {
+        CMachineDebugger cdebugger = console.GetDebugger();
+        if (console.isOk())
+            cdebugger.SetLogEnabled(bState);
+    }
+}
+#endif
+
+void UIMachineLogic::sltUpdateMachineState(KMachineState machineState)
+{
+    bool bGuruMeditation = false;
+
+    if (machineWindowWrapper() && m_machineState != machineState)
+    {
+        switch (machineState)
+        {
+            case KMachineState_Stuck:
+            {
+                bGuruMeditation = true;
+                break;
+            }
+            case KMachineState_Paused:
+            {
+                if (!actionsPool()->action(UIActionIndex_Toggle_Pause)->isChecked())
+                    actionsPool()->action(UIActionIndex_Toggle_Pause)->setChecked(true);
+                break;
+            }
+            case KMachineState_Running:
+            case KMachineState_Teleporting:
+            case KMachineState_LiveSnapshotting:
+            {
+                if ((m_machineState == KMachineState_Paused ||
+                     m_machineState == KMachineState_TeleportingPausedVM)
+                     && actionsPool()->action(UIActionIndex_Toggle_Pause)->isChecked())
+                     actionsPool()->action(UIActionIndex_Toggle_Pause)->setChecked(false);
+                break;
+            }
+#ifdef Q_WS_X11
+            case KMachineState_Starting:
+            case KMachineState_Restoring:
+            case KMachineState_TeleportingIn:
+            {
+                /* The keyboard handler may wish to do some release logging on startup.
+                 * Tell it that the logger is now active. */
+                doXKeyboardLogging(QX11Info::display());
+                break;
+            }
+#endif
+            default:
+                break;
+        }
+
+        bool bIsRunning = machineState == KMachineState_Running ||
+                          machineState == KMachineState_Teleporting ||
+                          machineState == KMachineState_LiveSnapshotting;
+
+        bool bIsRunningOrPaused = machineState == KMachineState_Running ||
+                                  machineState == KMachineState_Teleporting ||
+                                  machineState == KMachineState_LiveSnapshotting ||
+                                  machineState == KMachineState_Paused;
+
+        m_pRunningActions->setEnabled(bIsRunning);
+        m_pRunningOrPausedActions->setEnabled(bIsRunningOrPaused);
+
+        m_machineState = machineState;
+
+        updateAppearanceOf(UIVisualElement_WindowCaption |
+                           UIVisualElement_HDStuff | UIVisualElement_CDStuff | UIVisualElement_FDStuff |
+                           UIVisualElement_NetworkStuff | UIVisualElement_USBStuff | UIVisualElement_VRDPStuff |
+                           UIVisualElement_PauseStuff | UIVisualElement_MouseIntegrationStuff);
+
+        if (machineState == KMachineState_PoweredOff ||
+            machineState == KMachineState_Saved ||
+            machineState == KMachineState_Teleported ||
+            machineState == KMachineState_Aborted)
+        {
+            /* VM has been powered off or saved or aborted, no matter internally or externally.
+             * We must *safely* close the console window unless auto closure is disabled: */
+            if (!m_bIsPreventAutoClose)
+                machineWindowWrapper()->sltTryClose();
+        }
+    }
+
+    if (bGuruMeditation)
+    {
+        machineWindowWrapper()->machineView()->setIgnoreGuestResize(true);
+
+        CConsole console = session().GetConsole();
+        QString strLogFolder = console.GetMachine().GetLogFolder();
+
+        /* Take the screenshot for debugging purposes and save it */
+        QString strFileName = strLogFolder + "/VBox.png";
+
+        CDisplay display = console.GetDisplay();
+        QImage shot = QImage(display.GetWidth(), display.GetHeight(), QImage::Format_RGB32);
+        display.TakeScreenShot(shot.bits(), shot.width(), shot.height());
+        shot.save(QFile::encodeName(strFileName), "PNG");
+
+        if (vboxProblem().remindAboutGuruMeditation(console, QDir::toNativeSeparators(strLogFolder)))
+        {
+            qApp->processEvents();
+            console.PowerDown();
+            if (!console.isOk())
+                vboxProblem().cannotStopMachine(console);
+        }
+    }
+
+#ifdef Q_WS_MAC
+    if (machineWindowWrapper())
+        machineWindowWrapper()->updateDockOverlay();
+#endif
+}
+
+void UIMachineLogic::sltUpdateAdditionsState(const QString &strVersion, bool bIsActive,
+                                             bool bIsSeamlessSupported, bool bIsGraphicsSupported)
+{
+    actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize)->setEnabled(bIsActive && bIsGraphicsSupported);
+    actionsPool()->action(UIActionIndex_Toggle_Seamless)->setEnabled(bIsActive && bIsGraphicsSupported && bIsSeamlessSupported);
+
+    if ((m_bIsSeamlessSupported != bIsSeamlessSupported) || (m_bIsGraphicsSupported != bIsGraphicsSupported))
+    {
+        m_bIsSeamlessSupported = bIsSeamlessSupported;
+        m_bIsGraphicsSupported = bIsGraphicsSupported;
+
+        // TODO: How should that be performed now?
+        /* If seamless mode should be enabled then check if it is enabled currently and re-enable it if open-view procedure is finished */
+        //if (actionsPool()->action(UIActionIndex_Toggle_Seamless)->isChecked() && m_bIsOpenViewFinished && bIsGraphicsSupported && bIsSeamlessSupported)
+        //    toggleFullscreenMode(true, true);
+    }
+
+    /* Check the GA version only in case of additions are active */
+    if (!bIsActive)
+        return;
+
+    /* Check the Guest Additions version and warn the user about possible
+     * compatibility issues in case if the installed version is outdated. */
+    uint uVersion = strVersion.toUInt();
+    /** @todo r=bird: This isn't want we want! We want the VirtualBox version of the additions, all three numbers. See @bugref{4084}.*/
+    QString strRealVersion = QString("%1.%2").arg(RT_HIWORD(uVersion)).arg(RT_LOWORD(uVersion));
+    QString strExpectedVersion = QString("%1.%2").arg(VMMDEV_VERSION_MAJOR).arg(VMMDEV_VERSION_MINOR);
+
+    if (RT_HIWORD(uVersion) < VMMDEV_VERSION_MAJOR)
+    {
+        vboxProblem().warnAboutTooOldAdditions(machineWindowWrapper()->machineWindow(), strRealVersion, strExpectedVersion);
+    }
+    else if (RT_HIWORD(uVersion) == VMMDEV_VERSION_MAJOR && RT_LOWORD(uVersion) <  VMMDEV_VERSION_MINOR)
+    {
+        vboxProblem().warnAboutOldAdditions(machineWindowWrapper()->machineWindow(), strRealVersion, strExpectedVersion);
+    }
+    else if (uVersion > VMMDEV_VERSION)
+    {
+        vboxProblem().warnAboutNewAdditions(machineWindowWrapper()->machineWindow(), strRealVersion, strExpectedVersion);
+    }
+}
+
+void UIMachineLogic::sltUpdateMouseState(int iState)
+{
+    actionsPool()->action(UIActionIndex_Toggle_MouseIntegration)->setEnabled(iState & UIMouseStateType_MouseAbsolute);
+}
+
+void UIMachineLogic::prepareActionGroups()
+{
+    /* Create group for all actions that are enabled only when the VM is running.
+     * Note that only actions whose enabled state depends exclusively on the
+     * execution state of the VM are added to this group. */
+    m_pRunningActions = new QActionGroup(this);
+    m_pRunningActions->setExclusive(false);
+
+    /* Create group for all actions that are enabled when the VM is running or paused.
+     * Note that only actions whose enabled state depends exclusively on the
+     * execution state of the VM are added to this group. */
+    m_pRunningOrPausedActions = new QActionGroup(this);
+    m_pRunningOrPausedActions->setExclusive(false);
+
+    // TODO: Move actions into approprivate action groups!
+}
+
+void UIMachineLogic::prepareActionConnections()
+{
+    /* "Machine" actions connections */
+    connect(actionsPool()->action(UIActionIndex_Simple_AdjustWindow), SIGNAL(triggered()),
+            this, SLOT(sltAdjustWindow()));
+    connect(actionsPool()->action(UIActionIndex_Toggle_MouseIntegration), SIGNAL(toggled(bool)),
+            this, SLOT(sltToggleMouseIntegration(bool)));
+    connect(actionsPool()->action(UIActionIndex_Simple_TypeCAD), SIGNAL(triggered()),
+            this, SLOT(sltTypeCAD()));
+#ifdef Q_WS_X11
+    connect(actionsPool()->action(UIActionIndex_Simple_TypeCABS), SIGNAL(triggered()),
+            this, SLOT(sltTypeCABS()));
+#endif
+    connect(actionsPool()->action(UIActionIndex_Simple_TakeSnapshot), SIGNAL(triggered()),
+            this, SLOT(sltTakeSnapshot()));
+    connect(actionsPool()->action(UIActionIndex_Simple_InformationDialog), SIGNAL(triggered()),
+            this, SLOT(sltShowInformationDialog()));
+    connect(actionsPool()->action(UIActionIndex_Simple_Reset), SIGNAL(triggered()),
+            this, SLOT(sltReset()));
+    connect(actionsPool()->action(UIActionIndex_Toggle_Pause), SIGNAL(toggled(bool)),
+            this, SLOT(sltPause(bool)));
+    connect(actionsPool()->action(UIActionIndex_Simple_Shutdown), SIGNAL(triggered()),
+            this, SLOT(sltACPIShutdown()));
+    connect(actionsPool()->action(UIActionIndex_Simple_Close), SIGNAL(triggered()),
+            this, SLOT(sltClose()));
+
+    /* "Devices" actions connections */
+    connect(actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu(), SIGNAL(aboutToShow()),
+            this, SLOT(sltPrepareStorageMenu()));
+    connect(actionsPool()->action(UIActionIndex_Menu_FloppyDevices)->menu(), SIGNAL(aboutToShow()),
+            this, SLOT(sltPrepareStorageMenu()));
+    connect(actionsPool()->action(UIActionIndex_Simple_NetworkAdaptersDialog), SIGNAL(triggered()),
+            this, SLOT(sltOpenNetworkAdaptersDialog()));
+    connect(actionsPool()->action(UIActionIndex_Simple_SharedFoldersDialog), SIGNAL(triggered()),
+            this, SLOT(sltOpenSharedFoldersDialog()));
+    connect(actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu(), SIGNAL(aboutToShow()),
+            this, SLOT(sltPrepareUSBMenu()));
+    connect(actionsPool()->action(UIActionIndex_Toggle_VRDP), SIGNAL(toggled(bool)),
+            this, SLOT(sltSwitchVrdp(bool)));
+    connect(actionsPool()->action(UIActionIndex_Simple_InstallGuestTools), SIGNAL(triggered()),
+            this, SLOT(sltInstallGuestAdditions()));
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    /* "Debug" actions connections */
+    connect(actionsPool()->action(UIActionIndex_Menu_Debug)->menu(), SIGNAL(aboutToShow()),
+            this, SLOT(sltPrepareDebugMenu()));
+    connect(actionsPool()->action(UIActionIndex_Simple_Statistics), SIGNAL(triggered()),
+            this, SLOT(sltShowDebugStatistics()));
+    connect(actionsPool()->action(UIActionIndex_Simple_CommandLine), SIGNAL(triggered()),
+            this, SLOT(sltShowDebugCommandLine()));
+    connect(actionsPool()->action(UIActionIndex_Toggle_Logging), SIGNAL(toggled(bool)),
+            this, SLOT(dbgLoggingToggled(bool)));
+#endif
+}
+
+void UIMachineLogic::prepareRequiredFeatures()
+{
+    CConsole console = session().GetConsole();
+
+    /* Check if the virtualization feature is required. */
+    bool bIs64BitsGuest = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetIs64Bit();
+    bool fRecommendVirtEx = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetRecommendedVirtEx();
+    AssertMsg(!bIs64BitsGuest || fRecommendVirtEx, ("Virtualization support missed for 64bit guest!\n"));
+    bool bIsVirtEnabled = console.GetDebugger().GetHWVirtExEnabled();
+    if (fRecommendVirtEx && !bIsVirtEnabled)
+    {
+        bool ret;
+
+        // TODO: Check that logic!
+        //sltPause(true);
+
+        bool fVTxAMDVSupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx);
+
+        if (bIs64BitsGuest)
+            ret = vboxProblem().warnAboutVirtNotEnabled64BitsGuest(fVTxAMDVSupported);
+        else
+            ret = vboxProblem().warnAboutVirtNotEnabledGuestRequired(fVTxAMDVSupported);
+
+        // TODO: Close application!
+        //if (ret == true)
+        //    machineWindowWrapper()->machineWindow()->close();
+        // TODO: Check that logic!
+        //else
+        //    sltPause(false);
+    }
+
+#ifdef Q_WS_MAC
+# ifdef VBOX_WITH_ICHAT_THEATER
+    initSharedAVManager();
+# endif
+#endif
+}
+
+void UIMachineLogic::loadLogicSettings()
+{
+    CMachine machine = session().GetMachine();
+
+    /* Extra-data settings */
+    {
+        QString strSettings;
+
+        strSettings = machine.GetExtraData(VBoxDefs::GUI_AutoresizeGuest);
+        if (strSettings != "off")
+            actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize)->setChecked(true);
+
+        strSettings = machine.GetExtraData(VBoxDefs::GUI_FirstRun);
+        if (strSettings == "yes")
+            m_bIsFirstTimeStarted = true;
+
+        strSettings = machine.GetExtraData(VBoxDefs::GUI_SaveMountedAtRuntime);
+        if (strSettings == "no")
+            m_bIsAutoSaveMedia = false;
+    }
+
+    /* Initial settings */
+    {
+        /* Initialize storage stuff: */
+        int iDevicesCountCD = 0;
+        int iDevicesCountFD = 0;
+        const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
+        foreach (const CMediumAttachment &attachment, attachments)
+        {
+            if (attachment.GetType() == KDeviceType_DVD)
+                ++ iDevicesCountCD;
+            if (attachment.GetType() == KDeviceType_Floppy)
+                ++ iDevicesCountFD;
+        }
+        actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->setData(iDevicesCountCD);
+        actionsPool()->action(UIActionIndex_Menu_FloppyDevices)->setData(iDevicesCountFD);
+        actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->setVisible(iDevicesCountCD);
+        actionsPool()->action(UIActionIndex_Menu_FloppyDevices)->setVisible(iDevicesCountFD);
+    }
+
+    /* Availability settings */
+    {
+        /* USB Stuff: */
+        CUSBController usbController = machine.GetUSBController();
+        if (usbController.isNull())
+        {
+            /* Hide USB_Menu: */
+            actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu()->setVisible(false);
+        }
+        else
+        {
+            /* Enable/Disable USB_Menu: */
+            actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu()->setEnabled(usbController.GetEnabled());
+        }
+
+        /* VRDP Stuff: */
+        CVRDPServer vrdpServer = machine.GetVRDPServer();
+        if (vrdpServer.isNull())
+        {
+            /* Hide VRDP Action: */
+            actionsPool()->action(UIActionIndex_Toggle_VRDP)->setVisible(false);
+        }
+    }
+}
+
+void UIMachineLogic::saveLogicSettings()
+{
+    CMachine machine = session().GetMachine();
+
+    /* Extra-data settings */
+    {
+        machine.SetExtraData(VBoxDefs::GUI_AutoresizeGuest,
+                             actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize)->isChecked() ? "on" : "off");
+
+        machine.SetExtraData(VBoxDefs::GUI_FirstRun, QString());
+
+        // TODO: Move to fullscreen/seamless logic:
+        //machine.SetExtraData(VBoxDefs::GUI_MiniToolBarAutoHide, mMiniToolBar->isAutoHide() ? "on" : "off");
+    }
+}
+
+bool UIMachineLogic::pause(bool bOn)
+{
+    if (isPaused() == bOn)
+        return true;
+
+    CConsole console = session().GetConsole();
+
+    if (bOn)
+        console.Pause();
+    else
+        console.Resume();
+
+    bool ok = console.isOk();
+    if (!ok)
+    {
+        if (bOn)
+            vboxProblem().cannotPauseMachine(console);
+        else
+            vboxProblem().cannotResumeMachine(console);
+    }
+
+    return ok;
+}
+
+void UIMachineLogic::installGuestAdditionsFrom(const QString &strSource)
+{
+    CMachine machine = session().GetMachine();
+    CVirtualBox vbox = vboxGlobal().virtualBox();
+    QString strUuid;
+
+    CMedium image = vbox.FindDVDImage(strSource);
+    if (image.isNull())
+    {
+        image = vbox.OpenDVDImage(strSource, strUuid);
+        if (vbox.isOk())
+            strUuid = image.GetId();
+    }
+    else
+        strUuid = image.GetId();
+
+    if (!vbox.isOk())
+    {
+        vboxProblem().cannotOpenMedium(machineWindowWrapper()->machineWindow(), vbox, VBoxDefs::MediumType_DVD, strSource);
+        return;
+    }
+
+    AssertMsg(!strUuid.isNull(), ("Guest Additions image UUID should be valid!\n"));
+
+    QString strCntName;
+    LONG iCntPort = -1, iCntDevice = -1;
+    /* Searching for the first suitable slot */
+    {
+        CStorageControllerVector controllers = machine.GetStorageControllers();
+        int i = 0;
+        while (i < controllers.size() && strCntName.isNull())
+        {
+            CStorageController controller = controllers[i];
+            CMediumAttachmentVector attachments = machine.GetMediumAttachmentsOfController(controller.GetName());
+            int j = 0;
+            while (j < attachments.size() && strCntName.isNull())
+            {
+                CMediumAttachment attachment = attachments[j];
+                if (attachment.GetType() == KDeviceType_DVD)
+                {
+                    strCntName = controller.GetName();
+                    iCntPort = attachment.GetPort();
+                    iCntDevice = attachment.GetDevice();
+                }
+                ++ j;
+            }
+            ++ i;
+        }
+    }
+
+    if (!strCntName.isNull())
+    {
+        bool isMounted = false;
+
+        /* Mount medium to the predefined port/device */
+        machine.MountMedium(strCntName, iCntPort, iCntDevice, strUuid, false /* force */);
+        if (machine.isOk())
+            isMounted = true;
+        else
+        {
+            /* Ask for force mounting */
+            if (vboxProblem().cannotRemountMedium(machineWindowWrapper()->machineWindow(), machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
+                                                  true /* mount? */, true /* retry? */) == QIMessageBox::Ok)
+            {
+                /* Force mount medium to the predefined port/device */
+                machine.MountMedium(strCntName, iCntPort, iCntDevice, strUuid, true /* force */);
+                if (machine.isOk())
+                    isMounted = true;
+                else
+                    vboxProblem().cannotRemountMedium(machineWindowWrapper()->machineWindow(), machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
+                                                      true /* mount? */, false /* retry? */);
+            }
+        }
+
+        /* Save medium mounted at runtime */
+        if (isMounted && m_bIsAutoSaveMedia)
+        {
+            machine.SaveSettings();
+            if (!machine.isOk())
+                vboxProblem().cannotSaveMachineSettings(machine);
+        }
+    }
+    else
+        vboxProblem().cannotMountGuestAdditions(machine.GetName());
+}
+
+int UIMachineLogic::searchMaxSnapshotIndex(const CMachine &machine,
+                                           const CSnapshot &snapshot,
+                                           const QString &strNameTemplate)
+{
+    int iMaxIndex = 0;
+    QRegExp regExp(QString("^") + strNameTemplate.arg("([0-9]+)") + QString("$"));
+    if (!snapshot.isNull())
+    {
+        /* Check the current snapshot name */
+        QString strName = snapshot.GetName();
+        int iPos = regExp.indexIn(strName);
+        if (iPos != -1)
+            iMaxIndex = regExp.cap(1).toInt() > iMaxIndex ? regExp.cap(1).toInt() : iMaxIndex;
+        /* Traversing all the snapshot children */
+        foreach (const CSnapshot &child, snapshot.GetChildren())
+        {
+            int iMaxIndexOfChildren = searchMaxSnapshotIndex(machine, child, strNameTemplate);
+            iMaxIndex = iMaxIndexOfChildren > iMaxIndex ? iMaxIndexOfChildren : iMaxIndex;
+        }
+    }
+    return iMaxIndex;
+}
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+bool UIMachineLogic::dbgCreated()
+{
+    if (m_dbgGui)
+        return true;
+
+    RTLDRMOD hLdrMod = vboxGlobal().getDebuggerModule();
+    if (hLdrMod == NIL_RTLDRMOD)
+        return false;
+
+    PFNDBGGUICREATE pfnGuiCreate;
+    int rc = RTLdrGetSymbol (hLdrMod, "DBGGuiCreate", (void**) &pfnGuiCreate);
+    if (RT_SUCCESS (rc))
+    {
+        ISession *pISession = session().raw();
+        rc = pfnGuiCreate (pISession, &m_dbgGui, &m_dbgGuiVT);
+        if (RT_SUCCESS (rc))
+        {
+            if (DBGGUIVT_ARE_VERSIONS_COMPATIBLE (m_dbgGuiVT->u32Version, DBGGUIVT_VERSION) ||
+                m_dbgGuiVT->u32EndVersion == m_dbgGuiVT->u32Version)
+            {
+                m_dbgGuiVT->pfnSetParent (m_dbgGui, (QWidget*) machineWindowWrapper());
+                m_dbgGuiVT->pfnSetMenu (m_dbgGui, (QMenu*) actionsPool()->action(UIActionIndex_Menu_Debug));
+                dbgAdjustRelativePos();
+                return true;
+            }
+
+            LogRel (("DBGGuiCreate failed, incompatible versions (loaded %#x/%#x, expected %#x)\n",
+                     m_dbgGuiVT->u32Version, m_dbgGuiVT->u32EndVersion, DBGGUIVT_VERSION));
+        }
+        else
+            LogRel (("DBGGuiCreate failed, rc=%Rrc\n", rc));
+    }
+    else
+        LogRel (("RTLdrGetSymbol(,\"DBGGuiCreate\",) -> %Rrc\n", rc));
+
+    m_dbgGui = 0;
+    m_dbgGuiVT = 0;
+    return false;
+}
+
+void UIMachineLogic::dbgDestroy()
+{
+    if (m_dbgGui)
+    {
+        m_dbgGuiVT->pfnDestroy(m_dbgGui);
+        m_dbgGui = 0;
+        m_dbgGuiVT = 0;
+    }
+}
+
+void UIMachineLogic::dbgAdjustRelativePos()
+{
+    if (m_dbgGui)
+    {
+        QRect rct = machineWindowWrapper()->machineWindow()->frameGeometry();
+        m_dbgGuiVT->pfnAdjustRelativePos(m_dbgGui, rct.x(), rct.y(), rct.width(), rct.height());
+    }
+}
+#endif
+
+#if 0 // TODO: Where to move that?
+# ifdef Q_WS_MAC
+void UIMachineLogic::fadeToBlack()
+{
+    /* Fade to black */
+    CGAcquireDisplayFadeReservation (kCGMaxDisplayReservationInterval, &mFadeToken);
+    CGDisplayFade (mFadeToken, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true);
+}
+void UIMachineLogic::fadeToNormal()
+{
+    /* Fade back to the normal gamma */
+    CGDisplayFade (mFadeToken, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false);
+    CGReleaseDisplayFadeReservation (mFadeToken);
+    mConsole->setMouseCoalescingEnabled (true);
+}
+# endif
+bool UIMachineLogic::toggleFullscreenMode (bool aOn, bool aSeamless)
+{
+    /* Please note: For some platforms like the Mac, the calling order of the
+     * functions in this methods is vital. So please be careful on changing
+     * this. */
+
+    QSize initialSize = size();
+    if (aSeamless || mConsole->isAutoresizeGuestActive())
+    {
+        QRect screen = aSeamless ?
+            QApplication::desktop()->availableGeometry (this) :
+            QApplication::desktop()->screenGeometry (this);
+        ULONG64 availBits = mSession.GetMachine().GetVRAMSize() /* vram */
+                          * _1M /* mb to bytes */
+                          * 8; /* to bits */
+        ULONG guestBpp = mConsole->console().GetDisplay().GetBitsPerPixel();
+        ULONG64 usedBits = (screen.width() /* display width */
+                         * screen.height() /* display height */
+                         * guestBpp
+                         + _1M * 8) /* current cache per screen - may be changed in future */
+                         * mSession.GetMachine().GetMonitorCount() /**< @todo fix assumption that all screens have same resolution */
+                         + 4096 * 8; /* adapter info */
+        if (aOn && (availBits < usedBits))
+        {
+            if (aSeamless)
+            {
+                vboxProblem().cannotEnterSeamlessMode (
+                    screen.width(), screen.height(), guestBpp,
+                    (((usedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
+                return false;
+            }
+            else
+            {
+                int result = vboxProblem().cannotEnterFullscreenMode (
+                    screen.width(), screen.height(), guestBpp,
+                    (((usedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
+                if (result == QIMessageBox::Cancel)
+                    return false;
+            }
+        }
+    }
+
+    AssertReturn (mConsole, false);
+    AssertReturn ((mHiddenChildren.empty() == aOn), false);
+    AssertReturn ((aSeamless && mIsSeamless != aOn) ||
+                  (!aSeamless && mIsFullscreen != aOn), false);
+    if (aOn)
+        AssertReturn ((aSeamless && !mIsFullscreen) ||
+                      (!aSeamless && !mIsSeamless), false);
+
+    if (aOn)
+    {
+        /* Take the toggle hot key from the menu item. Since
+         * VBoxGlobal::extractKeyFromActionText gets exactly the
+         * linked key without the 'Host+' part we are adding it here. */
+        QString hotKey = QString ("Host+%1")
+            .arg (VBoxGlobal::extractKeyFromActionText (aSeamless ?
+                  mVmSeamlessAction->text() : mVmFullscreenAction->text()));
+
+        Assert (!hotKey.isEmpty());
+
+        /* Show the info message. */
+        bool ok = aSeamless ?
+            vboxProblem().confirmGoingSeamless (hotKey) :
+            vboxProblem().confirmGoingFullscreen (hotKey);
+        if (!ok)
+            return false;
+    }
+
+#ifdef Q_WS_MAC
+    if (!aSeamless)
+    {
+    }
+#endif
+
+    if (aSeamless)
+    {
+        /* Activate the auto-resize feature required for the seamless mode. */
+        if (!mVmAutoresizeGuestAction->isChecked())
+            mVmAutoresizeGuestAction->setChecked (true);
+
+        /* Activate the mouse integration feature for the seamless mode. */
+        if (mVmDisableMouseIntegrAction->isChecked())
+            mVmDisableMouseIntegrAction->setChecked (false);
+
+        mVmAdjustWindowAction->setEnabled (!aOn);
+        mVmFullscreenAction->setEnabled (!aOn);
+        mVmAutoresizeGuestAction->setEnabled (!aOn);
+        mVmDisableMouseIntegrAction->setEnabled (!aOn);
+
+        mConsole->console().GetDisplay().SetSeamlessMode (aOn);
+        mIsSeamless = aOn;
+    }
+    else
+    {
+        mIsFullscreen = aOn;
+        mVmAdjustWindowAction->setEnabled (!aOn);
+        mVmSeamlessAction->setEnabled (!aOn && m_bIsSeamlessSupported && m_bIsGraphicsSupported);
+    }
+
+    bool wasHidden = isHidden();
+
+    /* Temporarily disable the mode-related action to make sure
+     * user can not leave the mode before he enter it and inside out. */
+    aSeamless ? mVmSeamlessAction->setEnabled (false) :
+                mVmFullscreenAction->setEnabled (false);
+
+    /* Calculate initial console size */
+    QSize consoleSize;
+
+    if (aOn)
+    {
+        consoleSize = mConsole->frameSize();
+        consoleSize -= QSize (mConsole->frameWidth() * 2, mConsole->frameWidth() * 2);
+
+        /* Toggle console to manual resize mode. */
+        mConsole->setIgnoreMainwndResize (true);
+
+        /* Memorize the maximized state. */
+        QDesktopWidget *dtw = QApplication::desktop();
+        mWasMax = isWindowMaximized() &&
+                  dtw->availableGeometry().width()  == frameSize().width() &&
+                  dtw->availableGeometry().height() == frameSize().height();
+
+        /* Save the previous scroll-view minimum size before entering
+         * fullscreen/seamless state to restore this minimum size before
+         * the exiting fullscreen. Required for correct scroll-view and
+         * guest display update in SDL mode. */
+        mPrevMinSize = mConsole->minimumSize();
+        mConsole->setMinimumSize (0, 0);
+
+        /* let the widget take the whole available desktop space */
+        QRect scrGeo = aSeamless ?
+            dtw->availableGeometry (this) : dtw->screenGeometry (this);
+
+        /* It isn't guaranteed that the guest os set the video mode that
+         * we requested. So after all the resizing stuff set the clipping
+         * mask and the spacing shifter to the corresponding values. */
+        if (aSeamless)
+            setViewInSeamlessMode (scrGeo);
+
+#ifdef Q_WS_WIN
+        mPrevRegion = dtw->screenGeometry (this);
+#endif
+
+        /* Hide all but the central widget containing the console view. */
+        QList <QWidget*> list (findChildren <QWidget*> ());
+        QList <QWidget*> excludes;
+        excludes << centralWidget() << centralWidget()->findChildren <QWidget*> ();
+        foreach (QWidget *w, list)
+        {
+            if (!excludes.contains (w))
+            {
+                if (!w->isHidden())
+                {
+                    w->hide();
+                    mHiddenChildren.append (w);
+                }
+            }
+        }
+
+        /* Adjust colors and appearance. */
+        mErasePalette = centralWidget()->palette();
+        QPalette palette(mErasePalette);
+        palette.setColor (centralWidget()->backgroundRole(), Qt::black);
+        centralWidget()->setPalette (palette);
+        centralWidget()->setAutoFillBackground (!aSeamless);
+        mConsoleStyle = mConsole->frameStyle();
+        mConsole->setFrameStyle (QFrame::NoFrame);
+        mConsole->setMaximumSize (scrGeo.size());
+        mConsole->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
+        mConsole->setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
+    }
+    else
+    {
+        /* Reset the shifting spacers. */
+        mShiftingSpacerLeft->changeSize (0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+        mShiftingSpacerTop->changeSize (0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+        mShiftingSpacerRight->changeSize (0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+        mShiftingSpacerBottom->changeSize (0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+        /* Restore the previous scroll-view minimum size before the exiting
+         * fullscreen. Required for correct scroll-view and guest display
+         * update in SDL mode. */
+        mConsole->setMinimumSize (mPrevMinSize);
+
+#ifdef Q_WS_MAC
+        if (aSeamless)
+        {
+            /* Please note: All the stuff below has to be done before the
+             * window switch back to normal size. Qt changes the winId on the
+             * fullscreen switch and make this stuff useless with the old
+             * winId. So please be careful on rearrangement of the method
+             * calls. */
+            /* Undo all mac specific installations */
+            ::darwinSetShowsWindowTransparent (this, false);
+        }
+#endif
+
+        /* Adjust colors and appearance. */
+        clearMask();
+        centralWidget()->setPalette (mErasePalette);
+        centralWidget()->setAutoFillBackground (false);
+        mConsole->setFrameStyle (mConsoleStyle);
+        mConsole->setMaximumSize (mConsole->sizeHint());
+        mConsole->setHorizontalScrollBarPolicy (Qt::ScrollBarAsNeeded);
+        mConsole->setVerticalScrollBarPolicy (Qt::ScrollBarAsNeeded);
+
+        /* Show everything hidden when going fullscreen. */
+        foreach (QPointer <QWidget> child, mHiddenChildren)
+            if (child) child->show();
+        mHiddenChildren.clear();
+    }
+
+    /* Set flag for waiting host resize if it awaited during mode entering */
+    if ((mIsFullscreen || mIsSeamless) && (consoleSize != initialSize))
+        mIsWaitingModeResize = true;
+
+    if (!aOn)
+    {
+        /* Animation takes a bit long, the mini toolbar is still disappearing
+         * when switched to normal mode so hide it completely */
+        mMiniToolBar->hide();
+        mMiniToolBar->updateDisplay (false, true);
+    }
+
+    /* Toggle qt full-screen mode */
+    switchToFullscreen (aOn, aSeamless);
+
+    if (aOn)
+    {
+        mMiniToolBar->setSeamlessMode (aSeamless);
+        mMiniToolBar->updateDisplay (true, true);
+    }
+
+#ifdef Q_WS_MAC
+    if (aOn && aSeamless)
+    {
+        /* Please note: All the stuff below has to be done after the window has
+         * switched to fullscreen. Qt changes the winId on the fullscreen
+         * switch and make this stuff useless with the old winId. So please be
+         * careful on rearrangement of the method calls. */
+        ::darwinSetShowsWindowTransparent (this, true);
+    }
+#endif
+
+    /* Send guest size hint */
+    mConsole->toggleFSMode (consoleSize);
+
+    /* Process all console attributes changes and sub-widget hidings */
+    qApp->processEvents();
+
+    if (!mIsWaitingModeResize)
+        onExitFullscreen();
+
+    /* Unlock FS actions locked during modes toggling */
+    QTimer::singleShot (300, this, SLOT (unlockActionsSwitch()));
+
+#ifdef Q_WS_MAC /* wasHidden is wrong on the mac it seems. */
+    /** @todo figure out what is really wrong here... */
+    if (!wasHidden)
+        show();
+#else
+    if (wasHidden)
+        hide();
+#endif
+    return true;
+}
+void UIMachineLogic::switchToFullscreen (bool aOn, bool aSeamless)
+{
+#ifdef Q_WS_MAC
+# ifndef QT_MAC_USE_COCOA
+    /* setWindowState removes the window group connection somehow. So save it
+     * temporary. */
+    WindowGroupRef g = GetWindowGroup (::darwinToNativeWindow (this));
+# endif  /* !QT_MAC_USE_COCOA */
+    if (aSeamless)
+        if (aOn)
+        {
+            /* Save for later restoring */
+            mNormalGeometry = geometry();
+            mSavedFlags = windowFlags();
+            /* Remove the frame from the window */
+            const QRect fullscreen (qApp->desktop()->screenGeometry (qApp->desktop()->screenNumber (this)));
+            setParent (0, Qt::Window | Qt::FramelessWindowHint | (windowFlags() & 0xffff0000));
+            setGeometry (fullscreen);
+            /* Set it maximized */
+            setWindowState (windowState() ^ Qt::WindowMaximized);
+        }
+        else
+        {
+            /* Restore old values */
+            setParent (0, mSavedFlags);
+            setGeometry (mNormalGeometry);
+        }
+    else
+    {
+        /* Here we are going really fullscreen */
+        setWindowState (windowState() ^ Qt::WindowFullScreen);
+        sltChangePresentationMode (VBoxChangePresentationModeEvent(aOn));
+    }
+
+# ifndef QT_MAC_USE_COCOA
+    /* Reassign the correct window group. */
+    SetWindowGroup (::darwinToNativeWindow (this), g);
+# endif /* !QT_MAC_USE_COCOA */
+#else
+    NOREF (aOn);
+    NOREF (aSeamless);
+    setWindowState (windowState() ^ Qt::WindowFullScreen);
+#endif
+}
+void UIMachineLogic::setViewInSeamlessMode (const QRect &aTargetRect)
+{
+#ifndef Q_WS_MAC
+    /* It isn't guaranteed that the guest os set the video mode that
+     * we requested. So after all the resizing stuff set the clipping
+     * mask and the spacing shifter to the corresponding values. */
+    QDesktopWidget *dtw = QApplication::desktop();
+    QRect sRect = dtw->screenGeometry (this);
+    QRect aRect (aTargetRect);
+    mMaskShift.scale (aTargetRect.left(), aTargetRect.top(), Qt::IgnoreAspectRatio);
+    /* Set the clipping mask */
+    mStrictedRegion = aRect;
+    /* Set the shifting spacer */
+    mShiftingSpacerLeft->changeSize (RT_ABS (sRect.left() - aRect.left()), 0,
+                                     QSizePolicy::Fixed, QSizePolicy::Preferred);
+    mShiftingSpacerTop->changeSize (0, RT_ABS (sRect.top() - aRect.top()),
+                                    QSizePolicy::Preferred, QSizePolicy::Fixed);
+    mShiftingSpacerRight->changeSize (RT_ABS (sRect.right() - aRect.right()), 0,
+                                      QSizePolicy::Fixed, QSizePolicy::Preferred);
+    mShiftingSpacerBottom->changeSize (0, RT_ABS (sRect.bottom() - aRect.bottom()),
+                                           QSizePolicy::Preferred, QSizePolicy::Fixed);
+#else // !Q_WS_MAC
+    NOREF (aTargetRect);
+#endif // !Q_WS_MAC
+}
+#endif
+
+#include "UIMachineLogic.moc"
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h	(revision 26637)
@@ -0,0 +1,185 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineLogic class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIMachineLogic_h__
+#define __UIMachineLogic_h__
+
+/* Local includes */
+#include "COMDefs.h"
+#include "UIMachineDefs.h"
+#ifdef VBOX_WITH_DEBUGGER_GUI
+# include <VBox/dbggui.h>
+#endif
+
+/* Global forwards */
+class QActionGroup;
+
+/* Local forwards */
+class UIActionsPool;
+class UIMachineWindow;
+
+class UIMachineLogic : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    /* Factory function to create required logic sub-child: */
+    static UIMachineLogic* create(QObject *pParent,
+                                  const CSession &session,
+                                  UIActionsPool *pActionsPool,
+                                  UIVisualStateType visualStateType);
+
+    /* Public getters: */
+    CSession& session() { return m_session; }
+    UIActionsPool* actionsPool() { return m_pActionsPool; }
+    KMachineState machineState() const { return m_machineState; }
+    UIVisualStateType visualStateType() const { return m_visualStateType; }
+    bool isPaused() const { return m_machineState == KMachineState_Paused || m_machineState == KMachineState_TeleportingPausedVM; }
+
+    /* Public setters: */
+    bool pause(bool bPaused);
+
+protected:
+
+    /* Common machine logic constructor: */
+    UIMachineLogic(QObject *pParent,
+                   const CSession &session,
+                   UIActionsPool *pActionsPool,
+                   UIVisualStateType visualStateType);
+    /* Common machine logic destructor: */
+    virtual ~UIMachineLogic();
+
+    /* Update routines: */
+    virtual void updateAppearanceOf(int iElement);
+
+    /* Protected getters: */
+    UIMachineWindow* machineWindowWrapper() { return m_pMachineWindowContainer; }
+    bool isFirstTimeStarted() const { return m_bIsFirstTimeStarted; }
+    bool isPreventAutoClose() const { return m_bIsPreventAutoClose; }
+
+    /* Pretected setters: */
+    void setMachineState(KMachineState state) { m_machineState = state; }
+    void setPreventAutoClose(bool bIsPreventAutoClose) { m_bIsPreventAutoClose = bIsPreventAutoClose; }
+    void setOpenViewFinished(bool bIsOpenViewFinished) { m_bIsOpenViewFinished = bIsOpenViewFinished; }
+
+    /* Protected variables: */
+    UIMachineWindow *m_pMachineWindowContainer;
+
+private slots:
+
+    /* "Machine" menu funtionality */
+    void sltAdjustWindow();
+    void sltToggleMouseIntegration(bool bOff);
+    void sltTypeCAD();
+#ifdef Q_WS_X11
+    void sltTypeCABS();
+#endif
+    void sltTakeSnapshot();
+    void sltShowInformationDialog();
+    void sltReset();
+    void sltPause(bool aOn);
+    void sltACPIShutdown();
+    void sltClose();
+
+    /* "Device" menu funtionality */
+    void sltPrepareStorageMenu();
+    void sltMountStorageMedium();
+    void sltOpenNetworkAdaptersDialog();
+    void sltOpenSharedFoldersDialog();
+    void sltPrepareUSBMenu();
+    void sltAttachUSBDevice();
+    void sltSwitchVrdp(bool bOn);
+    void sltInstallGuestAdditions();
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    void sltPrepareDebugMenu();
+    void sltShowDebugStatistics();
+    void sltShowDebugCommandLine();
+    void sltLoggingToggled(bool);
+#endif
+
+    /* Machine state change handler */
+    void sltUpdateMachineState(KMachineState machineState);
+    /* Guest Additions state change handler */
+    void sltUpdateAdditionsState(const QString &strVersion, bool bActive, bool bSeamlessSupported, bool bGraphicsSupported);
+    /* Mouse Integration state change handler */
+    void sltUpdateMouseState(int iState);
+
+private:
+
+    /* Prepare helpers: */
+    void prepareActionGroups();
+    void prepareActionConnections();
+    void prepareRequiredFeatures();
+    void loadLogicSettings();
+
+    /* Cleanup helpers: */
+    void saveLogicSettings();
+    //void cleanupRequiredFeatures();
+    //void cleanupActionConnections();
+    //void cleanupActionGroups();
+
+    /* Utility functions: */
+    void installGuestAdditionsFrom(const QString &strSource);
+    static int searchMaxSnapshotIndex(const CMachine &machine, const CSnapshot &snapshot, const QString &strNameTemplate);
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    bool dbgCreated();
+    void dbgDestroy();
+    void dbgAdjustRelativePos();
+#endif
+
+#if 0 // TODO: Where to move that?
+# ifdef Q_WS_MAC
+    void fadeToBlack();
+    void fadeToNormal();
+# endif
+    bool toggleFullscreenMode(bool aOn, bool aSeamless);
+    void switchToFullscreen(bool aOn, bool aSeamless);
+    void setViewInSeamlessMode(const QRect &aTargetRect);
+#endif
+
+    /* Private variables: */
+    CSession m_session;
+    UIActionsPool *m_pActionsPool;
+    KMachineState m_machineState;
+    UIVisualStateType m_visualStateType;
+
+    QActionGroup *m_pRunningActions;
+    QActionGroup *m_pRunningOrPausedActions;
+
+    bool m_bIsFirstTimeStarted : 1;
+    bool m_bIsOpenViewFinished : 1;
+    bool m_bIsGraphicsSupported : 1;
+    bool m_bIsSeamlessSupported : 1;
+    bool m_bIsAutoSaveMedia : 1;
+    bool m_bIsPreventAutoClose : 1;
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    /* The handle to the debugger gui: */
+    PDBGGUI m_dbgGui;
+    /* The virtual method table for the debugger GUI: */
+    PCDBGGUIVT m_dbgGuiVT;
+#endif
+};
+
+#endif // __UIMachineLogic_h__
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 26637)
@@ -0,0 +1,3818 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineView class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Global includes */
+#include <QDesktopWidget>
+#include <QTimer>
+#include <QPainter>
+#include <QScrollBar>
+#include <VBox/VBoxVideo.h>
+
+/* Local includes */
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+#include "UIFrameBuffer.h"
+#include "UIActionsPool.h"
+#include "UIMachineLogic.h"
+#include "UIMachineWindow.h"
+#include "UIMachineView.h"
+#include "UIMachineViewNormal.h"
+
+#ifdef Q_WS_PM
+# include "QIHotKeyEdit.h"
+#endif
+
+#ifdef Q_WS_WIN
+#undef LOWORD
+#undef HIWORD
+#undef LOBYTE
+#undef HIBYTE
+#include <windows.h>
+#endif
+
+#ifdef Q_WS_X11
+# include <QX11Info>
+# define XK_XKB_KEYS
+# define XK_MISCELLANY
+# include <X11/XKBlib.h>
+# include <X11/keysym.h>
+# ifdef KeyPress
+const int XFocusOut = FocusOut;
+const int XFocusIn = FocusIn;
+const int XKeyPress = KeyPress;
+const int XKeyRelease = KeyRelease;
+#  undef KeyRelease
+#  undef KeyPress
+#  undef FocusOut
+#  undef FocusIn
+# endif
+# include "XKeyboard.h"
+# ifndef VBOX_WITHOUT_XCURSOR
+#  include <X11/Xcursor/Xcursor.h>
+# endif
+#endif
+
+#if defined (Q_WS_MAC)
+# include "DockIconPreview.h"
+# include "DarwinKeyboard.h"
+# ifdef QT_MAC_USE_COCOA
+#  include "darwin/VBoxCocoaApplication.h"
+# elif defined(VBOX_WITH_HACKED_QT)
+#  include "QIApplication.h"
+# endif
+# include <Carbon/Carbon.h>
+# include <VBox/err.h>
+#endif /* defined (Q_WS_MAC) */
+
+/** Guest mouse pointer shape change event. */
+class MousePointerChangeEvent : public QEvent
+{
+public:
+
+    MousePointerChangeEvent (bool visible, bool alpha, uint xhot, uint yhot, uint width, uint height, const uchar *shape)
+        : QEvent((QEvent::Type)VBoxDefs::MousePointerChangeEventType)
+        , vis(visible), alph(alpha), xh(xhot), yh(yhot), w(width), h(height), data(0)
+    {
+        uint dataSize = ((((width + 7) / 8 * height) + 3) & ~3) + width * 4 * height;
+
+        if (shape)
+        {
+            data = new uchar[dataSize];
+            memcpy((void*)data, (void*)shape, dataSize);
+        }
+    }
+
+    ~MousePointerChangeEvent()
+    {
+        if (data) delete[] data;
+    }
+
+    bool isVisible() const { return vis; }
+    bool hasAlpha() const { return alph; }
+    uint xHot() const { return xh; }
+    uint yHot() const { return yh; }
+    uint width() const { return w; }
+    uint height() const { return h; }
+    const uchar *shapeData() const { return data; }
+
+private:
+
+    bool vis, alph;
+    uint xh, yh, w, h;
+    const uchar *data;
+};
+
+/** Guest mouse absolute positioning capability change event. */
+class MouseCapabilityEvent : public QEvent
+{
+public:
+
+    MouseCapabilityEvent (bool supportsAbsolute, bool needsHostCursor)
+        : QEvent((QEvent::Type) VBoxDefs::MouseCapabilityEventType)
+        , can_abs(supportsAbsolute), needs_host_cursor(needsHostCursor) {}
+
+    bool supportsAbsolute() const { return can_abs; }
+    bool needsHostCursor() const { return needs_host_cursor; }
+
+private:
+
+    bool can_abs;
+    bool needs_host_cursor;
+};
+
+/** Machine state change. */
+class StateChangeEvent : public QEvent
+{
+public:
+
+    StateChangeEvent (KMachineState state)
+        : QEvent((QEvent::Type)VBoxDefs::MachineStateChangeEventType)
+        , s (state) {}
+
+    KMachineState machineState() const { return s; }
+
+private:
+
+    KMachineState s;
+};
+
+/** Guest Additions property changes. */
+class GuestAdditionsEvent : public QEvent
+{
+public:
+
+    GuestAdditionsEvent (const QString &aOsTypeId,
+                         const QString &aAddVersion,
+                         bool aAddActive,
+                         bool aSupportsSeamless,
+                         bool aSupportsGraphics)
+        : QEvent((QEvent::Type)VBoxDefs::AdditionsStateChangeEventType)
+        , mOsTypeId(aOsTypeId), mAddVersion(aAddVersion)
+        , mAddActive(aAddActive), mSupportsSeamless(aSupportsSeamless)
+        , mSupportsGraphics (aSupportsGraphics) {}
+
+    const QString &osTypeId() const { return mOsTypeId; }
+    const QString &additionVersion() const { return mAddVersion; }
+    bool additionActive() const { return mAddActive; }
+    bool supportsSeamless() const { return mSupportsSeamless; }
+    bool supportsGraphics() const { return mSupportsGraphics; }
+
+private:
+
+    QString mOsTypeId;
+    QString mAddVersion;
+    bool mAddActive;
+    bool mSupportsSeamless;
+    bool mSupportsGraphics;
+};
+
+/** DVD/Floppy drive change event */
+class MediaDriveChangeEvent : public QEvent
+{
+public:
+
+    MediaDriveChangeEvent(VBoxDefs::MediumType aType)
+        : QEvent ((QEvent::Type) VBoxDefs::MediaDriveChangeEventType)
+        , mType (aType) {}
+    VBoxDefs::MediumType type() const { return mType; }
+
+private:
+
+    VBoxDefs::MediumType mType;
+};
+
+/** Menu activation event */
+class ActivateMenuEvent : public QEvent
+{
+public:
+
+    ActivateMenuEvent (QAction *aData)
+        : QEvent((QEvent::Type)VBoxDefs::ActivateMenuEventType)
+        , mAction(aData) {}
+    QAction *action() const { return mAction; }
+
+private:
+
+    QAction *mAction;
+};
+
+/** VM Runtime error event */
+class RuntimeErrorEvent : public QEvent
+{
+public:
+
+    RuntimeErrorEvent(bool aFatal, const QString &aErrorID, const QString &aMessage)
+        : QEvent((QEvent::Type)VBoxDefs::RuntimeErrorEventType)
+        , mFatal(aFatal), mErrorID(aErrorID), mMessage(aMessage) {}
+
+    bool fatal() const { return mFatal; }
+    QString errorID() const { return mErrorID; }
+    QString message() const { return mMessage; }
+
+private:
+
+    bool mFatal;
+    QString mErrorID;
+    QString mMessage;
+};
+
+/** Modifier key change event */
+class ModifierKeyChangeEvent : public QEvent
+{
+public:
+
+    ModifierKeyChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
+        : QEvent((QEvent::Type)VBoxDefs::ModifierKeyChangeEventType)
+        , mNumLock(fNumLock), mCapsLock(fCapsLock), mScrollLock(fScrollLock) {}
+
+    bool numLock()    const { return mNumLock; }
+    bool capsLock()   const { return mCapsLock; }
+    bool scrollLock() const { return mScrollLock; }
+
+private:
+
+    bool mNumLock, mCapsLock, mScrollLock;
+};
+
+/** Network adapter change event */
+class NetworkAdapterChangeEvent : public QEvent
+{
+public:
+
+    NetworkAdapterChangeEvent(INetworkAdapter *aAdapter)
+        : QEvent((QEvent::Type)VBoxDefs::NetworkAdapterChangeEventType)
+        , mAdapter(aAdapter) {}
+
+    INetworkAdapter* networkAdapter() { return mAdapter; }
+
+private:
+
+    INetworkAdapter *mAdapter;
+};
+
+/** USB controller state change event */
+class USBControllerStateChangeEvent : public QEvent
+{
+public:
+
+    USBControllerStateChangeEvent()
+        : QEvent((QEvent::Type)VBoxDefs::USBCtlStateChangeEventType) {}
+};
+
+/** USB device state change event */
+class USBDeviceStateChangeEvent : public QEvent
+{
+public:
+
+    USBDeviceStateChangeEvent(const CUSBDevice &aDevice, bool aAttached, const CVirtualBoxErrorInfo &aError)
+        : QEvent((QEvent::Type)VBoxDefs::USBDeviceStateChangeEventType)
+        , mDevice(aDevice), mAttached(aAttached), mError(aError) {}
+
+    CUSBDevice device() const { return mDevice; }
+    bool attached() const { return mAttached; }
+    CVirtualBoxErrorInfo error() const { return mError; }
+
+private:
+
+    CUSBDevice mDevice;
+    bool mAttached;
+    CVirtualBoxErrorInfo mError;
+};
+
+class VBoxViewport: public QWidget
+{
+public:
+
+    VBoxViewport(QWidget *pParent) : QWidget(pParent)
+    {
+        /* No need for background drawing */
+        setAttribute(Qt::WA_OpaquePaintEvent);
+    }
+
+    QPaintEngine *paintEngine() const
+    {
+        if (testAttribute(Qt::WA_PaintOnScreen))
+            return NULL;
+        else
+            return QWidget::paintEngine();
+    }
+};
+
+class UIConsoleCallback : VBOX_SCRIPTABLE_IMPL(IConsoleCallback)
+{
+public:
+
+    UIConsoleCallback (UIMachineView *v)
+    {
+#if defined (Q_WS_WIN)
+        mRefCnt = 0;
+#endif
+        mView = v;
+    }
+
+    virtual ~UIConsoleCallback() {}
+
+    NS_DECL_ISUPPORTS
+
+#if defined (Q_WS_WIN)
+    STDMETHOD_(ULONG, AddRef)()
+    {
+        return ::InterlockedIncrement(&mRefCnt);
+    }
+    STDMETHOD_(ULONG, Release)()
+    {
+        long cnt = ::InterlockedDecrement(&mRefCnt);
+        if (cnt == 0)
+            delete this;
+        return cnt;
+    }
+#endif
+    VBOX_SCRIPTABLE_DISPATCH_IMPL(IConsoleCallback)
+
+    STDMETHOD(OnMousePointerShapeChange) (BOOL visible, BOOL alpha,
+                                          ULONG xhot, ULONG yhot,
+                                          ULONG width, ULONG height,
+                                          BYTE *shape)
+    {
+        QApplication::postEvent(mView, new MousePointerChangeEvent(visible, alpha, xhot, yhot, width, height, shape));
+        return S_OK;
+    }
+
+    STDMETHOD(OnMouseCapabilityChange)(BOOL supportsAbsolute, BOOL needsHostCursor)
+    {
+        QApplication::postEvent(mView, new MouseCapabilityEvent (supportsAbsolute, needsHostCursor));
+        return S_OK;
+    }
+
+    STDMETHOD(OnKeyboardLedsChange)(BOOL fNumLock, BOOL fCapsLock, BOOL fScrollLock)
+    {
+        QApplication::postEvent(mView, new ModifierKeyChangeEvent (fNumLock, fCapsLock, fScrollLock));
+        return S_OK;
+    }
+
+    STDMETHOD(OnStateChange)(MachineState_T machineState)
+    {
+        QApplication::postEvent(mView, new StateChangeEvent ((KMachineState) machineState));
+        return S_OK;
+    }
+
+    STDMETHOD(OnAdditionsStateChange)()
+    {
+        CGuest guest = mView->console().GetGuest();
+        QApplication::postEvent (mView, new GuestAdditionsEvent(guest.GetOSTypeId(), guest.GetAdditionsVersion(),
+                                                                guest.GetAdditionsActive(), guest.GetSupportsSeamless(),
+                                                                guest.GetSupportsGraphics()));
+        return S_OK;
+    }
+
+    STDMETHOD(OnNetworkAdapterChange) (INetworkAdapter *aNetworkAdapter)
+    {
+        QApplication::postEvent (mView, new NetworkAdapterChangeEvent (aNetworkAdapter));
+        return S_OK;
+    }
+
+    STDMETHOD(OnStorageControllerChange) ()
+    {
+        //QApplication::postEvent(mView, new StorageControllerChangeEvent());
+        return S_OK;
+    }
+
+    STDMETHOD(OnMediumChange)(IMediumAttachment *aMediumAttachment)
+    {
+        CMediumAttachment att(aMediumAttachment);
+        switch (att.GetType())
+        {
+            case KDeviceType_Floppy:
+                QApplication::postEvent(mView, new MediaDriveChangeEvent(VBoxDefs::MediumType_Floppy));
+                break;
+            case KDeviceType_DVD:
+                QApplication::postEvent(mView, new MediaDriveChangeEvent(VBoxDefs::MediumType_DVD));
+                break;
+            default:
+                break;
+        }
+        return S_OK;
+    }
+
+    STDMETHOD(OnCPUChange)(ULONG aCPU, BOOL aRemove)
+    {
+        NOREF(aCPU);
+        NOREF(aRemove);
+        return S_OK;
+    }
+
+    STDMETHOD(OnSerialPortChange) (ISerialPort *aSerialPort)
+    {
+        NOREF(aSerialPort);
+        return S_OK;
+    }
+
+    STDMETHOD(OnParallelPortChange) (IParallelPort *aParallelPort)
+    {
+        NOREF(aParallelPort);
+        return S_OK;
+    }
+
+    STDMETHOD(OnVRDPServerChange)()
+    {
+        return S_OK;
+    }
+
+    STDMETHOD(OnRemoteDisplayInfoChange)()
+    {
+        return S_OK;
+    }
+
+    STDMETHOD(OnUSBControllerChange)()
+    {
+        QApplication::postEvent (mView, new USBControllerStateChangeEvent());
+        return S_OK;
+    }
+
+    STDMETHOD(OnUSBDeviceStateChange)(IUSBDevice *aDevice, BOOL aAttached, IVirtualBoxErrorInfo *aError)
+    {
+        QApplication::postEvent (mView, new USBDeviceStateChangeEvent(CUSBDevice(aDevice), bool(aAttached), CVirtualBoxErrorInfo(aError)));
+        return S_OK;
+    }
+
+    STDMETHOD(OnSharedFolderChange) (Scope_T aScope)
+    {
+        NOREF(aScope);
+        QApplication::postEvent (mView, new QEvent((QEvent::Type)VBoxDefs::SharedFolderChangeEventType));
+        return S_OK;
+    }
+
+    STDMETHOD(OnRuntimeError)(BOOL fatal, IN_BSTR id, IN_BSTR message)
+    {
+        QApplication::postEvent (mView, new RuntimeErrorEvent(!!fatal, QString::fromUtf16(id), QString::fromUtf16(message)));
+        return S_OK;
+    }
+
+    STDMETHOD(OnCanShowWindow) (BOOL *canShow)
+    {
+        if (!canShow)
+            return E_POINTER;
+
+        *canShow = TRUE;
+        return S_OK;
+    }
+
+    STDMETHOD(OnShowWindow) (ULONG64 *winId)
+    {
+        if (!winId)
+            return E_POINTER;
+
+#if defined (Q_WS_MAC)
+        /*
+         * Let's try the simple approach first - grab the focus.
+         * Getting a window out of the dock (minimized or whatever it's called)
+         * needs to be done on the GUI thread, so post it a note.
+         */
+        *winId = 0;
+        if (!mView)
+            return S_OK;
+
+        ProcessSerialNumber psn = { 0, kCurrentProcess };
+        OSErr rc = ::SetFrontProcess (&psn);
+        if (!rc)
+            QApplication::postEvent(mView, new QEvent((QEvent::Type)VBoxDefs::ShowWindowEventType));
+        else
+        {
+            /*
+             * It failed for some reason, send the other process our PSN so it can try.
+             * (This is just a precaution should Mac OS X start imposing the same sensible
+             * focus stealing restrictions that other window managers implement.)
+             */
+            AssertMsgFailed(("SetFrontProcess -> %#x\n", rc));
+            if (::GetCurrentProcess (&psn))
+                *winId = RT_MAKE_U64(psn.lowLongOfPSN, psn.highLongOfPSN);
+        }
+
+#else
+        /* Return the ID of the top-level console window. */
+        *winId = (ULONG64)mView->window()->winId();
+#endif
+
+        return S_OK;
+    }
+
+protected:
+
+    UIMachineView *mView;
+
+#if defined (Q_WS_WIN)
+private:
+    long mRefCnt;
+#endif
+};
+
+#if !defined (Q_WS_WIN)
+NS_DECL_CLASSINFO(UIConsoleCallback)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI(UIConsoleCallback, IConsoleCallback)
+#endif
+
+UIMachineView* UIMachineView::create(  UIMachineWindow *pMachineWindow
+                                     , VBoxDefs::RenderMode renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                                     , bool bAccelerate2DVideo
+#endif
+                                     , UIVisualStateType visualStateType)
+{
+    UIMachineView *view = 0;
+    switch (visualStateType)
+    {
+        case UIVisualStateType_Normal:
+            view = new UIMachineViewNormal(  pMachineWindow
+                                           , renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                                           , bAccelerate2DVideo
+#endif
+                                          );
+            break;
+        case UIVisualStateType_Fullscreen:
+            view = new UIMachineViewNormal(  pMachineWindow
+                                           , renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                                           , bAccelerate2DVideo
+#endif
+                                          );
+            break;
+        case UIVisualStateType_Seamless:
+            view = new UIMachineViewNormal(  pMachineWindow
+                                           , renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                                           , bAccelerate2DVideo
+#endif
+                                          );
+            break;
+        default:
+            break;
+    }
+    return view;
+}
+
+void UIMachineView::onViewOpened()
+{
+    /* Variable m_bIsMachineWindowResizeIgnored was initially "true" to ignore QT
+     * initial resize event in case of auto-resize feature is on.
+     * Currently, initial resize event is already processed, so we set
+     * m_bIsMachineWindowResizeIgnored to "false" to process all further resize
+     * events as user-initiated window resize events. */
+    m_bIsMachineWindowResizeIgnored = false;
+}
+
+int UIMachineView::contentsX() const
+{
+    return horizontalScrollBar()->value();
+}
+
+int UIMachineView::contentsY() const
+{
+    return verticalScrollBar()->value();
+}
+
+QRect UIMachineView::desktopGeometry() const
+{
+    QRect rc;
+    switch (mDesktopGeo)
+    {
+        case DesktopGeo_Fixed:
+        case DesktopGeo_Automatic:
+            rc = QRect(0, 0,
+                       qMax(mDesktopGeometry.width(), mStoredConsoleSize.width()),
+                       qMax(mDesktopGeometry.height(), mStoredConsoleSize.height()));
+            break;
+        case DesktopGeo_Any:
+            rc = QRect(0, 0, 0, 0);
+            break;
+        default:
+            AssertMsgFailed(("Bad geometry type %d\n", mDesktopGeo));
+    }
+    return rc;
+}
+
+void UIMachineView::setIgnoreGuestResize(bool bIgnore)
+{
+    m_bIsGuestResizeIgnored = bIgnore;
+}
+
+void UIMachineView::setMouseIntegrationEnabled(bool bEnabled)
+{
+    if (m_bIsMouseIntegrated == bEnabled)
+        return;
+
+    if (m_bIsMouseAbsolute)
+        captureMouse(!bEnabled, false);
+
+    /* Hiding host cursor in case we are entering mouse integration
+     * mode until it's shape is set to the guest cursor shape in
+     * OnMousePointerShapeChange event handler.
+     *
+     * This is necessary to avoid double-cursor issues where both the
+     * guest and the host cursors are displayed in one place, one above the
+     * other.
+     *
+     * This is a workaround because the correct decision would be to notify
+     * the Guest Additions about we are entering the mouse integration
+     * mode. The GuestOS should hide it's cursor to allow using of
+     * host cursor for the guest's manipulation.
+     *
+     * This notification is not always possible though, as not all guests
+     * support switching to a hardware pointer on demand. */
+    if (bEnabled)
+        viewport()->setCursor(QCursor(Qt::BlankCursor));
+
+    m_bIsMouseIntegrated = bEnabled;
+
+    emitMouseStateChanged();
+}
+
+UIMachineView::UIMachineView(  UIMachineWindow *pMachineWindow
+                             , VBoxDefs::RenderMode renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                             , bool bAccelerate2DVideo
+#endif
+                            )
+    : QAbstractScrollArea(pMachineWindow->machineWindow())
+    /* Protected members: */
+    , mode(renderMode)
+    , m_bIsGuestSupportsGraphics(false)
+    /* Private members: */
+    , m_pMachineWindow(pMachineWindow)
+    , m_console(pMachineWindow->machineLogic()->session().GetConsole())
+    , m_globalSettings(vboxGlobal().settings())
+    , m_iLastMouseWheelDelta(0)
+    , muNumLockAdaptionCnt(2)
+    , muCapsLockAdaptionCnt(2)
+    , m_bIsAutoCaptureDisabled(false)
+    , m_bIsKeyboardCaptured(false)
+    , m_bIsMouseCaptured(false)
+    , m_bIsMouseAbsolute(false)
+    , m_bIsMouseIntegrated(true)
+    , m_bIsHostkeyPressed(false)
+    , m_bIsHostkeyAlone (false)
+    , m_bIsMachineWindowResizeIgnored(true)
+    , m_bIsFrameBufferResizeIgnored(false)
+    , m_bIsGuestResizeIgnored(false)
+    , mDoResize(false)
+    , mNumLock(false)
+    , mScrollLock(false)
+    , mCapsLock(false)
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    , mAccelerate2DVideo(bAccelerate2DVideo)
+#endif
+#if defined(Q_WS_WIN)
+    , mAlphaCursor (NULL)
+#endif
+#if defined(Q_WS_MAC)
+# if !defined (VBOX_WITH_HACKED_QT) && !defined (QT_MAC_USE_COCOA)
+    , mDarwinEventHandlerRef (NULL)
+# endif
+    , mDarwinKeyModifiers (0)
+    , mKeyboardGrabbed (false)
+    , mDockIconEnabled (true)
+#endif
+    , mDesktopGeo (DesktopGeo_Invalid)
+    , mPassCAD (false)
+      /* Don't show a hardware pointer until we have one to show */
+    , mHideHostPointer (true)
+{
+    Assert (!m_console.isNull() && !m_console.GetDisplay().isNull() && !m_console.GetKeyboard().isNull() && !m_console.GetMouse().isNull());
+
+#ifdef Q_WS_MAC
+    /* Overlay logo for the dock icon */
+    //mVirtualBoxLogo = ::darwinToCGImageRef("VirtualBox_cube_42px.png");
+    QString osTypeId = m_console.GetGuest().GetOSTypeId();
+    mDockIconPreview = new VBoxDockIconPreview(machineWindowWrapper(), vboxGlobal().vmGuestOSTypeIcon (osTypeId));
+
+# ifdef QT_MAC_USE_COCOA
+    /** @todo Carbon -> Cocoa */
+# else /* !QT_MAC_USE_COCOA */
+    /* Install the event handler which will proceed external window handling */
+    EventHandlerUPP eventHandler = ::NewEventHandlerUPP(::darwinOverlayWindowHandler);
+    EventTypeSpec eventTypes[] =
+    {
+        { kEventClassVBox, kEventVBoxShowWindow },
+        { kEventClassVBox, kEventVBoxHideWindow },
+        { kEventClassVBox, kEventVBoxMoveWindow },
+        { kEventClassVBox, kEventVBoxResizeWindow },
+        { kEventClassVBox, kEventVBoxDisposeWindow },
+        { kEventClassVBox, kEventVBoxUpdateDock }
+    };
+
+    mDarwinWindowOverlayHandlerRef = NULL;
+    ::InstallApplicationEventHandler(eventHandler, RT_ELEMENTS (eventTypes), &eventTypes[0], this, &mDarwinWindowOverlayHandlerRef);
+    ::DisposeEventHandlerUPP(eventHandler);
+# endif /* !QT_MAC_USE_COCOA */
+#endif /* QT_WS_MAC */
+
+    /* No frame around the view */
+    setFrameStyle(QFrame::NoFrame);
+
+#ifdef VBOX_GUI_USE_QGL
+    QWidget *pViewport;
+    switch (mode)
+    {
+        // TODO: Fix that!
+        //case VBoxDefs::QGLMode:
+        //    pViewport = new VBoxGLWidget(this, this, NULL);
+        //    break;
+        default:
+            pViewport = new VBoxViewport(this);
+    }
+#else
+    VBoxViewport *pViewport = new VBoxViewport(this);
+#endif
+    setViewport(pViewport);
+//    pViewport->vboxDoInit();
+
+    /* enable MouseMove events */
+    viewport()->setMouseTracking(true);
+
+    /*
+     *  QScrollView does the below on its own, but let's do it anyway
+     *  for the case it will not do it in the future.
+     */
+    viewport()->installEventFilter(this);
+
+    /* to fix some focus issues */
+    // TODO: Fix that!
+    //machineWindowWrapper()->menuBar()->installEventFilter(this);
+
+    /* we want to be notified on some parent's events */
+    machineWindowWrapper()->machineWindow()->installEventFilter(this);
+
+#ifdef Q_WS_X11
+    /* initialize the X keyboard subsystem */
+    initMappedX11Keyboard(QX11Info::display(), vboxGlobal().settings().publicProperty("GUI/RemapScancodes"));
+#endif
+
+    ::memset(mPressedKeys, 0, sizeof(mPressedKeys));
+
+    /* setup rendering */
+
+    CDisplay display = m_console.GetDisplay();
+    Assert(!display.isNull());
+
+    mFrameBuf = NULL;
+
+    LogFlowFunc(("Rendering mode: %d\n", mode));
+
+    switch (mode)
+    {
+#if defined (VBOX_GUI_USE_QGL)
+// TODO: Fix that!
+//        case VBoxDefs::QGLMode:
+//            mFrameBuf = new VBoxQGLFrameBuffer(this);
+//            break;
+//        case VBoxDefs::QGLOverlayMode:
+//            mFrameBuf = new VBoxQGLOverlayFrameBuffer(this);
+//            break;
+#endif
+#if defined (VBOX_GUI_USE_QIMAGE)
+        case VBoxDefs::QImageMode:
+            mFrameBuf =
+#ifdef VBOX_WITH_VIDEOHWACCEL
+//                    mAccelerate2DVideo ? new VBoxOverlayFrameBuffer<UIFrameBufferQImage>(this, &machineWindowWrapper()->session()) :
+#endif
+                    new UIFrameBufferQImage(this);
+            break;
+#endif
+#if defined (VBOX_GUI_USE_SDL)
+        case VBoxDefs::SDLMode:
+            /* Indicate that we are doing all
+             * drawing stuff ourself */
+            pViewport->setAttribute(Qt::WA_PaintOnScreen);
+# ifdef Q_WS_X11
+            /* This is somehow necessary to prevent strange X11 warnings on
+             * i386 and segfaults on x86_64. */
+            XFlush(QX11Info::display());
+# endif
+//            mFrameBuf =
+#if defined(VBOX_WITH_VIDEOHWACCEL) && defined(DEBUG_misha) /* not tested yet */
+//                mAccelerate2DVideo ? new VBoxOverlayFrameBuffer<VBoxSDLFrameBuffer> (this, &machineWindowWrapper()->session()) :
+#endif
+//                new VBoxSDLFrameBuffer(this);
+            /*
+             *  disable scrollbars because we cannot correctly draw in a
+             *  scrolled window using SDL
+             */
+            horizontalScrollBar()->setEnabled(false);
+            verticalScrollBar()->setEnabled(false);
+            break;
+#endif
+#if defined (VBOX_GUI_USE_DDRAW)
+        case VBoxDefs::DDRAWMode:
+            mFrameBuf = new VBoxDDRAWFrameBuffer(this);
+            break;
+#endif
+#if defined (VBOX_GUI_USE_QUARTZ2D)
+        case VBoxDefs::Quartz2DMode:
+            /* Indicate that we are doing all
+             * drawing stuff ourself */
+            pViewport->setAttribute(Qt::WA_PaintOnScreen);
+            mFrameBuf =
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                    mAccelerate2DVideo ? new VBoxOverlayFrameBuffer<VBoxQuartz2DFrameBuffer>(this, &machineWindowWrapper()->session()) :
+#endif
+            	    new VBoxQuartz2DFrameBuffer(this);
+            break;
+#endif
+        default:
+            AssertReleaseMsgFailed(("Render mode must be valid: %d\n", mode));
+            LogRel (("Invalid render mode: %d\n", mode));
+            qApp->exit (1);
+            break;
+    }
+
+#if defined (VBOX_GUI_USE_DDRAW)
+    if (!mFrameBuf || mFrameBuf->address() == NULL)
+    {
+        if (mFrameBuf)
+            delete mFrameBuf;
+        mode = VBoxDefs::QImageMode;
+        mFrameBuf = new UIFrameBufferQImage(this);
+    }
+#endif
+
+    if (mFrameBuf)
+    {
+        mFrameBuf->AddRef();
+        display.SetFramebuffer(VBOX_VIDEO_PRIMARY_SCREEN, CFramebuffer(mFrameBuf));
+    }
+
+    /* setup the callback */
+    mCallback = CConsoleCallback(new UIConsoleCallback(this));
+    m_console.RegisterCallback(mCallback);
+    AssertWrapperOk(m_console);
+
+    QPalette palette(viewport()->palette());
+    palette.setColor(viewport()->backgroundRole(), Qt::black);
+    viewport()->setPalette(palette);
+
+    setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum));
+    setMaximumSize(sizeHint());
+
+    setFocusPolicy(Qt::WheelFocus);
+
+    /* Remember the desktop geometry and register for geometry change
+       events for telling the guest about video modes we like. */
+
+    QString desktopGeometry = vboxGlobal().settings().publicProperty("GUI/MaxGuestResolution");
+    if ((desktopGeometry == QString::null) || (desktopGeometry == "auto"))
+        setDesktopGeometry(DesktopGeo_Automatic, 0, 0);
+    else if (desktopGeometry == "any")
+        setDesktopGeometry(DesktopGeo_Any, 0, 0);
+    else
+    {
+        int width = desktopGeometry.section(',', 0, 0).toInt();
+        int height = desktopGeometry.section(',', 1, 1).toInt();
+        setDesktopGeometry(DesktopGeo_Fixed, width, height);
+    }
+    connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(doResizeDesktop(int)));
+
+    QString passCAD = m_console.GetMachine().GetExtraData(VBoxDefs::GUI_PassCAD);
+    if (!passCAD.isEmpty() && ((passCAD != "false") || (passCAD != "no")))
+        mPassCAD = true;
+
+#if defined (Q_WS_WIN)
+    gView = this;
+#endif
+
+#if defined (Q_WS_PM)
+    bool ok = VBoxHlpInstallKbdHook(0, winId(), UM_PREACCEL_CHAR);
+    Assert (ok);
+    NOREF (ok);
+#endif
+
+#ifdef Q_WS_MAC
+    /* Dock icon update connection */
+    connect(&vboxGlobal(), SIGNAL(dockIconUpdateChanged(const VBoxChangeDockIconUpdateEvent &)),
+            this, SLOT(sltChangeDockIconUpdate(const VBoxChangeDockIconUpdateEvent &)));
+    /* Presentation Mode connection */
+    connect(&vboxGlobal(), SIGNAL(presentationModeChanged(const VBoxChangePresentationModeEvent &)),
+            this, SLOT(sltChangePresentationMode(const VBoxChangePresentationModeEvent &)));
+#endif
+}
+
+UIMachineView::~UIMachineView()
+{
+#if 0
+#if defined (Q_WS_PM)
+    bool ok = VBoxHlpUninstallKbdHook(0, winId(), UM_PREACCEL_CHAR);
+    Assert (ok);
+    NOREF (ok);
+#endif
+
+#if defined (Q_WS_WIN)
+    if (gKbdHook)
+        UnhookWindowsHookEx(gKbdHook);
+    gView = 0;
+    if (mAlphaCursor)
+        DestroyIcon(mAlphaCursor);
+#endif
+
+    if (mFrameBuf)
+    {
+        /* detach our framebuffer from Display */
+        CDisplay display = m_console.GetDisplay();
+        Assert(!display.isNull());
+        display.SetFramebuffer(VBOX_VIDEO_PRIMARY_SCREEN, CFramebuffer(NULL));
+        /* release the reference */
+        mFrameBuf->Release();
+        mFrameBuf = NULL;
+    }
+
+    m_console.UnregisterCallback(mCallback);
+
+#if defined (Q_WS_MAC)
+# if !defined (QT_MAC_USE_COCOA)
+    if (mDarwinWindowOverlayHandlerRef)
+    {
+        ::RemoveEventHandler(mDarwinWindowOverlayHandlerRef);
+        mDarwinWindowOverlayHandlerRef = NULL;
+    }
+# endif
+    delete mDockIconPreview;
+    mDockIconPreview = NULL;
+#endif
+#endif
+}
+
+void UIMachineView::calculateDesktopGeometry()
+{
+    /* This method should not get called until we have initially set up the */
+    Assert((mDesktopGeo != DesktopGeo_Invalid));
+    /* If we are not doing automatic geometry calculation then there is nothing to do. */
+    if (DesktopGeo_Automatic == mDesktopGeo)
+    {
+        /* Available geometry of the desktop.  If the desktop is a single
+         * screen, this will exclude space taken up by desktop taskbars
+         * and things, but this is unfortunately not true for the more
+         * complex case of a desktop spanning multiple screens. */
+        QRect desktop = availableGeometry();
+        /* The area taken up by the console window on the desktop,
+         * including window frame, title and menu bar and whatnot. */
+        QRect frame = machineWindowWrapper()->machineWindow()->frameGeometry();
+        /* The area taken up by the console window, minus all decorations. */
+        //QRect window = machineWindowWrapper()->centralWidget()->geometry(); // TODO check that!
+        /* To work out how big we can make the console window while still
+         * fitting on the desktop, we calculate desktop - frame + window.
+         * This works because the difference between frame and window
+         * (or at least its width and height) is a constant. */
+        //mDesktopGeometry = QRect(0, 0, desktop.width() - frame.width() + window.width(),
+        //                               desktop.height() - frame.height() + window.height());
+    }
+}
+
+QSize UIMachineView::sizeHint() const
+{
+#ifdef VBOX_WITH_DEBUGGER
+    /** @todo figure out a more proper fix. */
+    /* HACK ALERT! Really ugly workaround for the resizing to 9x1 done
+     *             by DevVGA if provoked before power on. */
+    QSize fb(mFrameBuf->width(), mFrameBuf->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(mFrameBuf->width() + frameWidth() * 2, mFrameBuf->height() + frameWidth() * 2);
+#endif
+}
+
+#ifdef Q_WS_MAC
+void UIMachineLogic::sltChangeDockIconUpdate(const VBoxChangeDockIconUpdateEvent &event)
+{
+    setDockIconEnabled(event.mChanged);
+    updateDockOverlay();
+}
+
+# ifdef QT_MAC_USE_COCOA
+void UIMachineLogic::sltChangePresentationMode(const VBoxChangePresentationModeEvent &event)
+{
+    if (mIsFullscreen)
+    {
+        /* First check if we are on the primary screen, only than the presentation mode have to be changed. */
+        QDesktopWidget* pDesktop = QApplication::desktop();
+        if (pDesktop->screenNumber(this) == pDesktop->primaryScreen())
+        {
+            QString testStr = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_PresentationModeEnabled).toLower();
+            /* Default to false if it is an empty value */
+            if (testStr.isEmpty() || testStr == "false")
+                SetSystemUIMode(kUIModeAllHidden, 0);
+            else
+                SetSystemUIMode(kUIModeAllSuppressed, 0);
+        }
+    }
+    else
+        SetSystemUIMode(kUIModeNormal, 0);
+}
+# endif /* QT_MAC_USE_COCOA */
+#endif
+
+int UIMachineView::contentsWidth() const
+{
+    return mFrameBuf->width();
+}
+
+int UIMachineView::contentsHeight() const
+{
+    return mFrameBuf->height();
+}
+
+int UIMachineView::visibleWidth() const
+{
+    return horizontalScrollBar()->pageStep();
+}
+
+int UIMachineView::visibleHeight() const
+{
+    return verticalScrollBar()->pageStep();
+}
+
+bool UIMachineView::event(QEvent *e)
+{
+    //if (m_bIsAttached)
+    {
+        switch (e->type())
+        {
+            case QEvent::FocusIn:
+            {
+                if (isRunning())
+                    focusEvent (true);
+                break;
+            }
+            case QEvent::FocusOut:
+            {
+                if (isRunning())
+                    focusEvent (false);
+                else
+                {
+                    /* release the host key and all other pressed keys too even
+                     * when paused (otherwise, we will get stuck keys in the
+                     * guest when doing sendChangedKeyStates() on resume because
+                     * key presses were already recorded in mPressedKeys but key
+                     * releases will most likely not reach us but the new focus
+                     * window instead). */
+                    releaseAllPressedKeys (true /* aReleaseHostKey */);
+                }
+                break;
+            }
+
+            case VBoxDefs::ResizeEventType:
+            {
+                /* Some situations require initial VGA Resize Request
+                 * to be ignored at all, leaving previous framebuffer,
+                 * console widget and vm window size preserved. */
+                if (m_bIsGuestResizeIgnored)
+                    return true;
+
+                bool oldIgnoreMainwndResize = m_bIsMachineWindowResizeIgnored;
+                m_bIsMachineWindowResizeIgnored = true;
+
+                UIResizeEvent *re = (UIResizeEvent *) e;
+                LogFlow (("VBoxDefs::ResizeEventType: %d x %d x %d bpp\n",
+                          re->width(), re->height(), re->bitsPerPixel()));
+#ifdef DEBUG_michael
+                LogRel (("Resize event from guest: %d x %d x %d bpp\n",
+                         re->width(), re->height(), re->bitsPerPixel()));
+#endif
+
+                /* Store the new size to prevent unwanted resize hints being
+                 * sent back. */
+                storeConsoleSize(re->width(), re->height());
+                /* do frame buffer dependent resize */
+
+                /* restoreOverrideCursor() is broken in Qt 4.4.0 if WA_PaintOnScreen
+                 * widgets are present. This is the case on linux with SDL. As
+                 * workaround we save/restore the arrow cursor manually. See
+                 * http://trolltech.com/developer/task-tracker/index_html?id=206165&method=entry
+                 * for details.
+                 *
+                 * Moreover the current cursor, which could be set by the guest,
+                 * should be restored after resize.
+                 */
+                QCursor cursor;
+                if (shouldHideHostPointer())
+                    cursor = QCursor (Qt::BlankCursor);
+                else
+                    cursor = viewport()->cursor();
+                mFrameBuf->resizeEvent (re);
+                viewport()->setCursor (cursor);
+
+#ifdef Q_WS_MAC
+                mDockIconPreview->setOriginalSize (re->width(), re->height());
+#endif /* Q_WS_MAC */
+
+                /* This event appears in case of guest video was changed
+                 * for somehow even without video resolution change.
+                 * In this last case the host VM window will not be resized
+                 * according this event and the host mouse cursor which was
+                 * unset to default here will not be hidden in capture state.
+                 * So it is necessary to perform updateMouseClipping() for
+                 * the guest resize event if the mouse cursor was captured. */
+                if (m_bIsMouseCaptured)
+                    updateMouseClipping();
+
+                /* apply maximum size restriction */
+                setMaximumSize (sizeHint());
+
+                maybeRestrictMinimumSize();
+
+                /* resize the guest canvas */
+                if (!m_bIsFrameBufferResizeIgnored)
+                    resize (re->width(), re->height());
+                updateSliders();
+                /* Let our toplevel widget calculate its sizeHint properly. */
+#ifdef Q_WS_X11
+                /* We use processEvents rather than sendPostedEvents & set the
+                 * time out value to max cause on X11 otherwise the layout
+                 * isn't calculated correctly. Dosn't find the bug in Qt, but
+                 * this could be triggered through the async nature of the X11
+                 * window event system. */
+                QCoreApplication::processEvents (QEventLoop::AllEvents, INT_MAX);
+#else /* Q_WS_X11 */
+                QCoreApplication::sendPostedEvents (0, QEvent::LayoutRequest);
+#endif /* Q_WS_X11 */
+
+                if (!m_bIsFrameBufferResizeIgnored)
+                    normalizeGeometry (true /* adjustPosition */);
+
+                /* report to the VM thread that we finished resizing */
+                m_console.GetDisplay().ResizeCompleted (0);
+
+                m_bIsMachineWindowResizeIgnored = oldIgnoreMainwndResize;
+
+                /* update geometry after entering fullscreen | seamless */
+                // if (machineWindowWrapper()->isTrueFullscreen() || machineWindowWrapper()->isTrueSeamless()) TODO check that!
+                    updateGeometry();
+
+                /* make sure that all posted signals are processed */
+                qApp->processEvents();
+
+                /* emit a signal about guest was resized */
+                emit resizeHintDone();
+
+                /* We also recalculate the desktop geometry if this is determined
+                 * automatically.  In fact, we only need this on the first resize,
+                 * but it is done every time to keep the code simpler. */
+                calculateDesktopGeometry();
+
+                /* Enable frame-buffer resize watching. */
+                if (m_bIsFrameBufferResizeIgnored)
+                {
+                    m_bIsFrameBufferResizeIgnored = false;
+                }
+
+                // machineWindowWrapper()->onDisplayResize (re->width(), re->height()); TODO check that!
+
+                return true;
+            }
+
+            /* See VBox[QImage|SDL]FrameBuffer::NotifyUpdate(). */
+            case VBoxDefs::RepaintEventType:
+            {
+                UIRepaintEvent *re = (UIRepaintEvent *) e;
+                viewport()->repaint (re->x() - contentsX(),
+                                     re->y() - contentsY(),
+                                     re->width(), re->height());
+                /* m_console.GetDisplay().UpdateCompleted(); - the event was acked already */
+                return true;
+            }
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+            case VBoxDefs::VHWACommandProcessType:
+            {
+                mFrameBuf->doProcessVHWACommand(e);
+                return true;
+            }
+#endif
+
+            #if 0
+            // TODO check that!
+            case VBoxDefs::SetRegionEventType:
+            {
+                VBoxSetRegionEvent *sre = (VBoxSetRegionEvent*) e;
+                if (machineWindowWrapper()->isTrueSeamless() && sre->region() != mLastVisibleRegion)
+                {
+                    mLastVisibleRegion = sre->region();
+                    machineWindowWrapper()->setMask (sre->region());
+                }
+                else if (!mLastVisibleRegion.isEmpty() && !machineWindowWrapper()->isTrueSeamless())
+                    mLastVisibleRegion = QRegion();
+                return true;
+            }
+            #endif
+
+            case VBoxDefs::MousePointerChangeEventType:
+            {
+                MousePointerChangeEvent *me = (MousePointerChangeEvent *) e;
+                /* change cursor shape only when mouse integration is
+                 * supported (change mouse shape type event may arrive after
+                 * mouse capability change that disables integration */
+                if (m_bIsMouseAbsolute)
+                    setPointerShape (me);
+                else
+                    /* Note: actually we should still remember the requested
+                     * cursor shape.  If we can't do that, at least remember
+                     * the requested visiblilty. */
+                    mHideHostPointer = !me->isVisible();
+                return true;
+            }
+            case VBoxDefs::MouseCapabilityEventType:
+            {
+                MouseCapabilityEvent *me = (MouseCapabilityEvent *) e;
+                if (m_bIsMouseAbsolute != me->supportsAbsolute())
+                {
+                    m_bIsMouseAbsolute = me->supportsAbsolute();
+                    /* correct the mouse capture state and reset the cursor
+                     * to the default shape if necessary */
+                    if (m_bIsMouseAbsolute)
+                    {
+                        CMouse mouse = m_console.GetMouse();
+                        mouse.PutMouseEventAbsolute (-1, -1, 0,
+                                                     0 /* Horizontal wheel */,
+                                                     0);
+                        captureMouse (false, false);
+                    }
+                    else
+                        viewport()->unsetCursor();
+                    emitMouseStateChanged();
+                    vboxProblem().remindAboutMouseIntegration (m_bIsMouseAbsolute);
+                }
+                if (me->needsHostCursor())
+                    setMouseIntegrationLocked (false);
+                else
+                    setMouseIntegrationLocked (true);
+                return true;
+            }
+
+            case VBoxDefs::ModifierKeyChangeEventType:
+            {
+                ModifierKeyChangeEvent *me = (ModifierKeyChangeEvent* )e;
+                if (me->numLock() != mNumLock)
+                    muNumLockAdaptionCnt = 2;
+                if (me->capsLock() != mCapsLock)
+                    muCapsLockAdaptionCnt = 2;
+                mNumLock    = me->numLock();
+                mCapsLock   = me->capsLock();
+                mScrollLock = me->scrollLock();
+                return true;
+            }
+
+            case VBoxDefs::MachineStateChangeEventType:
+            {
+                StateChangeEvent *me = (StateChangeEvent *) e;
+                LogFlowFunc (("MachineStateChangeEventType: state=%d\n",
+                               me->machineState()));
+                onStateChange (me->machineState());
+                emit machineStateChanged (me->machineState());
+                return true;
+            }
+
+            case VBoxDefs::AdditionsStateChangeEventType:
+            {
+                GuestAdditionsEvent *ge = (GuestAdditionsEvent *) e;
+                LogFlowFunc (("AdditionsStateChangeEventType\n"));
+
+                /* Always send a size hint if we are in fullscreen or seamless
+                 * when the graphics capability is enabled, in case the host
+                 * resolution has changed since the VM was last run. */
+#if 0
+                if (!mDoResize && !m_bIsGuestSupportsGraphics &&
+                    ge->supportsGraphics() &&
+                    (machineWindowWrapper()->isTrueSeamless() || machineWindowWrapper()->isTrueFullscreen()))
+                    mDoResize = true;
+#endif
+
+                m_bIsGuestSupportsGraphics = ge->supportsGraphics();
+
+                maybeRestrictMinimumSize();
+
+#if 0
+                /* This will only be acted upon if mDoResize is true. */
+                doResizeHint();
+#endif
+
+                emit additionsStateChanged (ge->additionVersion(),
+                                            ge->additionActive(),
+                                            ge->supportsSeamless(),
+                                            ge->supportsGraphics());
+                return true;
+            }
+
+            case VBoxDefs::MediaDriveChangeEventType:
+            {
+                MediaDriveChangeEvent *mce = (MediaDriveChangeEvent *) e;
+                LogFlowFunc (("MediaChangeEvent\n"));
+
+                emit mediaDriveChanged (mce->type());
+                return true;
+            }
+
+            #if 0
+            case VBoxDefs::ActivateMenuEventType:
+            {
+                ActivateMenuEvent *ame = (ActivateMenuEvent *) e;
+                ame->action()->trigger();
+
+                /*
+                 *  The main window and its children can be destroyed at this
+                 *  point (if, for example, the activated menu item closes the
+                 *  main window). Detect this situation to prevent calls to
+                 *  destroyed widgets.
+                 */
+                QWidgetList list = QApplication::topLevelWidgets();
+                bool destroyed = list.indexOf (machineWindowWrapper()->machineWindow()) < 0;
+                if (!destroyed && machineWindowWrapper()->machineWindow()->statusBar())
+                    machineWindowWrapper()->machineWindow()->statusBar()->clearMessage();
+
+                return true;
+            }
+            #endif
+
+            case VBoxDefs::NetworkAdapterChangeEventType:
+            {
+                /* no specific adapter information stored in this
+                 * event is currently used */
+                emit networkStateChange();
+                return true;
+            }
+
+            case VBoxDefs::USBCtlStateChangeEventType:
+            {
+                emit usbStateChange();
+                return true;
+            }
+
+            case VBoxDefs::USBDeviceStateChangeEventType:
+            {
+                USBDeviceStateChangeEvent *ue = (USBDeviceStateChangeEvent *)e;
+
+                bool success = ue->error().isNull();
+
+                if (!success)
+                {
+                    if (ue->attached())
+                        vboxProblem().cannotAttachUSBDevice (
+                            m_console,
+                            vboxGlobal().details (ue->device()), ue->error());
+                    else
+                        vboxProblem().cannotDetachUSBDevice (
+                            m_console,
+                            vboxGlobal().details (ue->device()), ue->error());
+                }
+
+                emit usbStateChange();
+
+                return true;
+            }
+
+            case VBoxDefs::SharedFolderChangeEventType:
+            {
+                emit sharedFoldersChanged();
+                return true;
+            }
+
+            case VBoxDefs::RuntimeErrorEventType:
+            {
+                RuntimeErrorEvent *ee = (RuntimeErrorEvent *) e;
+                vboxProblem().showRuntimeError (m_console, ee->fatal(),
+                                                ee->errorID(), ee->message());
+                return true;
+            }
+
+            case QEvent::KeyPress:
+            case QEvent::KeyRelease:
+            {
+                QKeyEvent *ke = (QKeyEvent *) e;
+
+#ifdef Q_WS_PM
+                /// @todo temporary solution to send Alt+Tab and friends to
+                //  the guest. The proper solution is to write a keyboard
+                //  driver that will steal these combos from the host (it's
+                //  impossible to do so using hooks on OS/2).
+
+                if (m_bIsHostkeyPressed)
+                {
+                    bool pressed = e->type() == QEvent::KeyPress;
+                    CKeyboard keyboard = m_console.GetKeyboard();
+
+                    /* whether the host key is Shift so that it will modify
+                     * the hot key values? Note that we don't distinguish
+                     * between left and right shift here (too much hassle) */
+                    const bool kShift = (m_globalSettings.hostKey() == VK_SHIFT ||
+                                        m_globalSettings.hostKey() == VK_LSHIFT) &&
+                                        (ke->state() & Qt::ShiftModifier);
+                    /* define hot keys according to the Shift state */
+                    const int kAltTab      = kShift ? Qt::Key_Exclam     : Qt::Key_1;
+                    const int kAltShiftTab = kShift ? Qt::Key_At         : Qt::Key_2;
+                    const int kCtrlEsc     = kShift ? Qt::Key_AsciiTilde : Qt::Key_QuoteLeft;
+
+                    /* Simulate Alt+Tab on Host+1 and Alt+Shift+Tab on Host+2 */
+                    if (ke->key() == kAltTab || ke->key() == kAltShiftTab)
+                    {
+                        if (pressed)
+                        {
+                            /* Send the Alt press to the guest */
+                            if (!(mPressedKeysCopy [0x38] & IsKeyPressed))
+                            {
+                                /* store the press in *Copy to have it automatically
+                                 * released when the Host key is released */
+                                mPressedKeysCopy [0x38] |= IsKeyPressed;
+                                keyboard.PutScancode (0x38);
+                            }
+
+                            /* Make sure Shift is pressed if it's Key_2 and released
+                             * if it's Key_1 */
+                            if (ke->key() == kAltTab &&
+                                (mPressedKeysCopy [0x2A] & IsKeyPressed))
+                            {
+                                mPressedKeysCopy [0x2A] &= ~IsKeyPressed;
+                                keyboard.PutScancode (0xAA);
+                            }
+                            else
+                            if (ke->key() == kAltShiftTab &&
+                                !(mPressedKeysCopy [0x2A] & IsKeyPressed))
+                            {
+                                mPressedKeysCopy [0x2A] |= IsKeyPressed;
+                                keyboard.PutScancode (0x2A);
+                            }
+                        }
+
+                        keyboard.PutScancode (pressed ? 0x0F : 0x8F);
+
+                        ke->accept();
+                        return true;
+                    }
+
+                    /* Simulate Ctrl+Esc on Host+Tilde */
+                    if (ke->key() == kCtrlEsc)
+                    {
+                        /* Send the Ctrl press to the guest */
+                        if (pressed && !(mPressedKeysCopy [0x1d] & IsKeyPressed))
+                        {
+                            /* store the press in *Copy to have it automatically
+                             * released when the Host key is released */
+                            mPressedKeysCopy [0x1d] |= IsKeyPressed;
+                            keyboard.PutScancode (0x1d);
+                        }
+
+                        keyboard.PutScancode (pressed ? 0x01 : 0x81);
+
+                        ke->accept();
+                        return true;
+                    }
+                }
+
+                /* fall through to normal processing */
+
+#endif /* Q_WS_PM */
+
+                if (m_bIsHostkeyPressed && e->type() == QEvent::KeyPress)
+                {
+                    if (ke->key() >= Qt::Key_F1 && ke->key() <= Qt::Key_F12)
+                    {
+                        QVector <LONG> combo (6);
+                        combo [0] = 0x1d; /* Ctrl down */
+                        combo [1] = 0x38; /* Alt  down */
+                        combo [4] = 0xb8; /* Alt  up   */
+                        combo [5] = 0x9d; /* Ctrl up   */
+                        if (ke->key() >= Qt::Key_F1 && ke->key() <= Qt::Key_F10)
+                        {
+                            combo [2] = 0x3b + (ke->key() - Qt::Key_F1); /* F1-F10 down */
+                            combo [3] = 0xbb + (ke->key() - Qt::Key_F1); /* F1-F10 up   */
+                        }
+                        /* some scan slice */
+                        else if (ke->key() >= Qt::Key_F11 && ke->key() <= Qt::Key_F12)
+                        {
+                            combo [2] = 0x57 + (ke->key() - Qt::Key_F11); /* F11-F12 down */
+                            combo [3] = 0xd7 + (ke->key() - Qt::Key_F11); /* F11-F12 up   */
+                        }
+                        else
+                            Assert (0);
+
+                        CKeyboard keyboard = m_console.GetKeyboard();
+                        keyboard.PutScancodes (combo);
+                    }
+                    #if 0
+                    // TODO check that!
+                    else if (ke->key() == Qt::Key_Home)
+                    {
+                        /* Activate the main menu */
+                        if (machineWindowWrapper()->isTrueSeamless() || machineWindowWrapper()->isTrueFullscreen())
+                            machineWindowWrapper()->popupMainMenu (m_bIsMouseCaptured);
+                        else
+                        {
+                            /* In Qt4 it is not enough to just set the focus to
+                             * menu-bar. So to get the menu-bar we have to send
+                             * Qt::Key_Alt press/release events directly. */
+                            QKeyEvent e1 (QEvent::KeyPress, Qt::Key_Alt,
+                                          Qt::NoModifier);
+                            QKeyEvent e2 (QEvent::KeyRelease, Qt::Key_Alt,
+                                          Qt::NoModifier);
+                            QApplication::sendEvent (machineWindowWrapper()->menuBar(), &e1);
+                            QApplication::sendEvent (machineWindowWrapper()->menuBar(), &e2);
+                        }
+                    }
+                    else
+                    {
+                        /* process hot keys not processed in keyEvent()
+                         * (as in case of non-alphanumeric keys) */
+                        processHotKey (QKeySequence (ke->key()),
+                                       machineWindowWrapper()->menuBar()->actions());
+                    }
+                    #endif
+                }
+                else if (!m_bIsHostkeyPressed && e->type() == QEvent::KeyRelease)
+                {
+                    /* Show a possible warning on key release which seems to
+                     * be more expected by the end user */
+
+                    if (machineWindowWrapper()->machineLogic()->isPaused())
+                    {
+                        /* if the reminder is disabled we pass the event to
+                         * Qt to enable normal keyboard functionality
+                         * (for example, menu access with Alt+Letter) */
+                        if (!vboxProblem().remindAboutPausedVMInput())
+                            break;
+                    }
+                }
+
+                ke->accept();
+                return true;
+            }
+
+#ifdef Q_WS_MAC
+            /* posted OnShowWindow */
+            case VBoxDefs::ShowWindowEventType:
+            {
+                /*
+                 *  Dunno what Qt3 thinks a window that has minimized to the dock
+                 *  should be - it is not hidden, neither is it minimized. OTOH it is
+                 *  marked shown and visible, but not activated. This latter isn't of
+                 *  much help though, since at this point nothing is marked activated.
+                 *  I might have overlooked something, but I'm buggered what if I know
+                 *  what. So, I'll just always show & activate the stupid window to
+                 *  make it get out of the dock when the user wishes to show a VM.
+                 */
+                window()->show();
+                window()->activateWindow();
+                return true;
+            }
+#endif
+            default:
+                break;
+        }
+    }
+
+    return QAbstractScrollArea::event (e);
+}
+
+bool UIMachineView::eventFilter(QObject *watched, QEvent *e)
+{
+    if (watched == viewport())
+    {
+        switch (e->type())
+        {
+            case QEvent::MouseMove:
+            case QEvent::MouseButtonPress:
+            case QEvent::MouseButtonDblClick:
+            case QEvent::MouseButtonRelease:
+            {
+                QMouseEvent *me = (QMouseEvent *) e;
+                m_iLastMouseWheelDelta = 0;
+                if (mouseEvent (me->type(), me->pos(), me->globalPos(),
+                                me->buttons(), me->modifiers(),
+                                0, Qt::Horizontal))
+                    return true; /* stop further event handling */
+                break;
+            }
+            case QEvent::Wheel:
+            {
+                QWheelEvent *we = (QWheelEvent *) e;
+                /* There are pointing devices which send smaller values for the
+                 * delta than 120. Here we sum them up until we are greater
+                 * than 120. This allows to have finer control over the speed
+                 * acceleration & enables such devices to send a valid wheel
+                 * event to our guest mouse device at all. */
+                int iDelta = 0;
+                m_iLastMouseWheelDelta += we->delta();
+                if (qAbs(m_iLastMouseWheelDelta) >= 120)
+                {
+                    iDelta = m_iLastMouseWheelDelta;
+                    m_iLastMouseWheelDelta = m_iLastMouseWheelDelta % 120;
+                }
+                if (mouseEvent (we->type(), we->pos(), we->globalPos(),
+#ifdef QT_MAC_USE_COCOA
+                                /* Qt Cocoa is buggy. It always reports a left
+                                 * button pressed when the mouse wheel event
+                                 * occurs. A workaround is to ask the
+                                 * application which buttons are pressed
+                                 * currently. */
+                                QApplication::mouseButtons(),
+#else /* QT_MAC_USE_COCOA */
+                                we->buttons(),
+#endif /* QT_MAC_USE_COCOA */
+                                we->modifiers(),
+                                iDelta, we->orientation()))
+                    return true; /* stop further event handling */
+                break;
+            }
+#ifdef Q_WS_MAC
+            case QEvent::Leave:
+            {
+                /* Enable mouse event compression if we leave the VM view. This
+                   is necessary for having smooth resizing of the VM/other
+                   windows. */
+                setMouseCoalescingEnabled (true);
+                break;
+            }
+            case QEvent::Enter:
+            {
+                /* Disable mouse event compression if we enter the VM view. So
+                   all mouse events are registered in the VM. Only do this if
+                   the keyboard/mouse is grabbed (this is when we have a valid
+                   event handler). */
+                setMouseCoalescingEnabled (false);
+                break;
+            }
+#endif /* Q_WS_MAC */
+            case QEvent::Resize:
+            {
+                if (m_bIsMouseCaptured)
+                    updateMouseClipping();
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                if (mFrameBuf)
+                {
+                    mFrameBuf->viewportResized((QResizeEvent*)e);
+                }
+#endif
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    else if (watched == machineWindowWrapper()->machineWindow())
+    {
+        switch (e->type())
+        {
+#if defined (Q_WS_WIN32)
+#if defined (VBOX_GUI_USE_DDRAW)
+            case QEvent::Move:
+            {
+                /*
+                 *  notification from our parent that it has moved. We need this
+                 *  in order to possibly adjust the direct screen blitting.
+                 */
+                if (mFrameBuf)
+                    mFrameBuf->moveEvent ((QMoveEvent *) e);
+                break;
+            }
+#endif
+            /*
+             *  install/uninstall low-level kbd hook on every
+             *  activation/deactivation to:
+             *  a) avoid excess hook calls when we're not active and
+             *  b) be always in front of any other possible hooks
+             */
+            case QEvent::WindowActivate:
+            {
+                gKbdHook = SetWindowsHookEx (WH_KEYBOARD_LL, lowLevelKeyboardProc,
+                                              GetModuleHandle (NULL), 0);
+                AssertMsg (gKbdHook, ("SetWindowsHookEx(): err=%d", GetLastError()));
+                break;
+            }
+            case QEvent::WindowDeactivate:
+            {
+                if (gKbdHook)
+                {
+                    UnhookWindowsHookEx (gKbdHook);
+                    gKbdHook = NULL;
+                }
+                break;
+            }
+#endif /* defined (Q_WS_WIN32) */
+#if defined (Q_WS_MAC)
+            /*
+             *  Install/remove the keyboard event handler.
+             */
+            case QEvent::WindowActivate:
+                darwinGrabKeyboardEvents (true);
+                break;
+            case QEvent::WindowDeactivate:
+                darwinGrabKeyboardEvents (false);
+                break;
+#endif /* defined (Q_WS_MAC) */
+            #if 0
+            // TODO check that!
+            case QEvent::Resize:
+            {
+                /* Set the "guest needs to resize" hint.  This hint is acted upon
+                 * when (and only when) the autoresize property is "true". */
+                mDoResize = m_bIsGuestSupportsGraphics || machineWindowWrapper()->isTrueFullscreen();
+                if (!m_bIsMachineWindowResizeIgnored &&
+                    m_bIsGuestSupportsGraphics && m_bIsGuestAutoresizeEnabled)
+                    QTimer::singleShot (300, this, SLOT (doResizeHint()));
+                break;
+            }
+            #endif
+            case QEvent::WindowStateChange:
+            {
+                /* During minimizing and state restoring machineWindowWrapper() gets the focus
+                 * which belongs to console view window, so returning it properly. */
+                QWindowStateChangeEvent *ev = static_cast <QWindowStateChangeEvent*> (e);
+                if (ev->oldState() & Qt::WindowMinimized)
+                {
+                    if (QApplication::focusWidget())
+                    {
+                        QApplication::focusWidget()->clearFocus();
+                        qApp->processEvents();
+                    }
+                    QTimer::singleShot (0, this, SLOT (setFocus()));
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+    }
+    #if 0 // TODO check that
+    else if (watched == machineWindowWrapper()->menuBar())
+    {
+        /*
+         *  sometimes when we press ESC in the menu it brings the
+         *  focus away (Qt bug?) causing no widget to have a focus,
+         *  or holds the focus itself, instead of returning the focus
+         *  to the console window. here we fix this.
+         */
+        switch (e->type())
+        {
+            case QEvent::FocusOut:
+            {
+                if (qApp->focusWidget() == 0)
+                    setFocus();
+                break;
+            }
+            case QEvent::KeyPress:
+            {
+                QKeyEvent *ke = (QKeyEvent *) e;
+                if (ke->key() == Qt::Key_Escape && (ke->modifiers() == Qt::NoModifier))
+                    if (machineWindowWrapper()->menuBar()->hasFocus())
+                        setFocus();
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    #endif
+
+    return QAbstractScrollArea::eventFilter (watched, e);
+}
+
+#if defined(Q_WS_WIN32)
+
+bool UIMachineView::winLowKeyboardEvent(UINT msg, const KBDLLHOOKSTRUCT &event)
+{
+    /* Sometimes it happens that Win inserts additional events on some key
+     * press/release. For example, it prepends ALT_GR in German layout with
+     * the VK_LCONTROL vkey with curious 0x21D scan code (seems to be necessary
+     * to specially treat ALT_GR to enter additional chars to regular apps).
+     * These events are definitely unwanted in VM, so filter them out. */
+    /* Note (michael): it also sometimes sends the VK_CAPITAL vkey with scan
+     * code 0x23a. If this is not passed through then it is impossible to
+     * cancel CapsLock on a French keyboard.  I didn't find any other examples
+     * of these strange events.  Let's hope we are not missing anything else
+     * of importance! */
+    if (hasFocus() && (event.scanCode & ~0xFF))
+    {
+        if (event.vkCode == VK_CAPITAL)
+            return false;
+        else
+            return true;
+    }
+
+    if (!m_bIsKeyboardCaptured)
+        return false;
+
+    /* it's possible that a key has been pressed while the keyboard was not
+     * captured, but is being released under the capture. Detect this situation
+     * and return false to let Windows process the message normally and update
+     * its key state table (to avoid the stuck key effect). */
+    uint8_t what_pressed = (event.flags & 0x01) && (event.vkCode != VK_RSHIFT) ? IsExtKeyPressed : IsKeyPressed;
+    if ((event.flags & 0x80) /* released */ &&
+        ((event.vkCode == m_globalSettings.hostKey() && !hostkey_in_capture) ||
+         (mPressedKeys [event.scanCode] & (IsKbdCaptured | what_pressed)) == what_pressed))
+        return false;
+
+    MSG message;
+    message.hwnd = winId();
+    message.message = msg;
+    message.wParam = event.vkCode;
+    message.lParam = 1 | (event.scanCode & 0xFF) << 16 | (event.flags & 0xFF) << 24;
+
+    /* Windows sets here the extended bit when the Right Shift key is pressed,
+     * which is totally wrong. Undo it. */
+    if (event.vkCode == VK_RSHIFT)
+        message.lParam &= ~0x1000000;
+
+    /* we suppose here that this hook is always called on the main GUI thread */
+    long dummyResult;
+    return winEvent(&message, &dummyResult);
+}
+
+bool UIMachineView::winEvent(MSG *aMsg, long* /* aResult */)
+{
+    if (!(aMsg->message == WM_KEYDOWN || aMsg->message == WM_SYSKEYDOWN ||
+          aMsg->message == WM_KEYUP || aMsg->message == WM_SYSKEYUP))
+        return false;
+
+    /* Check for the special flag possibly set at the end of this function */
+    if (aMsg->lParam & (0x1 << 25))
+    {
+        aMsg->lParam &= ~(0x1 << 25);
+        return false;
+    }
+
+    int scan = (aMsg->lParam >> 16) & 0x7F;
+    /* scancodes 0x80 and 0x00 are ignored */
+    if (!scan)
+        return true;
+
+    int vkey = aMsg->wParam;
+
+    /* When one of the SHIFT keys is held and one of the cursor movement
+     * keys is pressed, Windows duplicates SHIFT press/release messages,
+     * but with the virtual key code set to 0xFF. These virtual keys are also
+     * sent in some other situations (Pause, PrtScn, etc.). Ignore such
+     * messages. */
+    if (vkey == 0xFF)
+        return true;
+
+    int flags = 0;
+    if (aMsg->lParam & 0x1000000)
+        flags |= KeyExtended;
+    if (!(aMsg->lParam & 0x80000000))
+        flags |= KeyPressed;
+
+    switch (vkey)
+    {
+        case VK_SHIFT:
+        case VK_CONTROL:
+        case VK_MENU:
+        {
+            /* overcome stupid Win32 modifier key generalization */
+            int keyscan = scan;
+            if (flags & KeyExtended)
+                keyscan |= 0xE000;
+            switch (keyscan)
+            {
+                case 0x002A: vkey = VK_LSHIFT; break;
+                case 0x0036: vkey = VK_RSHIFT; break;
+                case 0x001D: vkey = VK_LCONTROL; break;
+                case 0xE01D: vkey = VK_RCONTROL; break;
+                case 0x0038: vkey = VK_LMENU; break;
+                case 0xE038: vkey = VK_RMENU; break;
+            }
+            break;
+        }
+        case VK_NUMLOCK:
+            /* Win32 sets the extended bit for the NumLock key. Reset it. */
+            flags &= ~KeyExtended;
+            break;
+        case VK_SNAPSHOT:
+            flags |= KeyPrint;
+            break;
+        case VK_PAUSE:
+            flags |= KeyPause;
+            break;
+    }
+
+    bool result = keyEvent(vkey, scan, flags);
+    if (!result && m_bIsKeyboardCaptured)
+    {
+        /* keyEvent() returned that it didn't process the message, but since the
+         * keyboard is captured, we don't want to pass it to Windows. We just want
+         * to let Qt process the message (to handle non-alphanumeric <HOST>+key
+         * shortcuts for example). So send it direcltly to the window with the
+         * special flag in the reserved area of lParam (to avoid recursion). */
+        ::SendMessage(aMsg->hwnd, aMsg->message,
+                      aMsg->wParam, aMsg->lParam | (0x1 << 25));
+        return true;
+    }
+
+    /* These special keys have to be handled by Windows as well to update the
+     * internal modifier state and to enable/disable the keyboard LED */
+    if (vkey == VK_NUMLOCK || vkey == VK_CAPITAL || vkey == VK_LSHIFT || vkey == VK_RSHIFT)
+        return false;
+
+    return result;
+}
+
+#elif defined (Q_WS_PM)
+
+bool UIMachineView::pmEvent(QMSG *aMsg)
+{
+    if (aMsg->msg == UM_PREACCEL_CHAR)
+    {
+        /* We are inside the input hook
+         * let the message go through the normal system pipeline. */
+        if (!m_bIsKeyboardCaptured)
+            return false;
+    }
+
+    if (aMsg->msg != WM_CHAR && aMsg->msg != UM_PREACCEL_CHAR)
+        return false;
+
+    /* check for the special flag possibly set at the end of this function */
+    if (SHORT2FROMMP(aMsg->mp2) & 0x8000)
+    {
+        aMsg->mp2 = MPFROM2SHORT(SHORT1FROMMP(aMsg->mp2), SHORT2FROMMP(aMsg->mp2) & ~0x8000);
+        return false;
+    }
+
+    USHORT ch = SHORT1FROMMP(aMsg->mp2);
+    USHORT f = SHORT1FROMMP(aMsg->mp1);
+
+    int scan = (unsigned int)CHAR4FROMMP(aMsg->mp1);
+    if (!scan || scan > 0x7F)
+        return true;
+
+    int vkey = QIHotKeyEdit::virtualKey(aMsg);
+
+    int flags = 0;
+
+    if ((ch & 0xFF) == 0xE0)
+    {
+        flags |= KeyExtended;
+        scan = ch >> 8;
+    }
+    else if (scan == 0x5C && (ch & 0xFF) == '/')
+    {
+        /* this is the '/' key on the keypad */
+        scan = 0x35;
+        flags |= KeyExtended;
+    }
+    else
+    {
+        /* For some keys, the scan code passed in QMSG is a pseudo scan
+         * code. We replace it with a real hardware scan code, according to
+         * http://www.computer-engineering.org/ps2keyboard/scancodes1.html.
+         * Also detect Pause and PrtScn and set flags. */
+        switch (vkey)
+        {
+            case VK_ENTER:     scan = 0x1C; flags |= KeyExtended; break;
+            case VK_CTRL:      scan = 0x1D; flags |= KeyExtended; break;
+            case VK_ALTGRAF:   scan = 0x38; flags |= KeyExtended; break;
+            case VK_LWIN:      scan = 0x5B; flags |= KeyExtended; break;
+            case VK_RWIN:      scan = 0x5C; flags |= KeyExtended; break;
+            case VK_WINMENU:   scan = 0x5D; flags |= KeyExtended; break;
+            case VK_FORWARD:   scan = 0x69; flags |= KeyExtended; break;
+            case VK_BACKWARD:  scan = 0x6A; flags |= KeyExtended; break;
+#if 0
+            /// @todo this would send 0xE0 0x46 0xE0 0xC6. It's not fully
+            // clear what is more correct
+            case VK_BREAK:     scan = 0x46; flags |= KeyExtended; break;
+#else
+            case VK_BREAK:     scan = 0;    flags |= KeyPause; break;
+#endif
+            case VK_PAUSE:     scan = 0;    flags |= KeyPause;    break;
+            case VK_PRINTSCRN: scan = 0;    flags |= KeyPrint;    break;
+            default:;
+        }
+    }
+
+    if (!(f & KC_KEYUP))
+        flags |= KeyPressed;
+
+    bool result = keyEvent (vkey, scan, flags);
+    if (!result && m_bIsKeyboardCaptured)
+    {
+        /* keyEvent() returned that it didn't process the message, but since the
+         * keyboard is captured, we don't want to pass it to PM. We just want
+         * to let Qt process the message (to handle non-alphanumeric <HOST>+key
+         * shortcuts for example). So send it direcltly to the window with the
+         * special flag in the reserved area of lParam (to avoid recursion). */
+        ::WinSendMsg (aMsg->hwnd, WM_CHAR, aMsg->mp1,
+                      MPFROM2SHORT (SHORT1FROMMP (aMsg->mp2), SHORT2FROMMP (aMsg->mp2) | 0x8000));
+        return true;
+    }
+    return result;
+}
+
+#elif defined(Q_WS_X11)
+
+static Bool VBoxConsoleViewCompEvent(Display *, XEvent *pEvent, XPointer pvArg)
+{
+    XEvent *pKeyEvent = (XEvent *) pvArg;
+    if ((pEvent->type == XKeyPress) && (pEvent->xkey.keycode == pKeyEvent->xkey.keycode))
+        return True;
+    else
+        return False;
+}
+
+bool UIMachineView::x11Event(XEvent *event)
+{
+    switch (event->type)
+    {
+        /* We have to handle XFocusOut right here as this event is not passed
+         * to UIMachineView::event(). Handling this event is important for
+         * releasing the keyboard before the screen saver gets active. */
+        case XFocusOut:
+        case XFocusIn:
+            if (isRunning())
+                focusEvent(event->type == XFocusIn);
+            return false;
+        case XKeyPress:
+        case XKeyRelease:
+            break;
+        default:
+            return false; /* pass the event to Qt */
+    }
+
+    /* Translate the keycode to a PC scan code. */
+    unsigned scan = handleXKeyEvent(event);
+
+    // scancodes 0x00 (no valid translation) and 0x80 are ignored
+    if (!scan & 0x7F)
+        return true;
+
+    /* Fix for http://www.virtualbox.org/ticket/1296:
+     * when X11 sends events for repeated keys, it always inserts an
+     * XKeyRelease before the XKeyPress. */
+    XEvent returnEvent;
+    if ((event->type == XKeyRelease) && (XCheckIfEvent(event->xkey.display, &returnEvent,
+        VBoxConsoleViewCompEvent, (XPointer) event) == True))
+    {
+        XPutBackEvent(event->xkey.display, &returnEvent);
+        /* Discard it, don't pass it to Qt. */
+        return true;
+    }
+
+    KeySym ks = ::XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 0);
+
+    int flags = 0;
+    if (scan >> 8)
+        flags |= KeyExtended;
+    if (event->type == XKeyPress)
+        flags |= KeyPressed;
+
+    /* Remove the extended flag */
+    scan &= 0x7F;
+
+    switch (ks)
+    {
+        case XK_Print:
+            flags |= KeyPrint;
+            break;
+        case XK_Pause:
+            flags |= KeyPause;
+            break;
+    }
+
+    return keyEvent(ks, scan, flags);
+}
+
+#elif defined (Q_WS_MAC)
+
+bool UIMachineView::darwinKeyboardEvent(const void *pvCocoaEvent, EventRef inEvent)
+{
+    bool ret = false;
+    UInt32 EventKind = ::GetEventKind(inEvent);
+    if (EventKind != kEventRawKeyModifiersChanged)
+    {
+        /* convert keycode to set 1 scan code. */
+        UInt32 keyCode = ~0U;
+        ::GetEventParameter(inEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof (keyCode), NULL, &keyCode);
+        unsigned scanCode = ::DarwinKeycodeToSet1Scancode(keyCode);
+        if (scanCode)
+        {
+            /* calc flags. */
+            int flags = 0;
+            if (EventKind != kEventRawKeyUp)
+                flags |= KeyPressed;
+            if (scanCode & VBOXKEY_EXTENDED)
+                flags |= KeyExtended;
+            /** @todo KeyPause, KeyPrint. */
+            scanCode &= VBOXKEY_SCANCODE_MASK;
+
+            /* get the unicode string (if present). */
+            AssertCompileSize(wchar_t, 2);
+            AssertCompileSize(UniChar, 2);
+            ByteCount cbWritten = 0;
+            wchar_t ucs[8];
+            if (::GetEventParameter(inEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL,
+                                    sizeof(ucs), &cbWritten, &ucs[0]) != 0)
+                cbWritten = 0;
+            ucs[cbWritten / sizeof(wchar_t)] = 0; /* The api doesn't terminate it. */
+
+            ret = keyEvent(keyCode, scanCode, flags, ucs[0] ? ucs : NULL);
+        }
+    }
+    else
+    {
+        /* May contain multiple modifier changes, kind of annoying. */
+        UInt32 newMask = 0;
+        ::GetEventParameter(inEvent, kEventParamKeyModifiers, typeUInt32, NULL,
+                            sizeof(newMask), NULL, &newMask);
+        newMask = ::DarwinAdjustModifierMask(newMask, pvCocoaEvent);
+        UInt32 changed = newMask ^ mDarwinKeyModifiers;
+        if (changed)
+        {
+            for (UInt32 bit = 0; bit < 32; bit++)
+            {
+                if (!(changed & (1 << bit)))
+                    continue;
+                unsigned scanCode = ::DarwinModifierMaskToSet1Scancode(1 << bit);
+                if (!scanCode)
+                    continue;
+                unsigned keyCode = ::DarwinModifierMaskToDarwinKeycode(1 << bit);
+                Assert(keyCode);
+
+                if (!(scanCode & VBOXKEY_LOCK))
+                {
+                    unsigned flags = (newMask & (1 << bit)) ? KeyPressed : 0;
+                    if (scanCode & VBOXKEY_EXTENDED)
+                        flags |= KeyExtended;
+                    scanCode &= VBOXKEY_SCANCODE_MASK;
+                    ret |= keyEvent(keyCode, scanCode & 0xff, flags);
+                }
+                else
+                {
+                    unsigned flags = 0;
+                    if (scanCode & VBOXKEY_EXTENDED)
+                        flags |= KeyExtended;
+                    scanCode &= VBOXKEY_SCANCODE_MASK;
+                    keyEvent(keyCode, scanCode, flags | KeyPressed);
+                    keyEvent(keyCode, scanCode, flags);
+                }
+            }
+        }
+
+        mDarwinKeyModifiers = newMask;
+
+        /* Always return true here because we'll otherwise getting a Qt event
+           we don't want and that will only cause the Pause warning to pop up. */
+        ret = true;
+    }
+
+    return ret;
+}
+
+void UIMachineView::darwinGrabKeyboardEvents(bool fGrab)
+{
+    mKeyboardGrabbed = fGrab;
+    if (fGrab)
+    {
+        /* Disable mouse and keyboard event compression/delaying to make sure we *really* get all of the events. */
+        ::CGSetLocalEventsSuppressionInterval(0.0);
+        setMouseCoalescingEnabled(false);
+
+        /* Register the event callback/hook and grab the keyboard. */
+# ifdef QT_MAC_USE_COCOA
+        ::VBoxCocoaApplication_setCallback (UINT32_MAX, /** @todo fix mask */
+                                            UIMachineView::darwinEventHandlerProc, this);
+
+# elif !defined (VBOX_WITH_HACKED_QT)
+        EventTypeSpec eventTypes[6];
+        eventTypes[0].eventClass = kEventClassKeyboard;
+        eventTypes[0].eventKind  = kEventRawKeyDown;
+        eventTypes[1].eventClass = kEventClassKeyboard;
+        eventTypes[1].eventKind  = kEventRawKeyUp;
+        eventTypes[2].eventClass = kEventClassKeyboard;
+        eventTypes[2].eventKind  = kEventRawKeyRepeat;
+        eventTypes[3].eventClass = kEventClassKeyboard;
+        eventTypes[3].eventKind  = kEventRawKeyModifiersChanged;
+        /* For ignorning Command-H and Command-Q which aren't affected by the
+         * global hotkey stuff (doesn't work well): */
+        eventTypes[4].eventClass = kEventClassCommand;
+        eventTypes[4].eventKind  = kEventCommandProcess;
+        eventTypes[5].eventClass = kEventClassCommand;
+        eventTypes[5].eventKind  = kEventCommandUpdateStatus;
+
+        EventHandlerUPP eventHandler = ::NewEventHandlerUPP(UIMachineView::darwinEventHandlerProc);
+
+        mDarwinEventHandlerRef = NULL;
+        ::InstallApplicationEventHandler(eventHandler, RT_ELEMENTS (eventTypes), &eventTypes[0],
+                                         this, &mDarwinEventHandlerRef);
+        ::DisposeEventHandlerUPP(eventHandler);
+
+# else  /* VBOX_WITH_HACKED_QT */
+        ((QIApplication *)qApp)->setEventFilter(UIMachineView::macEventFilter, this);
+# endif /* VBOX_WITH_HACKED_QT */
+
+        ::DarwinGrabKeyboard (false);
+    }
+    else
+    {
+        ::DarwinReleaseKeyboard();
+# ifdef QT_MAC_USE_COCOA
+        ::VBoxCocoaApplication_unsetCallback(UINT32_MAX, /** @todo fix mask */
+                                             UIMachineView::darwinEventHandlerProc, this);
+# elif !defined(VBOX_WITH_HACKED_QT)
+        if (mDarwinEventHandlerRef)
+        {
+            ::RemoveEventHandler(mDarwinEventHandlerRef);
+            mDarwinEventHandlerRef = NULL;
+        }
+# else  /* VBOX_WITH_HACKED_QT */
+        ((QIApplication *)qApp)->setEventFilter(NULL, NULL);
+# endif /* VBOX_WITH_HACKED_QT */
+    }
+}
+
+#endif
+
+#if defined (Q_WS_WIN32)
+static HHOOK gKbdHook = NULL;
+static UIMachineView *gView = 0;
+LRESULT CALLBACK UIMachineView::lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+    Assert (gView);
+    if (gView && nCode == HC_ACTION &&
+            gView->winLowKeyboardEvent (wParam, *(KBDLLHOOKSTRUCT *) lParam))
+        return 1;
+
+    return CallNextHookEx (NULL, nCode, wParam, lParam);
+}
+#endif
+
+#if defined (Q_WS_MAC)
+# if defined (QT_MAC_USE_COCOA)
+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 (VBoxCocoaApplication_isApplicationCommand(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;
+}
+
+# elif !defined (VBOX_WITH_HACKED_QT)
+
+pascal OSStatus UIMachineView::darwinEventHandlerProc (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
+{
+    UIMachineView *view = static_cast<UIMachineView *> (inUserData);
+    UInt32 eventClass = ::GetEventClass (inEvent);
+
+    /* Not sure but this seems an triggered event if the spotlight searchbar is
+     * displayed. So flag that the host key isn't pressed alone. */
+    if (eventClass == 'cgs ' && view->m_bIsHostkeyPressed && ::GetEventKind (inEvent) == 0x15)
+        view->m_bIsHostkeyAlone = false;
+
+    if (eventClass == kEventClassKeyboard)
+    {
+        if (view->darwinKeyboardEvent (NULL, inEvent))
+            return 0;
+    }
+
+    /*
+     * Command-H and Command-Q aren't properly disabled yet, and it's still
+     * possible to use the left command key to invoke them when the keyboard
+     * is captured. We discard the events these if the keyboard is captured
+     * as a half measure to prevent unexpected behaviour. However, we don't
+     * get any key down/up events, so these combinations are dead to the guest...
+     */
+    else if (eventClass == kEventClassCommand)
+    {
+        if (view->m_bIsKeyboardCaptured)
+            return 0;
+    }
+    return ::CallNextEventHandler(inHandlerCallRef, inEvent);
+}
+
+# else /* VBOX_WITH_HACKED_QT */
+
+bool UIMachineView::macEventFilter(EventRef inEvent, void *inUserData)
+{
+    UIMachineView *view = static_cast<UIMachineView *>(inUserData);
+    UInt32 eventClass = ::GetEventClass(inEvent);
+    UInt32 eventKind = ::GetEventKind(inEvent);
+
+    /* Not sure but this seems an triggered event if the spotlight searchbar is
+     * displayed. So flag that the host key isn't pressed alone. */
+    if (eventClass == 'cgs ' && eventKind == 0x15 &&
+        view->m_bIsHostkeyPressed)
+        view->m_bIsHostkeyAlone = false;
+
+    if (eventClass == kEventClassKeyboard)
+    {
+        if (view->darwinKeyboardEvent (NULL, inEvent))
+            return true;
+    }
+    return false;
+}
+# endif /* VBOX_WITH_HACKED_QT */
+
+#endif /* Q_WS_MAC */
+
+void UIMachineView::focusEvent(bool aHasFocus, bool aReleaseHostKey /* = true */)
+{
+    if (aHasFocus)
+    {
+#ifdef RT_OS_WINDOWS
+        if (!m_bIsAutoCaptureDisabled && m_globalSettings.autoCapture() && GetAncestor(winId(), GA_ROOT) == GetForegroundWindow())
+#else
+        if (!m_bIsAutoCaptureDisabled && m_globalSettings.autoCapture())
+#endif /* RT_OS_WINDOWS */
+        {
+            captureKbd(true);
+        }
+
+        /* reset the single-time disable capture flag */
+        if (m_bIsAutoCaptureDisabled)
+            m_bIsAutoCaptureDisabled = false;
+    }
+    else
+    {
+        captureMouse(false);
+        captureKbd(false, false);
+        releaseAllPressedKeys(aReleaseHostKey);
+    }
+}
+
+bool UIMachineView::keyEvent(int aKey, uint8_t aScan, int aFlags, wchar_t *aUniKey /* = NULL */)
+{
+    const bool isHostKey = aKey == m_globalSettings.hostKey();
+
+    LONG buf[16];
+    LONG *codes = buf;
+    uint count = 0;
+    uint8_t whatPressed = 0;
+
+    if (!isHostKey && !m_bIsHostkeyPressed)
+    {
+        if (aFlags & KeyPrint)
+        {
+            static LONG PrintMake[] = { 0xE0, 0x2A, 0xE0, 0x37 };
+            static LONG PrintBreak[] = { 0xE0, 0xB7, 0xE0, 0xAA };
+            if (aFlags & KeyPressed)
+            {
+                codes = PrintMake;
+                count = SIZEOF_ARRAY(PrintMake);
+            }
+            else
+            {
+                codes = PrintBreak;
+                count = SIZEOF_ARRAY(PrintBreak);
+            }
+        }
+        else if (aFlags & KeyPause)
+        {
+            if (aFlags & KeyPressed)
+            {
+                static LONG Pause[] = { 0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5 };
+                codes = Pause;
+                count = SIZEOF_ARRAY(Pause);
+            }
+            else
+            {
+                /* Pause shall not produce a break code */
+                return true;
+            }
+        }
+        else
+        {
+            if (aFlags & KeyPressed)
+            {
+                /* Check if the guest has the same view on the modifier keys (NumLock,
+                 * CapsLock, ScrollLock) as the X server. If not, send KeyPress events
+                 * to synchronize the state. */
+                fixModifierState(codes, &count);
+            }
+
+            /* Check if it's C-A-D and GUI/PassCAD is not true */
+            if (!mPassCAD &&
+                aScan == 0x53 /* Del */ &&
+                ((mPressedKeys [0x38] & IsKeyPressed) /* Alt */ ||
+                 (mPressedKeys [0x38] & IsExtKeyPressed)) &&
+                ((mPressedKeys [0x1d] & IsKeyPressed) /* Ctrl */ ||
+                 (mPressedKeys [0x1d] & IsExtKeyPressed)))
+            {
+                /* Use the C-A-D combination as a last resort to get the
+                 * keyboard and mouse back to the host when the user forgets
+                 * the Host Key. Note that it's always possible to send C-A-D
+                 * to the guest using the Host+Del combination. BTW, it would
+                 * be preferrable to completely ignore C-A-D in guests, but
+                 * that's not possible because we cannot predict what other
+                 * keys will be pressed next when one of C, A, D is held. */
+
+                if (isRunning() && m_bIsKeyboardCaptured)
+                {
+                    captureKbd (false);
+                    if (!(m_bIsMouseAbsolute && m_bIsMouseIntegrated))
+                        captureMouse (false);
+                }
+
+                return true;
+            }
+
+            /* process the scancode and update the table of pressed keys */
+            whatPressed = IsKeyPressed;
+
+            if (aFlags & KeyExtended)
+            {
+                codes[count++] = 0xE0;
+                whatPressed = IsExtKeyPressed;
+            }
+
+            if (aFlags & KeyPressed)
+            {
+                codes[count++] = aScan;
+                mPressedKeys[aScan] |= whatPressed;
+            }
+            else
+            {
+                /* if we haven't got this key's press message, we ignore its
+                 * release */
+                if (!(mPressedKeys [aScan] & whatPressed))
+                    return true;
+                codes[count++] = aScan | 0x80;
+                mPressedKeys[aScan] &= ~whatPressed;
+            }
+
+            if (m_bIsKeyboardCaptured)
+                mPressedKeys[aScan] |= IsKbdCaptured;
+            else
+                mPressedKeys[aScan] &= ~IsKbdCaptured;
+        }
+    }
+    else
+    {
+        /* currently this is used in winLowKeyboardEvent() only */
+        hostkey_in_capture = m_bIsKeyboardCaptured;
+    }
+
+    bool emitSignal = false;
+    int hotkey = 0;
+
+    /* process the host key */
+    if (aFlags & KeyPressed)
+    {
+        if (isHostKey)
+        {
+            if (!m_bIsHostkeyPressed)
+            {
+                m_bIsHostkeyPressed = m_bIsHostkeyAlone = true;
+                if (isRunning())
+                    saveKeyStates();
+                emitSignal = true;
+            }
+        }
+        else
+        {
+            if (m_bIsHostkeyPressed)
+            {
+                if (m_bIsHostkeyAlone)
+                {
+                    hotkey = aKey;
+                    m_bIsHostkeyAlone = false;
+                }
+            }
+        }
+    }
+    else
+    {
+        if (isHostKey)
+        {
+            if (m_bIsHostkeyPressed)
+            {
+                m_bIsHostkeyPressed = false;
+
+                if (m_bIsHostkeyAlone)
+                {
+                    if (machineWindowWrapper()->machineLogic()->isPaused())
+                    {
+                        vboxProblem().remindAboutPausedVMInput();
+                    }
+                    else if (isRunning())
+                    {
+                        bool captured = m_bIsKeyboardCaptured;
+                        bool ok = true;
+                        if (!captured)
+                        {
+                            /* temporarily disable auto capture that will take
+                             * place after this dialog is dismissed because
+                             * the capture state is to be defined by the
+                             * dialog result itself */
+                            m_bIsAutoCaptureDisabled = true;
+                            bool autoConfirmed = false;
+                            ok = vboxProblem().confirmInputCapture (&autoConfirmed);
+                            if (autoConfirmed)
+                                m_bIsAutoCaptureDisabled = false;
+                            /* otherwise, the disable flag will be reset in
+                             * the next console view's foucs in event (since
+                             * may happen asynchronously on some platforms,
+                             * after we return from this code) */
+                        }
+
+                        if (ok)
+                        {
+                            captureKbd (!captured, false);
+                            if (!(m_bIsMouseAbsolute && m_bIsMouseIntegrated))
+                            {
+#ifdef Q_WS_X11
+                                /* make sure that pending FocusOut events from the
+                                 * previous message box are handled, otherwise the
+                                 * mouse is immediately ungrabbed. */
+                                qApp->processEvents();
+#endif
+                                captureMouse (m_bIsKeyboardCaptured);
+                            }
+                        }
+                    }
+                }
+
+                if (isRunning())
+                    sendChangedKeyStates();
+
+                emitSignal = true;
+            }
+        }
+        else
+        {
+            if (m_bIsHostkeyPressed)
+                m_bIsHostkeyAlone = false;
+        }
+    }
+
+    /* emit the keyboard state change signal */
+    if (emitSignal)
+        emitKeyboardStateChanged();
+
+    /* Process Host+<key> shortcuts. currently, <key> is limited to
+     * alphanumeric chars. Other Host+<key> combinations are handled in
+     * event(). */
+    if (hotkey)
+    {
+        bool processed = false;
+#if defined (Q_WS_WIN32)
+        NOREF(aUniKey);
+        int n = GetKeyboardLayoutList (0, NULL);
+        Assert (n);
+        HKL *list = new HKL [n];
+        GetKeyboardLayoutList (n, list);
+        for (int i = 0; i < n && !processed; i++)
+        {
+            wchar_t ch;
+            static BYTE keys [256] = {0};
+            if (!ToUnicodeEx (hotkey, 0, keys, &ch, 1, 0, list [i]) == 1)
+                ch = 0;
+            if (ch)
+                processed = processHotKey (QKeySequence (Qt::UNICODE_ACCEL +
+                                                QChar (ch).toUpper().unicode()),
+                                           machineWindowWrapper()->menuBar()->actions());
+        }
+        delete[] list;
+#elif defined (Q_WS_X11)
+        NOREF(aUniKey);
+        Display *display = QX11Info::display();
+        int keysyms_per_keycode = getKeysymsPerKeycode();
+        KeyCode kc = XKeysymToKeycode (display, aKey);
+        // iterate over the first level (not shifted) keysyms in every group
+        for (int i = 0; i < keysyms_per_keycode && !processed; i += 2)
+        {
+            KeySym ks = XKeycodeToKeysym (display, kc, i);
+            char ch = 0;
+            if (!XkbTranslateKeySym (display, &ks, 0, &ch, 1, NULL) == 1)
+                ch = 0;
+            if (ch)
+            {
+                QChar c = QString::fromLocal8Bit (&ch, 1) [0];
+            }
+        }
+#elif defined (Q_WS_MAC)
+        if (aUniKey && aUniKey [0] && !aUniKey [1])
+            processed = processHotKey (QKeySequence (Qt::UNICODE_ACCEL +
+                                                     QChar (aUniKey [0]).toUpper().unicode()),
+                                       machineWindowWrapper()->menuBar()->actions());
+
+        /* Don't consider the hot key as pressed since the guest never saw
+         * it. (probably a generic thing) */
+        mPressedKeys [aScan] &= ~whatPressed;
+#endif
+
+        /* grab the key from Qt if processed, or pass it to Qt otherwise
+         * in order to process non-alphanumeric keys in event(), after they are
+         * converted to Qt virtual keys. */
+        return processed;
+    }
+
+    /* no more to do, if the host key is in action or the VM is paused */
+    if (m_bIsHostkeyPressed || isHostKey || machineWindowWrapper()->machineLogic()->isPaused())
+    {
+        /* grab the key from Qt and from VM if it's a host key,
+         * otherwise just pass it to Qt */
+        return isHostKey;
+    }
+
+    CKeyboard keyboard = m_console.GetKeyboard();
+    Assert (!keyboard.isNull());
+
+#if defined (Q_WS_WIN32)
+    /* send pending WM_PAINT events */
+    ::UpdateWindow (viewport()->winId());
+#endif
+
+    std::vector <LONG> scancodes(codes, &codes[count]);
+    keyboard.PutScancodes (QVector<LONG>::fromStdVector(scancodes));
+
+    /* grab the key from Qt */
+    return true;
+}
+
+bool UIMachineView::mouseEvent(int aType, const QPoint &aPos, const QPoint &aGlobalPos,
+                               Qt::MouseButtons aButtons, Qt::KeyboardModifiers aModifiers,
+                               int aWheelDelta, Qt::Orientation aWheelDir)
+{
+#if 1
+    LogRel3(("%s: type=%03d x=%03d y=%03d btns=%08X wdelta=%03d wdir=%s\n",
+             __PRETTY_FUNCTION__ , aType, aPos.x(), aPos.y(),
+               (aButtons & Qt::LeftButton ? 1 : 0)
+             | (aButtons & Qt::RightButton ? 2 : 0)
+             | (aButtons & Qt::MidButton ? 4 : 0)
+             | (aButtons & Qt::XButton1 ? 8 : 0)
+             | (aButtons & Qt::XButton2 ? 16 : 0),
+             aWheelDelta,
+               aWheelDir == Qt::Horizontal ? "Horizontal"
+             : aWheelDir == Qt::Vertical ? "Vertical" : "Unknown"));
+    Q_UNUSED (aModifiers);
+#else
+    Q_UNUSED (aModifiers);
+#endif
+
+    int state = 0;
+    if (aButtons & Qt::LeftButton)
+        state |= KMouseButtonState_LeftButton;
+    if (aButtons & Qt::RightButton)
+        state |= KMouseButtonState_RightButton;
+    if (aButtons & Qt::MidButton)
+        state |= KMouseButtonState_MiddleButton;
+    if (aButtons & Qt::XButton1)
+        state |= KMouseButtonState_XButton1;
+    if (aButtons & Qt::XButton2)
+        state |= KMouseButtonState_XButton2;
+
+#ifdef Q_WS_MAC
+    /* Simulate the right click on
+     * Host+Left Mouse */
+    if (m_bIsHostkeyPressed &&
+        m_bIsHostkeyAlone &&
+        state == KMouseButtonState_LeftButton)
+        state = KMouseButtonState_RightButton;
+#endif /* Q_WS_MAC */
+
+    int wheelVertical = 0;
+    int wheelHorizontal = 0;
+    if (aWheelDir == Qt::Vertical)
+    {
+        /* the absolute value of wheel delta is 120 units per every wheel
+         * move; positive deltas correspond to counterclockwize rotations
+         * (usually up), negative -- to clockwize (usually down). */
+        wheelVertical = - (aWheelDelta / 120);
+    }
+    else if (aWheelDir == Qt::Horizontal)
+        wheelHorizontal = aWheelDelta / 120;
+
+    if (m_bIsMouseCaptured)
+    {
+#ifdef Q_WS_WIN32
+        /* send pending WM_PAINT events */
+        ::UpdateWindow (viewport()->winId());
+#endif
+
+        CMouse mouse = m_console.GetMouse();
+        mouse.PutMouseEvent (aGlobalPos.x() - mLastPos.x(),
+                             aGlobalPos.y() - mLastPos.y(),
+                             wheelVertical, wheelHorizontal, state);
+
+#if defined (Q_WS_MAC)
+        /*
+         * Keep the mouse from leaving the widget.
+         *
+         * This is a bit tricky to get right because if it escapes we won't necessarily
+         * get mouse events any longer and can warp it back. So, we keep safety zone
+         * of up to 300 pixels around the borders of the widget to prevent this from
+         * happening. Also, the mouse is warped back to the center of the widget.
+         *
+         * (Note, aPos seems to be unreliable, it caused endless recursion here at one points...)
+         * (Note, synergy and other remote clients might not like this cursor warping.)
+         */
+        QRect rect = viewport()->visibleRegion().boundingRect();
+        QPoint pw = viewport()->mapToGlobal (viewport()->pos());
+        rect.translate (pw.x(), pw.y());
+
+        QRect dpRect = QApplication::desktop()->screenGeometry (viewport());
+        if (rect.intersects (dpRect))
+            rect = rect.intersect (dpRect);
+
+        int wsafe = rect.width() / 6;
+        rect.setWidth (rect.width() - wsafe * 2);
+        rect.setLeft (rect.left() + wsafe);
+
+        int hsafe = rect.height() / 6;
+        rect.setWidth (rect.height() - hsafe * 2);
+        rect.setTop (rect.top() + hsafe);
+
+        if (rect.contains (aGlobalPos, true))
+            mLastPos = aGlobalPos;
+        else
+        {
+            mLastPos = rect.center();
+            QCursor::setPos (mLastPos);
+        }
+
+#else /* !Q_WS_MAC */
+
+        /* "jerk" the mouse by bringing it to the opposite side
+         * to simulate the endless moving */
+
+#ifdef Q_WS_WIN32
+        int we = viewport()->width() - 1;
+        int he = viewport()->height() - 1;
+        QPoint p = aPos;
+        if (aPos.x() == 0)
+            p.setX (we - 1);
+        else if (aPos.x() == we)
+            p.setX (1);
+        if (aPos.y() == 0 )
+            p.setY (he - 1);
+        else if (aPos.y() == he)
+            p.setY (1);
+
+        if (p != aPos)
+        {
+            mLastPos = viewport()->mapToGlobal (p);
+            QCursor::setPos (mLastPos);
+        }
+        else
+        {
+            mLastPos = aGlobalPos;
+        }
+#else
+        int we = QApplication::desktop()->width() - 1;
+        int he = QApplication::desktop()->height() - 1;
+        QPoint p = aGlobalPos;
+        if (aGlobalPos.x() == 0)
+            p.setX (we - 1);
+        else if (aGlobalPos.x() == we)
+            p.setX( 1 );
+        if (aGlobalPos.y() == 0)
+            p.setY (he - 1);
+        else if (aGlobalPos.y() == he)
+            p.setY (1);
+
+        if (p != aGlobalPos)
+        {
+            mLastPos =  p;
+            QCursor::setPos (mLastPos);
+        }
+        else
+        {
+            mLastPos = aGlobalPos;
+        }
+#endif
+#endif /* !Q_WS_MAC */
+        return true; /* stop further event handling */
+    }
+    else /* !m_bIsMouseCaptured */
+    {
+        //if (machineWindowWrapper()->isTrueFullscreen()) // TODO check that!
+        {
+            if (mode != VBoxDefs::SDLMode)
+            {
+                /* try to automatically scroll the guest canvas if the
+                 * mouse is on the screen border */
+                /// @todo (r=dmik) better use a timer for autoscroll
+                QRect scrGeo = QApplication::desktop()->screenGeometry (this);
+                int dx = 0, dy = 0;
+                if (scrGeo.width() < contentsWidth())
+                {
+                    if (scrGeo.left() == aGlobalPos.x()) dx = -1;
+                    if (scrGeo.right() == aGlobalPos.x()) dx = +1;
+                }
+                if (scrGeo.height() < contentsHeight())
+                {
+                    if (scrGeo.top() == aGlobalPos.y()) dy = -1;
+                    if (scrGeo.bottom() == aGlobalPos.y()) dy = +1;
+                }
+                if (dx || dy)
+                    scrollBy (dx, dy);
+            }
+        }
+
+        if (m_bIsMouseAbsolute && m_bIsMouseIntegrated)
+        {
+            int cw = contentsWidth(), ch = contentsHeight();
+            int vw = visibleWidth(), vh = visibleHeight();
+
+            if (mode != VBoxDefs::SDLMode)
+            {
+                /* try to automatically scroll the guest canvas if the
+                 * mouse goes outside its visible part */
+
+                int dx = 0;
+                if (aPos.x() > vw) dx = aPos.x() - vw;
+                else if (aPos.x() < 0) dx = aPos.x();
+                int dy = 0;
+                if (aPos.y() > vh) dy = aPos.y() - vh;
+                else if (aPos.y() < 0) dy = aPos.y();
+                if (dx != 0 || dy != 0) scrollBy (dx, dy);
+            }
+
+            QPoint cpnt = viewportToContents (aPos);
+            if (cpnt.x() < 0) cpnt.setX (0);
+            else if (cpnt.x() > cw) cpnt.setX (cw);
+            if (cpnt.y() < 0) cpnt.setY (0);
+            else if (cpnt.y() > ch) cpnt.setY (ch);
+
+            CMouse mouse = m_console.GetMouse();
+            mouse.PutMouseEventAbsolute (cpnt.x(), cpnt.y(), wheelVertical,
+                                         wheelHorizontal, state);
+            return true; /* stop further event handling */
+        }
+        else
+        {
+            if (hasFocus() &&
+                (aType == QEvent::MouseButtonRelease &&
+                 aButtons == Qt::NoButton))
+            {
+                if (machineWindowWrapper()->machineLogic()->isPaused())
+                {
+                    vboxProblem().remindAboutPausedVMInput();
+                }
+                else if (isRunning())
+                {
+                    /* temporarily disable auto capture that will take
+                     * place after this dialog is dismissed because
+                     * the capture state is to be defined by the
+                     * dialog result itself */
+                    m_bIsAutoCaptureDisabled = true;
+                    bool autoConfirmed = false;
+                    bool ok = vboxProblem().confirmInputCapture (&autoConfirmed);
+                    if (autoConfirmed)
+                        m_bIsAutoCaptureDisabled = false;
+                    /* otherwise, the disable flag will be reset in
+                     * the next console view's foucs in event (since
+                     * may happen asynchronously on some platforms,
+                     * after we return from this code) */
+
+                    if (ok)
+                    {
+#ifdef Q_WS_X11
+                        /* make sure that pending FocusOut events from the
+                         * previous message box are handled, otherwise the
+                         * mouse is immediately ungrabbed again */
+                        qApp->processEvents();
+#endif
+                        captureKbd (true);
+                        captureMouse (true);
+                    }
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
+void UIMachineView::resizeEvent(QResizeEvent *)
+{
+    updateSliders();
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+    QRect r = viewport()->geometry();
+    PostBoundsChanged(r);
+#endif /* Q_WS_MAC */
+}
+
+void UIMachineView::moveEvent(QMoveEvent *)
+{
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+    QRect r = viewport()->geometry();
+    PostBoundsChanged (r);
+#endif /* Q_WS_MAC */
+}
+
+void UIMachineView::paintEvent(QPaintEvent *pe)
+{
+    if (mPausedShot.isNull())
+    {
+        /* delegate the paint function to the VBoxFrameBuffer interface */
+        if (mFrameBuf)
+            mFrameBuf->paintEvent(pe);
+#ifdef Q_WS_MAC
+        /* Update the dock icon if we are in the running state */
+        if (isRunning())
+            updateDockIcon();
+#endif
+        return;
+    }
+
+#ifdef VBOX_GUI_USE_QUARTZ2D
+    if (mode == VBoxDefs::Quartz2DMode && mFrameBuf)
+    {
+        mFrameBuf->paintEvent(pe);
+        updateDockIcon();
+    }
+    else
+#endif
+    {
+        /* We have a snapshot for the paused state: */
+        QRect r = pe->rect().intersect (viewport()->rect());
+        /* We have to disable paint on screen if we are using the regular painter */
+        bool paintOnScreen = viewport()->testAttribute(Qt::WA_PaintOnScreen);
+        viewport()->setAttribute(Qt::WA_PaintOnScreen, false);
+        QPainter pnt(viewport());
+        pnt.drawPixmap(r.x(), r.y(), mPausedShot,
+                       r.x() + contentsX(), r.y() + contentsY(),
+                       r.width(), r.height());
+        /* Restore the attribute to its previous state */
+        viewport()->setAttribute(Qt::WA_PaintOnScreen, paintOnScreen);
+#ifdef Q_WS_MAC
+        updateDockIcon();
+#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 (muNumLockAdaptionCnt && (mNumLock ^ !!(uMask & uKeyMaskNum)))
+    {
+        -- muNumLockAdaptionCnt;
+        piCodes[(*puCount)++] = 0x45;
+        piCodes[(*puCount)++] = 0x45 | 0x80;
+    }
+    if (muCapsLockAdaptionCnt && (mCapsLock ^ !!(uMask & uKeyMaskCaps)))
+    {
+        muCapsLockAdaptionCnt--;
+        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 (mCapsLock && !(mPressedKeys [0x2a] & IsKeyPressed))
+        {
+            piCodes[(*puCount)++] = 0x2a;
+            piCodes[(*puCount)++] = 0x2a | 0x80;
+        }
+    }
+
+#elif defined (Q_WS_WIN32)
+
+    if (muNumLockAdaptionCnt && (mNumLock ^ !!(GetKeyState(VK_NUMLOCK))))
+    {
+        muNumLockAdaptionCnt--;
+        piCodes[(*puCount)++] = 0x45;
+        piCodes[(*puCount)++] = 0x45 | 0x80;
+    }
+    if (muCapsLockAdaptionCnt && (mCapsLock ^ !!(GetKeyState(VK_CAPITAL))))
+    {
+        muCapsLockAdaptionCnt--;
+        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 (mCapsLock && !(mPressedKeys [0x2a] & IsKeyPressed))
+        {
+            piCodes[(*puCount)++] = 0x2a;
+            piCodes[(*puCount)++] = 0x2a | 0x80;
+        }
+    }
+
+#elif defined (Q_WS_MAC)
+
+    /* if (muNumLockAdaptionCnt) ... - NumLock isn't implemented by Mac OS X so ignore it. */
+    if (muCapsLockAdaptionCnt && (mCapsLock ^ !!(::GetCurrentEventKeyModifiers() & alphaLock)))
+    {
+        muCapsLockAdaptionCnt--;
+        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 (mCapsLock && !(mPressedKeys [0x2a] & IsKeyPressed))
+        {
+            piCodes[(*puCount)++] = 0x2a;
+            piCodes[(*puCount)++] = 0x2a | 0x80;
+        }
+    }
+
+#else
+
+//#warning Adapt UIMachineView::fixModifierState
+
+#endif
+}
+
+void UIMachineView::scrollBy(int dx, int dy)
+{
+    horizontalScrollBar()->setValue(horizontalScrollBar()->value() + dx);
+    verticalScrollBar()->setValue(verticalScrollBar()->value() + dy);
+}
+
+QPoint UIMachineView::viewportToContents(const QPoint &vp) const
+{
+    return QPoint (vp.x() + contentsX(), vp.y() + contentsY());
+}
+
+void UIMachineView::updateSliders()
+{
+    QSize p = viewport()->size();
+    QSize m = maximumViewportSize();
+
+    QSize v = QSize(mFrameBuf->width(), mFrameBuf->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());
+}
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+void UIMachineView::scrollContentsBy (int dx, int dy)
+{
+    if (mFrameBuf)
+    {
+        mFrameBuf->viewportScrolled(dx, dy);
+    }
+    QAbstractScrollArea::scrollContentsBy (dx, dy);
+}
+#endif
+
+#if defined(Q_WS_MAC)
+void UIMachineView::updateDockIcon()
+{
+    if (mDockIconEnabled)
+    {
+        if (!mPausedShot.isNull())
+        {
+            CGImageRef pauseImg = ::darwinToCGImageRef (&mPausedShot);
+            /* Use the pause image as background */
+            mDockIconPreview->updateDockPreview (pauseImg);
+            CGImageRelease (pauseImg);
+        }
+        else
+        {
+# if defined (VBOX_GUI_USE_QUARTZ2D)
+            if (mode == 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. */
+                mDockIconPreview->updateDockPreview (static_cast <VBoxQuartz2DFrameBuffer *> (mFrameBuf)->imageRef());
+            }
+            else
+# endif
+                /* In image mode we have to create the image ref out of the
+                 * framebuffer */
+                mDockIconPreview->updateDockPreview (mFrameBuf);
+        }
+    }
+}
+
+void UIMachineView::updateDockOverlay()
+{
+    /* Only to an update to the realtime preview if this is enabled by the user
+     * & we are in an state where the framebuffer is likely valid. Otherwise to
+     * the overlay stuff only. */
+    if (mDockIconEnabled &&
+        (mLastState == KMachineState_Running ||
+         mLastState == KMachineState_Paused ||
+         mLastState == KMachineState_Teleporting ||
+         mLastState == KMachineState_LiveSnapshotting ||
+         mLastState == KMachineState_Restoring ||
+         mLastState == KMachineState_TeleportingPausedVM ||
+         mLastState == KMachineState_TeleportingIn ||
+         mLastState == KMachineState_Saving))
+        updateDockIcon();
+    else
+        mDockIconPreview->updateDockOverlay();
+}
+
+void UIMachineView::setMouseCoalescingEnabled (bool aOn)
+{
+    /* Enable mouse event compression if we leave the VM view. This
+       is necessary for having smooth resizing of the VM/other
+       windows.
+       Disable mouse event compression if we enter the VM view. So
+       all mouse events are registered in the VM. Only do this if
+       the keyboard/mouse is grabbed (this is when we have a valid
+       event handler). */
+    if (aOn || mKeyboardGrabbed)
+        ::darwinSetMouseCoalescingEnabled (aOn);
+}
+#endif /* Q_WS_MAC */
+
+void UIMachineView::onStateChange(KMachineState state)
+{
+    switch (state)
+    {
+        case KMachineState_Paused:
+        case KMachineState_TeleportingPausedVM:
+        {
+            if (    mode != VBoxDefs::TimerMode
+                &&  mFrameBuf
+                &&  (   state      != KMachineState_TeleportingPausedVM
+                     || mLastState != KMachineState_Teleporting)
+               )
+            {
+                /*
+                 *  Take a screen snapshot. Note that TakeScreenShot() always
+                 *  needs a 32bpp image
+                 */
+                QImage shot = QImage (mFrameBuf->width(), mFrameBuf->height(), QImage::Format_RGB32);
+                CDisplay dsp = m_console.GetDisplay();
+                dsp.TakeScreenShot (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);
+                    mPausedShot = QPixmap::fromImage (shot);
+                    /* fully repaint to pick up mPausedShot */
+                    repaint();
+                }
+            }
+            /* fall through */
+        }
+        case KMachineState_Stuck:
+        {
+            /* reuse the focus event handler to uncapture everything */
+            if (hasFocus())
+                focusEvent (false /* aHasFocus*/, false /* aReleaseHostKey */);
+            break;
+        }
+        case KMachineState_Running:
+        {
+            if (   mLastState == KMachineState_Paused
+                || mLastState == KMachineState_TeleportingPausedVM
+               )
+            {
+                if (mode != VBoxDefs::TimerMode && mFrameBuf)
+                {
+                    /* reset the pixmap to free memory */
+                    mPausedShot = QPixmap ();
+                    /*
+                     *  ask for full guest display update (it will also update
+                     *  the viewport through IFramebuffer::NotifyUpdate)
+                     */
+                    CDisplay dsp = m_console.GetDisplay();
+                    dsp.InvalidateAndUpdate();
+                }
+            }
+            /* reuse the focus event handler to capture input */
+            if (hasFocus())
+                focusEvent (true /* aHasFocus */);
+            break;
+        }
+        default:
+            break;
+    }
+
+    mLastState = state;
+}
+
+void UIMachineView::captureKbd(bool aCapture, bool aEmitSignal /* = true */)
+{
+    //AssertMsg(m_bIsAttached, ("Console must be attached"));
+
+    if (m_bIsKeyboardCaptured == aCapture)
+        return;
+
+    /* On Win32, keyboard grabbing is ineffective, a low-level keyboard hook is
+     * used instead. On X11, we use XGrabKey instead of XGrabKeyboard (called
+     * by QWidget::grabKeyboard()) because the latter causes problems under
+     * metacity 2.16 (in particular, due to a bug, a window cannot be moved
+     * using the mouse if it is currently grabing the keyboard). On Mac OS X,
+     * we use the Qt methods + disabling global hot keys + watching modifiers
+     * (for right/left separation). */
+#if defined (Q_WS_WIN32)
+    /**/
+#elif defined (Q_WS_X11)
+	if (aCapture)
+		XGrabKey(QX11Info::display(), AnyKey, AnyModifier, window()->winId(), False, GrabModeAsync, GrabModeAsync);
+	else
+		XUngrabKey(QX11Info::display(),  AnyKey, AnyModifier, window()->winId());
+#elif defined (Q_WS_MAC)
+    if (aCapture)
+    {
+        ::DarwinDisableGlobalHotKeys(true);
+        grabKeyboard();
+    }
+    else
+    {
+        ::DarwinDisableGlobalHotKeys(false);
+        releaseKeyboard();
+    }
+#else
+    if (aCapture)
+        grabKeyboard();
+    else
+        releaseKeyboard();
+#endif
+
+    m_bIsKeyboardCaptured = aCapture;
+
+    if (aEmitSignal)
+        emitKeyboardStateChanged();
+}
+
+void UIMachineView::captureMouse(bool aCapture, bool aEmitSignal /* = true */)
+{
+    //AssertMsg (m_bIsAttached, ("Console must be attached"));
+
+    if (m_bIsMouseCaptured == aCapture)
+        return;
+
+    if (aCapture)
+    {
+        /* memorize the host position where the cursor was captured */
+        mCapturedPos = QCursor::pos();
+#ifdef Q_WS_WIN32
+        viewport()->setCursor (QCursor (Qt::BlankCursor));
+        /* move the mouse to the center of the visible area */
+        QCursor::setPos (mapToGlobal (visibleRegion().boundingRect().center()));
+        mLastPos = QCursor::pos();
+#elif defined (Q_WS_MAC)
+        /* move the mouse to the center of the visible area */
+        mLastPos = mapToGlobal (visibleRegion().boundingRect().center());
+        QCursor::setPos (mLastPos);
+        /* grab all mouse events. */
+        viewport()->grabMouse();
+#else
+        viewport()->grabMouse();
+        mLastPos = QCursor::pos();
+#endif
+    }
+    else
+    {
+#ifndef Q_WS_WIN32
+        viewport()->releaseMouse();
+#endif
+        /* release mouse buttons */
+        CMouse mouse = m_console.GetMouse();
+        mouse.PutMouseEvent (0, 0, 0, 0 /* Horizontal wheel */, 0);
+    }
+
+    m_bIsMouseCaptured = aCapture;
+
+    updateMouseClipping();
+
+    if (aEmitSignal)
+        emitMouseStateChanged();
+}
+
+bool UIMachineView::processHotKey(const QKeySequence &aKey, const QList <QAction*> &aData)
+{
+    foreach (QAction *pAction, aData)
+    {
+        if (QMenu *menu = pAction->menu())
+        {
+            /* Process recursively for each sub-menu */
+            if (processHotKey(aKey, menu->actions()))
+                return true;
+        }
+        else
+        {
+            QString hotkey = VBoxGlobal::extractKeyFromActionText(pAction->text());
+            if (pAction->isEnabled() && !hotkey.isEmpty())
+            {
+                if (aKey.matches(QKeySequence (hotkey)) == QKeySequence::ExactMatch)
+                {
+                    /* We asynchronously post a special event instead of calling
+                     * pAction->trigger() directly, to let key presses and
+                     * releases be processed correctly by Qt first.
+                     * Note: we assume that nobody will delete the menu item
+                     * corresponding to the key sequence, so that the pointer to
+                     * menu data posted along with the event will remain valid in
+                     * the event handler, at least until the main window is closed. */
+                    QApplication::postEvent(this, new ActivateMenuEvent(pAction));
+                    return true;
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
+void UIMachineView::releaseAllPressedKeys(bool aReleaseHostKey /* = true */)
+{
+    //AssertMsg(m_bIsAttached, ("Console must be attached"));
+
+    CKeyboard keyboard = m_console.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 (mPressedKeys); i++)
+    {
+        if (mPressedKeys[i] & IsKeyPressed)
+        {
+            if (!fSentRESEND)
+            {
+                keyboard.PutScancode (0xFE);
+                fSentRESEND = true;
+            }
+            keyboard.PutScancode(i | 0x80);
+        }
+        else if (mPressedKeys[i] & IsExtKeyPressed)
+        {
+            if (!fSentRESEND)
+            {
+                keyboard.PutScancode(0xFE);
+                fSentRESEND = true;
+            }
+            QVector <LONG> codes(2);
+            codes[0] = 0xE0;
+            codes[1] = i | 0x80;
+            keyboard.PutScancodes(codes);
+        }
+        mPressedKeys[i] = 0;
+    }
+
+    if (aReleaseHostKey)
+        m_bIsHostkeyPressed = false;
+
+#ifdef Q_WS_MAC
+    /* clear most of the modifiers. */
+    mDarwinKeyModifiers &=
+        alphaLock | kEventKeyModifierNumLockMask |
+        (aReleaseHostKey ? 0 : ::DarwinKeyCodeToDarwinModifierMask (m_globalSettings.hostKey()));
+#endif
+
+    emitKeyboardStateChanged();
+}
+
+void UIMachineView::saveKeyStates()
+{
+    ::memcpy(mPressedKeysCopy, mPressedKeys, sizeof(mPressedKeys));
+}
+
+void UIMachineView::sendChangedKeyStates()
+{
+    //AssertMsg(m_bIsAttached, ("Console must be attached"));
+
+    QVector <LONG> codes(2);
+    CKeyboard keyboard = m_console.GetKeyboard();
+    for (uint i = 0; i < SIZEOF_ARRAY(mPressedKeys); ++ i)
+    {
+        uint8_t os = mPressedKeysCopy[i];
+        uint8_t ns = mPressedKeys[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::updateMouseClipping()
+{
+    //AssertMsg(m_bIsAttached, ("Console must be attached"));
+
+    if (m_bIsMouseCaptured)
+    {
+        viewport()->setCursor(QCursor(Qt::BlankCursor));
+#ifdef Q_WS_WIN32
+        QRect r = viewport()->rect();
+        r.moveTopLeft(viewport()->mapToGlobal(QPoint (0, 0)));
+        RECT rect = { r.left(), r.top(), r.right() + 1, r.bottom() + 1 };
+        ::ClipCursor(&rect);
+#endif
+    }
+    else
+    {
+#ifdef Q_WS_WIN32
+        ::ClipCursor(NULL);
+#endif
+        /* return the cursor to where it was when we captured it and show it */
+        QCursor::setPos(mCapturedPos);
+        viewport()->unsetCursor();
+    }
+}
+
+void UIMachineView::setPointerShape(MousePointerChangeEvent *pEvent)
+{
+    if (pEvent->shapeData() != NULL)
+    {
+        bool ok = false;
+
+        const uchar *srcAndMaskPtr = pEvent->shapeData();
+        uint andMaskSize = (pEvent->width() + 7) / 8 * pEvent->height();
+        const uchar *srcShapePtr = pEvent->shapeData() + ((andMaskSize + 3) & ~3);
+        uint srcShapePtrScan = pEvent->width() * 4;
+
+#if defined (Q_WS_WIN)
+
+        BITMAPV5HEADER bi;
+        HBITMAP hBitmap;
+        void *lpBits;
+
+        ::ZeroMemory(&bi, sizeof (BITMAPV5HEADER));
+        bi.bV5Size = sizeof(BITMAPV5HEADER);
+        bi.bV5Width = pEvent->width();
+        bi.bV5Height = - (LONG)pEvent->height();
+        bi.bV5Planes = 1;
+        bi.bV5BitCount = 32;
+        bi.bV5Compression = BI_BITFIELDS;
+        bi.bV5RedMask   = 0x00FF0000;
+        bi.bV5GreenMask = 0x0000FF00;
+        bi.bV5BlueMask  = 0x000000FF;
+        if (pEvent->hasAlpha())
+            bi.bV5AlphaMask = 0xFF000000;
+        else
+            bi.bV5AlphaMask = 0;
+
+        HDC hdc = GetDC(NULL);
+
+        // create the DIB section with an alpha channel
+        hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, (DWORD) 0);
+
+        ReleaseDC(NULL, hdc);
+
+        HBITMAP hMonoBitmap = NULL;
+        if (pEvent->hasAlpha())
+        {
+            // create an empty mask bitmap
+            hMonoBitmap = CreateBitmap(pEvent->width(), pEvent->height(), 1, 1, NULL);
+        }
+        else
+        {
+            /* Word aligned AND mask. Will be allocated and created if necessary. */
+            uint8_t *pu8AndMaskWordAligned = NULL;
+
+            /* Width in bytes of the original AND mask scan line. */
+            uint32_t cbAndMaskScan = (pEvent->width() + 7) / 8;
+
+            if (cbAndMaskScan & 1)
+            {
+                /* Original AND mask is not word aligned. */
+
+                /* Allocate memory for aligned AND mask. */
+                pu8AndMaskWordAligned = (uint8_t *)RTMemTmpAllocZ((cbAndMaskScan + 1) * pEvent->height());
+
+                Assert(pu8AndMaskWordAligned);
+
+                if (pu8AndMaskWordAligned)
+                {
+                    /* According to MSDN the padding bits must be 0.
+                     * Compute the bit mask to set padding bits to 0 in the last byte of original AND mask. */
+                    uint32_t u32PaddingBits = cbAndMaskScan * 8  - pEvent->width();
+                    Assert(u32PaddingBits < 8);
+                    uint8_t u8LastBytesPaddingMask = (uint8_t)(0xFF << u32PaddingBits);
+
+                    Log(("u8LastBytesPaddingMask = %02X, aligned w = %d, width = %d, cbAndMaskScan = %d\n",
+                          u8LastBytesPaddingMask, (cbAndMaskScan + 1) * 8, pEvent->width(), cbAndMaskScan));
+
+                    uint8_t *src = (uint8_t *)srcAndMaskPtr;
+                    uint8_t *dst = pu8AndMaskWordAligned;
+
+                    unsigned i;
+                    for (i = 0; i < pEvent->height(); i++)
+                    {
+                        memcpy(dst, src, cbAndMaskScan);
+
+                        dst[cbAndMaskScan - 1] &= u8LastBytesPaddingMask;
+
+                        src += cbAndMaskScan;
+                        dst += cbAndMaskScan + 1;
+                    }
+                }
+            }
+
+            /* create the AND mask bitmap */
+            hMonoBitmap = ::CreateBitmap(pEvent->width(), pEvent->height(), 1, 1,
+                                         pu8AndMaskWordAligned? pu8AndMaskWordAligned: srcAndMaskPtr);
+
+            if (pu8AndMaskWordAligned)
+            {
+                RTMemTmpFree(pu8AndMaskWordAligned);
+            }
+        }
+
+        Assert(hBitmap);
+        Assert(hMonoBitmap);
+        if (hBitmap && hMonoBitmap)
+        {
+            DWORD *dstShapePtr = (DWORD *) lpBits;
+
+            for (uint y = 0; y < pEvent->height(); y ++)
+            {
+                memcpy(dstShapePtr, srcShapePtr, srcShapePtrScan);
+                srcShapePtr += srcShapePtrScan;
+                dstShapePtr += pEvent->width();
+            }
+
+            ICONINFO ii;
+            ii.fIcon = FALSE;
+            ii.xHotspot = pEvent->xHot();
+            ii.yHotspot = pEvent->yHot();
+            ii.hbmMask = hMonoBitmap;
+            ii.hbmColor = hBitmap;
+
+            HCURSOR hAlphaCursor = CreateIconIndirect(&ii);
+            Assert(hAlphaCursor);
+            if (hAlphaCursor)
+            {
+                viewport()->setCursor(QCursor(hAlphaCursor));
+                ok = true;
+                if (mAlphaCursor)
+                    DestroyIcon(mAlphaCursor);
+                mAlphaCursor = hAlphaCursor;
+            }
+        }
+
+        if (hMonoBitmap)
+            DeleteObject(hMonoBitmap);
+        if (hBitmap)
+            DeleteObject(hBitmap);
+
+#elif defined (Q_WS_X11) && !defined (VBOX_WITHOUT_XCURSOR)
+
+        XcursorImage *img = XcursorImageCreate (pEvent->width(), pEvent->height());
+        Assert (img);
+        if (img)
+        {
+            img->xhot = pEvent->xHot();
+            img->yhot = pEvent->yHot();
+
+            XcursorPixel *dstShapePtr = img->pixels;
+
+            for (uint y = 0; y < pEvent->height(); y ++)
+            {
+                memcpy (dstShapePtr, srcShapePtr, srcShapePtrScan);
+
+                if (!pEvent->hasAlpha())
+                {
+                    /* convert AND mask to the alpha channel */
+                    uchar byte = 0;
+                    for (uint x = 0; x < pEvent->width(); x ++)
+                    {
+                        if (!(x % 8))
+                            byte = *(srcAndMaskPtr ++);
+                        else
+                            byte <<= 1;
+
+                        if (byte & 0x80)
+                        {
+                            /* Linux doesn't support inverted pixels (XOR ops,
+                             * to be exact) in cursor shapes, so we detect such
+                             * pixels and always replace them with black ones to
+                             * make them visible at least over light colors */
+                            if (dstShapePtr [x] & 0x00FFFFFF)
+                                dstShapePtr [x] = 0xFF000000;
+                            else
+                                dstShapePtr [x] = 0x00000000;
+                        }
+                        else
+                            dstShapePtr [x] |= 0xFF000000;
+                    }
+                }
+
+                srcShapePtr += srcShapePtrScan;
+                dstShapePtr += pEvent->width();
+            }
+
+            Cursor cur = XcursorImageLoadCursor (QX11Info::display(), img);
+            Assert (cur);
+            if (cur)
+            {
+                viewport()->setCursor (QCursor (cur));
+                ok = true;
+            }
+
+            XcursorImageDestroy (img);
+        }
+
+#elif defined(Q_WS_MAC)
+
+        /* Create a ARGB image out of the shape data. */
+        QImage image  (pEvent->width(), pEvent->height(), QImage::Format_ARGB32);
+        const uint8_t* pbSrcMask = static_cast<const uint8_t*> (srcAndMaskPtr);
+        unsigned cbSrcMaskLine = RT_ALIGN (pEvent->width(), 8) / 8;
+        for (unsigned int y = 0; y < pEvent->height(); ++y)
+        {
+            for (unsigned int x = 0; x < pEvent->width(); ++x)
+            {
+               unsigned int color = ((unsigned int*)srcShapePtr)[y*pEvent->width()+x];
+               /* If the alpha channel isn't in the shape data, we have to
+                * create them from the and-mask. This is a bit field where 1
+                * represent transparency & 0 opaque respectively. */
+               if (!pEvent->hasAlpha())
+               {
+                   if (!(pbSrcMask[x / 8] & (1 << (7 - (x % 8)))))
+                       color  |= 0xff000000;
+                   else
+                   {
+                       /* This isn't quite right, but it's the best we can do I
+                        * think... */
+                       if (color & 0x00ffffff)
+                           color = 0xff000000;
+                       else
+                           color = 0x00000000;
+                   }
+               }
+               image.setPixel (x, y, color);
+            }
+            /* Move one scanline forward. */
+            pbSrcMask += cbSrcMaskLine;
+        }
+        /* Set the new cursor */
+        QCursor cursor (QPixmap::fromImage (image), pEvent->xHot(), pEvent->yHot());
+        viewport()->setCursor (cursor);
+        ok = true;
+        NOREF (srcShapePtrScan);
+
+#else
+
+# warning "port me"
+
+#endif
+
+        if (ok)
+            mLastCursor = viewport()->cursor();
+        else
+            viewport()->unsetCursor();
+    }
+    else
+    {
+        if (pEvent->isVisible())
+        {
+            viewport()->setCursor(mLastCursor);
+        }
+        else
+        {
+            viewport()->setCursor(Qt::BlankCursor);
+        }
+    }
+    mHideHostPointer = !pEvent->isVisible();
+}
+
+inline QRgb qRgbIntensity(QRgb rgb, int mul, int div)
+{
+    int r = qRed(rgb);
+    int g = qGreen(rgb);
+    int b = qBlue(rgb);
+    return qRgb(mul * r / div, mul * g / div, mul * b / div);
+}
+
+void UIMachineView::storeConsoleSize(int aWidth, int aHeight)
+{
+    LogFlowThisFunc(("aWidth=%d, aHeight=%d\n", aWidth, aHeight));
+    mStoredConsoleSize = QRect(0, 0, aWidth, aHeight);
+}
+
+void UIMachineView::setMouseIntegrationLocked(bool bDisabled)
+{
+    machineWindowWrapper()->machineLogic()->actionsPool()->action(UIActionIndex_Toggle_MouseIntegration)->setChecked(false);
+    machineWindowWrapper()->machineLogic()->actionsPool()->action(UIActionIndex_Toggle_MouseIntegration)->setEnabled(bDisabled);
+}
+
+void UIMachineView::setDesktopGeometry(DesktopGeo aGeo, int aWidth, int aHeight)
+{
+    switch (aGeo)
+    {
+        case DesktopGeo_Fixed:
+            mDesktopGeo = DesktopGeo_Fixed;
+            if (aWidth != 0 && aHeight != 0)
+                mDesktopGeometry = QRect(0, 0, aWidth, aHeight);
+            else
+                mDesktopGeometry = QRect(0, 0, 0, 0);
+            storeConsoleSize(0, 0);
+            break;
+        case DesktopGeo_Automatic:
+            mDesktopGeo = DesktopGeo_Automatic;
+            mDesktopGeometry = QRect(0, 0, 0, 0);
+            storeConsoleSize(0, 0);
+            break;
+        case DesktopGeo_Any:
+            mDesktopGeo = DesktopGeo_Any;
+            mDesktopGeometry = QRect(0, 0, 0, 0);
+            break;
+        default:
+            AssertMsgFailed(("Invalid desktop geometry type %d\n", aGeo));
+            mDesktopGeo = DesktopGeo_Invalid;
+    }
+}
+
+QRect UIMachineView::availableGeometry()
+{
+    return machineWindowWrapper()->machineWindow()->isFullScreen() ?
+           QApplication::desktop()->screenGeometry(this) :
+           QApplication::desktop()->availableGeometry(this);
+}
+
+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));
+                }
+            }
+        }
+    }
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h	(revision 26637)
@@ -0,0 +1,286 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineView class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef ___UIMachineView_h___
+#define ___UIMachineView_h___
+
+/* Local forwards */
+class UIFrameBuffer;
+class UIMachineWindow;
+class VBoxGlobalSettings;
+class MousePointerChangeEvent;
+
+/* Global includes */
+#include <QAbstractScrollArea>
+
+/* Local includes */
+#include "COMDefs.h"
+#include "UIMachineDefs.h"
+
+class UIMachineView : public QAbstractScrollArea
+{
+    Q_OBJECT;
+
+public:
+
+    /* Factory function to create required view sub-child: */
+    static UIMachineView* create(  UIMachineWindow *pMachineWindow
+                                 , VBoxDefs::RenderMode renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                                 , bool bAccelerate2DVideo
+#endif
+                                 , UIVisualStateType visualStateType);
+
+    /* Adjust view geometry: */
+    virtual void normalizeGeometry(bool bAdjustPosition = false) = 0;
+
+    /* Public members: */
+    // TODO: Is it needed now?
+    void onViewOpened();
+
+    /* Public getters: */
+    int contentsX() const;
+    int contentsY() const;
+    QRect desktopGeometry() const;
+    bool isMouseAbsolute() const { return m_bIsMouseAbsolute; }
+
+    /* Public setters: */
+    void setIgnoreGuestResize(bool bIgnore);
+    void setMouseIntegrationEnabled(bool bEnabled);
+
+signals:
+
+    void keyboardStateChanged(int iState);
+    void mouseStateChanged(int iState);
+    void machineStateChanged(KMachineState state);
+    void additionsStateChanged(const QString &strVersion, bool bIsActive, bool bIsGraphicSupported, bool bIsSeamlessSupported);
+    void mediaDriveChanged(VBoxDefs::MediumType type);
+    void networkStateChange();
+    void usbStateChange();
+    void sharedFoldersChanged();
+    void resizeHintDone();
+
+protected slots:
+
+    virtual void doResizeHint(const QSize &aSize = QSize()) = 0;
+
+protected:
+
+    UIMachineView(  UIMachineWindow *pMachineWindow
+                  , VBoxDefs::RenderMode renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                  , bool bAccelerate2DVideo
+#endif
+    );
+    virtual ~UIMachineView();
+
+    /* Protected members: */
+    void calculateDesktopGeometry();
+
+    /* Protected getters: */
+    UIMachineWindow* machineWindowWrapper() { return m_pMachineWindow; }
+    QSize sizeHint() const;
+
+    /* Protected variables: */
+    VBoxDefs::RenderMode mode;
+    bool m_bIsGuestSupportsGraphics : 1;
+
+private slots:
+
+#ifdef Q_WS_MAC
+    /* Dock icon update handler */
+    void sltChangeDockIconUpdate(const VBoxChangeDockIconUpdateEvent &event);
+
+# ifdef QT_MAC_USE_COCOA
+    /* Presentation mode handler */
+    void sltChangePresentationMode(const VBoxChangePresentationModeEvent &event);
+# endif
+#endif
+
+private:
+
+    /* Private getters: */
+    int contentsWidth() const;
+    int contentsHeight() const;
+    int visibleWidth() const;
+    int visibleHeight() const;
+    const QPixmap& pauseShot() const { return mPausedShot; }
+    bool shouldHideHostPointer() const { return m_bIsMouseCaptured || (m_bIsMouseAbsolute && mHideHostPointer); }
+    bool isRunning() { return mLastState == KMachineState_Running || mLastState == KMachineState_Teleporting || mLastState == KMachineState_LiveSnapshotting; }
+    CConsole &console() { return m_console; }
+
+    /* Event processors: */
+    bool event(QEvent *pEvent);
+    bool eventFilter(QObject *pWatched, QEvent *pEvent);
+#if defined(Q_WS_WIN32)
+    bool winLowKeyboardEvent(UINT msg, const KBDLLHOOKSTRUCT &event);
+    bool winEvent (MSG *aMsg, long *aResult);
+#elif defined(Q_WS_PM)
+    bool pmEvent (QMSG *aMsg);
+#elif defined(Q_WS_X11)
+    bool x11Event (XEvent *event);
+#elif defined(Q_WS_MAC)
+    bool darwinKeyboardEvent (const void *pvCocoaEvent, EventRef inEvent);
+    void darwinGrabKeyboardEvents (bool fGrab);
+#endif
+#if defined (Q_WS_WIN32)
+    static LRESULT CALLBACK lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
+#elif defined (Q_WS_MAC)
+# if defined (QT_MAC_USE_COCOA)
+    static bool darwinEventHandlerProc(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser);
+# elif !defined (VBOX_WITH_HACKED_QT)
+    static pascal OSStatus darwinEventHandlerProc(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
+# else  /* VBOX_WITH_HACKED_QT */
+    static bool macEventFilter(EventRef inEvent, void *inUserData);
+# endif /* VBOX_WITH_HACKED_QT */
+#endif
+
+    /* Flags for keyEvent() */
+    enum { KeyExtended = 0x01, KeyPressed = 0x02, KeyPause = 0x04, KeyPrint = 0x08 };
+    void emitKeyboardStateChanged()
+    {
+        emit keyboardStateChanged((m_bIsKeyboardCaptured ? UIViewStateType_KeyboardCaptured : 0) |
+                                  (m_bIsHostkeyPressed ? UIViewStateType_HostKeyPressed : 0));
+    }
+    void emitMouseStateChanged()
+    {
+        emit mouseStateChanged((m_bIsMouseCaptured ? UIMouseStateType_MouseCaptured : 0) |
+                               (m_bIsMouseAbsolute ? UIMouseStateType_MouseAbsolute : 0) |
+                               (!m_bIsMouseIntegrated ? UIMouseStateType_MouseAbsoluteDisabled : 0));
+    }
+
+    void focusEvent(bool aHasFocus, bool aReleaseHostKey = true);
+    bool keyEvent(int aKey, uint8_t aScan, int aFlags, wchar_t *aUniKey = NULL);
+    bool mouseEvent(int aType, const QPoint &aPos, const QPoint &aGlobalPos,
+                    Qt::MouseButtons aButtons, Qt::KeyboardModifiers aModifiers,
+                    int aWheelDelta, Qt::Orientation aWheelDir);
+    void resizeEvent(QResizeEvent *pEvent);
+    void moveEvent(QMoveEvent *pEvent);
+    void paintEvent(QPaintEvent *pEvent);
+
+    /* Private members: */
+    void fixModifierState(LONG *piCodes, uint *puCount);
+    void scrollBy(int dx, int dy);
+    QPoint viewportToContents(const QPoint &vp) const;
+    void updateSliders();
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    void scrollContentsBy(int dx, int dy);
+#endif
+#if defined(Q_WS_MAC)
+    void updateDockIcon();
+    void updateDockOverlay();
+    void setDockIconEnabled(bool aOn) { mDockIconEnabled = aOn; };
+    void setMouseCoalescingEnabled(bool aOn);
+#endif
+    void onStateChange(KMachineState state);
+    void captureKbd(bool aCapture, bool aEmitSignal = true);
+    void captureMouse(bool aCapture, bool aEmitSignal = true);
+    bool processHotKey(const QKeySequence &key, const QList<QAction*> &data);
+    void releaseAllPressedKeys(bool aReleaseHostKey = true);
+    void saveKeyStates();
+    void sendChangedKeyStates();
+    void updateMouseClipping();
+    void setPointerShape(MousePointerChangeEvent *pEvent);
+
+    enum DesktopGeo { DesktopGeo_Invalid = 0, DesktopGeo_Fixed, DesktopGeo_Automatic, DesktopGeo_Any };
+    void storeConsoleSize(int aWidth, int aHeight);
+    void setMouseIntegrationLocked(bool bDisabled);
+    void setDesktopGeometry(DesktopGeo aGeo, int aWidth, int aHeight);
+    virtual void maybeRestrictMinimumSize() = 0;
+    QRect availableGeometry();
+
+    static void dimImage(QImage &img);
+
+    /* Private members: */
+    UIMachineWindow *m_pMachineWindow;
+    CConsole m_console;
+    const VBoxGlobalSettings &m_globalSettings;
+    KMachineState mLastState;
+
+    QPoint mLastPos;
+    QPoint mCapturedPos;
+    int m_iLastMouseWheelDelta;
+
+    enum { IsKeyPressed = 0x01, IsExtKeyPressed = 0x02, IsKbdCaptured = 0x80 };
+    uint8_t mPressedKeys[128];
+    uint8_t mPressedKeysCopy[128];
+
+    long muNumLockAdaptionCnt;
+    long muCapsLockAdaptionCnt;
+
+    bool m_bIsAutoCaptureDisabled : 1;
+    bool m_bIsKeyboardCaptured : 1;
+    bool m_bIsMouseCaptured : 1;
+    bool m_bIsMouseAbsolute : 1;
+    bool m_bIsMouseIntegrated : 1;
+    bool m_bIsHostkeyPressed : 1;
+    bool m_bIsHostkeyAlone : 1;
+    bool hostkey_in_capture : 1;
+    bool m_bIsMachineWindowResizeIgnored : 1;
+    bool m_bIsFrameBufferResizeIgnored : 1;
+    bool m_bIsGuestResizeIgnored : 1;
+    bool mDoResize : 1;
+    bool mNumLock : 1;
+    bool mScrollLock : 1;
+    bool mCapsLock : 1;
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    bool mAccelerate2DVideo;
+#endif
+
+#if defined(Q_WS_WIN)
+    HCURSOR mAlphaCursor;
+#endif
+
+#if defined(Q_WS_MAC)
+# if !defined (VBOX_WITH_HACKED_QT) && !defined (QT_MAC_USE_COCOA)
+    /** Event handler reference. NULL if the handler isn't installed. */
+    EventHandlerRef mDarwinEventHandlerRef;
+# endif
+    /** The current modifier key mask. Used to figure out which modifier
+     *  key was pressed when we get a kEventRawKeyModifiersChanged event. */
+    UInt32 mDarwinKeyModifiers;
+    bool mKeyboardGrabbed;
+#endif
+
+    UIFrameBuffer *mFrameBuf;
+    CConsoleCallback mCallback;
+
+    QPixmap mPausedShot;
+#if defined(Q_WS_MAC)
+# if !defined (QT_MAC_USE_COCOA)
+    EventHandlerRef mDarwinWindowOverlayHandlerRef;
+# endif
+    VBoxDockIconPreview *mDockIconPreview;
+    bool mDockIconEnabled;
+#endif
+    DesktopGeo mDesktopGeo;
+    QRect mDesktopGeometry;
+    QRect mStoredConsoleSize;
+    bool mPassCAD;
+    bool mHideHostPointer;
+    QCursor mLastCursor;
+
+    friend class UIConsoleCallback;
+};
+
+#endif // !___UIMachineViewNormal_h___
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp	(revision 26637)
@@ -0,0 +1,396 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineWindow class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Global includes */
+#include <QCloseEvent>
+
+/* Local includes */
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+#include "VBoxCloseVMDlg.h"
+
+#include "UIMachineLogic.h"
+#include "UIMachineWindow.h"
+#include "UIMachineView.h"
+#include "UIMachineWindowNormal.h"
+//#include "UIMachineWindowFullscreen.h"
+//#include "UIMachineWindowSeamless.h"
+
+UIMachineWindow* UIMachineWindow::create(UIMachineLogic *pMachineLogic, UIVisualStateType visualStateType)
+{
+    UIMachineWindow *window = 0;
+    switch (visualStateType)
+    {
+        case UIVisualStateType_Normal:
+            window = new UIMachineWindowNormal(pMachineLogic);
+            break;
+        case UIVisualStateType_Fullscreen:
+            // window = new UIMachineWindowFullscreen(pMachineLogic);
+            window = new UIMachineWindowNormal(pMachineLogic);
+            break;
+        case UIVisualStateType_Seamless:
+            // window = new UIMachineWindowSeamless(pMachineLogic);
+            window = new UIMachineWindowNormal(pMachineLogic);
+            break;
+    }
+    return window;
+}
+
+UIMachineWindow::UIMachineWindow(UIMachineLogic *pMachineLogic)
+    : m_pMachineLogic(pMachineLogic)
+{
+    /* Prepare window icon: */
+    prepareWindowIcon();
+
+    /* Load common window settings: */
+    loadWindowSettings();
+
+    /* Translate common window: */
+    retranslateWindow();
+}
+
+UIMachineWindow::~UIMachineWindow()
+{
+    // Nothing for now!
+}
+
+void UIMachineWindow::retranslateWindow()
+{
+#ifdef VBOX_OSE
+    m_strWindowTitlePrefix = UIMachineLogic::tr("VirtualBox OSE");
+#else
+    m_strWindowTitlePrefix = UIMachineLogic::tr("Sun VirtualBox");
+#endif
+#ifdef VBOX_BLEEDING_EDGE
+    m_strWindowTitlePrefix += UIMachineLogic::tr(" EXPERIMENTAL build %1r%2 - %3")
+                              .arg(RTBldCfgVersion())
+                              .arg(RTBldCfgRevisionStr())
+                              .arg(VBOX_BLEEDING_EDGE);
+#endif
+}
+
+void UIMachineWindow::updateAppearanceOf(int iElement)
+{
+    CMachine machine = machineLogic()->session().GetMachine();
+
+    if (iElement & UIVisualElement_WindowCaption)
+    {
+        QString strSnapshotName;
+        if (machine.GetSnapshotCount() > 0)
+        {
+            CSnapshot snapshot = machine.GetCurrentSnapshot();
+            strSnapshotName = " (" + snapshot.GetName() + ")";
+        }
+        machineWindow()->setWindowTitle(machine.GetName() + strSnapshotName + " [" +
+                                        vboxGlobal().toString(machineLogic()->machineState()) + "] - " +
+                                        m_strWindowTitlePrefix);
+
+        // TODO: Move that to fullscreen/seamless update routine:
+        // mMiniToolBar->setDisplayText(machine.GetName() + strSnapshotName);
+    }
+}
+
+void UIMachineWindow::closeEvent(QCloseEvent *pEvent)
+{
+    static const char *pstrSave = "save";
+    static const char *pstrShutdown = "shutdown";
+    static const char *pstrPowerOff = "powerOff";
+    static const char *pstrDiscardCurState = "discardCurState";
+
+    if (!machineView())
+    {
+        pEvent->accept();
+        return;
+    }
+
+    switch (machineLogic()->machineState())
+    {
+        case KMachineState_PoweredOff:
+        case KMachineState_Saved:
+        case KMachineState_Teleported:
+        case KMachineState_Aborted:
+            /* The machine has been already powered off or saved or aborted -- close the window immediately. */
+            pEvent->accept();
+            break;
+
+        default:
+            /* The machine is in some temporary state like Saving or Stopping.
+             * Ignore the close event. When it is Stopping, it will be soon closed anyway from sltUpdatmachineState().
+             * In all other cases, an appropriate progress dialog will be shown within a few seconds. */
+            pEvent->ignore();
+            break;
+
+        case KMachineState_Teleporting: /** @todo Live Migration: Test closing a VM that's being teleported or snapshotted. */
+        case KMachineState_LiveSnapshotting:
+        case KMachineState_Running:
+        case KMachineState_Paused:
+        case KMachineState_TeleportingPausedVM: /** @todo Live Migration: Check out this. */
+        case KMachineState_Stuck:
+            /* Start with ignoring the close event */
+            pEvent->ignore();
+
+            bool isACPIEnabled = machineLogic()->session().GetConsole().GetGuestEnteredACPIMode();
+
+            bool success = true;
+
+            bool wasPaused = machineLogic()->machineState() == KMachineState_Paused ||
+                             machineLogic()->machineState() == KMachineState_Stuck ||
+                             machineLogic()->machineState() == KMachineState_TeleportingPausedVM;
+            if (!wasPaused)
+            {
+                /* Suspend the VM and ignore the close event if failed to do so.
+                 * pause() will show the error message to the user. */
+                success = machineLogic()->pause(true);
+            }
+
+            if (success)
+            {
+                success = false;
+
+                CMachine machine = machineLogic()->session().GetMachine();
+                VBoxCloseVMDlg dlg(machineWindow());
+                QString typeId = machine.GetOSTypeId();
+                dlg.pmIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(typeId));
+
+                /* Make the Discard checkbox invisible if there are no snapshots */
+                dlg.mCbDiscardCurState->setVisible(machine.GetSnapshotCount() > 0);
+                if (!machine.GetCurrentSnapshot().isNull())
+                    dlg.mCbDiscardCurState->setText(dlg.mCbDiscardCurState->text().arg(machine.GetCurrentSnapshot().GetName()));
+
+                if (machineLogic()->machineState() != KMachineState_Stuck)
+                {
+                    /* Read the last user's choice for the given VM */
+                    QStringList lastAction = machine.GetExtraData(VBoxDefs::GUI_LastCloseAction).split(',');
+                    AssertWrapperOk(machine);
+                    if (lastAction[0] == pstrSave)
+                    {
+                        dlg.mRbShutdown->setEnabled(isACPIEnabled);
+                        dlg.mRbSave->setChecked(true);
+                        dlg.mRbSave->setFocus();
+                    }
+                    else if (lastAction[0] == pstrPowerOff || !isACPIEnabled)
+                    {
+                        dlg.mRbShutdown->setEnabled(isACPIEnabled);
+                        dlg.mRbPowerOff->setChecked(true);
+                        dlg.mRbPowerOff->setFocus();
+                    }
+                    else /* The default is ACPI Shutdown */
+                    {
+                        dlg.mRbShutdown->setChecked(true);
+                        dlg.mRbShutdown->setFocus();
+                    }
+                    dlg.mCbDiscardCurState->setChecked(lastAction.count() > 1 && lastAction [1] == pstrDiscardCurState);
+                }
+                else
+                {
+                    /* The stuck VM can only be powered off; disable anything else and choose PowerOff */
+                    dlg.mRbSave->setEnabled(false);
+                    dlg.mRbShutdown->setEnabled(false);
+                    dlg.mRbPowerOff->setChecked(true);
+                }
+
+                bool wasShutdown = false;
+
+                if (dlg.exec() == QDialog::Accepted)
+                {
+                    /* Disable auto closure because we want to have a chance to show
+                     * the error dialog on save state / power off failure. */
+                    // TODO: process for multiple windows!
+                    //m_bNoAutoClose = true;
+
+                    CConsole console = machineLogic()->session().GetConsole();
+
+                    if (dlg.mRbSave->isChecked())
+                    {
+                        CProgress progress = console.SaveState();
+
+                        if (console.isOk())
+                        {
+                            /* Show the "VM saving" progress dialog */
+                            vboxProblem().showModalProgressDialog(progress, machine.GetName(), machineWindow(), 0);
+                            if (progress.GetResultCode() != 0)
+                                vboxProblem().cannotSaveMachineState(progress);
+                            else
+                                success = true;
+                        }
+                        else
+                            vboxProblem().cannotSaveMachineState(console);
+                    }
+                    else if (dlg.mRbShutdown->isChecked())
+                    {
+                        /* Unpause the VM to let it grab the ACPI shutdown event */
+                        machineLogic()->pause(false);
+                        /* Prevent the subsequent unpause request */
+                        wasPaused = true;
+                        /* Signal ACPI shutdown (if there is no ACPI device, the
+                         * operation will fail) */
+                        console.PowerButton();
+                        wasShutdown = console.isOk();
+                        if (!wasShutdown)
+                            vboxProblem().cannotACPIShutdownMachine(console);
+                        /* Success is always false because we never accept the close
+                         * window action when doing ACPI shutdown */
+                        success = false;
+                    }
+                    else if (dlg.mRbPowerOff->isChecked())
+                    {
+                        CProgress progress = console.PowerDown();
+
+                        if (console.isOk())
+                        {
+                            /* Show the power down progress dialog */
+                            vboxProblem().showModalProgressDialog(progress, machine.GetName(), machineWindow());
+                            if (progress.GetResultCode() != 0)
+                                vboxProblem().cannotStopMachine(progress);
+                            else
+                                success = true;
+                        }
+                        else
+                            vboxProblem().cannotStopMachine(console);
+
+                        if (success)
+                        {
+                            /* Note: leave success = true even if we fail to
+                             * discard the current state later -- the console window
+                             * will closed anyway */
+
+                            /* Discard the current state if requested */
+                            if (dlg.mCbDiscardCurState->isChecked() && dlg.mCbDiscardCurState->isVisibleTo(&dlg))
+                            {
+                                CSnapshot snapshot = machine.GetCurrentSnapshot();
+                                CProgress progress = console.RestoreSnapshot(snapshot);
+                                if (console.isOk())
+                                {
+                                    /* Show the progress dialog */
+                                    vboxProblem().showModalProgressDialog(progress, machine.GetName(), machineWindow());
+                                    if (progress.GetResultCode() != 0)
+                                        vboxProblem().cannotRestoreSnapshot(progress, snapshot.GetName());
+                                }
+                                else
+                                    vboxProblem().cannotRestoreSnapshot(console, snapshot.GetName());
+                            }
+                        }
+                    }
+
+                    if (success)
+                    {
+                        /* Accept the close action on success */
+                        pEvent->accept();
+                    }
+
+                    if (success || wasShutdown)
+                    {
+                        /* Read the last user's choice for the given VM */
+                        QStringList prevAction = machine.GetExtraData(VBoxDefs::GUI_LastCloseAction).split(',');
+                        /* Memorize the last user's choice for the given VM */
+                        QString lastAction = pstrPowerOff;
+                        if (dlg.mRbSave->isChecked())
+                            lastAction = pstrSave;
+                        else if (dlg.mRbShutdown->isChecked() ||
+                                 (dlg.mRbPowerOff->isChecked() && prevAction [0] == pstrShutdown && !isACPIEnabled))
+                            lastAction = pstrShutdown;
+                        else if (dlg.mRbPowerOff->isChecked())
+                            lastAction = pstrPowerOff;
+                        else
+                            AssertFailed();
+                        if (dlg.mCbDiscardCurState->isChecked())
+                            (lastAction += ",") += pstrDiscardCurState;
+                        machine.SetExtraData (VBoxDefs::GUI_LastCloseAction, lastAction);
+                        AssertWrapperOk(machine);
+                    }
+                }
+            }
+
+            // TODO: process for multiple windows!
+            //m_bNoAutoClose = false;
+
+            if (machineLogic()->machineState() == KMachineState_PoweredOff ||
+                machineLogic()->machineState() == KMachineState_Saved ||
+                machineLogic()->machineState() == KMachineState_Teleported ||
+                machineLogic()->machineState() == KMachineState_Aborted)
+            {
+                /* The machine has been stopped while showing the Close or the Pause
+                 * failure dialog -- accept the close event immediately. */
+                pEvent->accept();
+            }
+            else
+            {
+                if (!success)
+                {
+                    /* Restore the running state if needed */
+                    if (!wasPaused && machineLogic()->machineState() == KMachineState_Paused)
+                        machineLogic()->pause(false);
+                }
+            }
+            break;
+    }
+
+    if (pEvent->isAccepted())
+    {
+#ifndef VBOX_GUI_SEPARATE_VM_PROCESS
+        vboxGlobal().selectorWnd().show();
+#endif
+
+        /* Hide console window */
+        machineWindow()->hide();
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+        /* Close & destroy the debugger GUI */
+        // TODO: Check that logic!
+        //dbgDestroy();
+#endif
+
+        /* Make sure all events are delievered */
+        qApp->processEvents();
+
+        /* Notify all the top-level dialogs about closing */
+        // TODO: Notify about closing!
+        // emit closing();
+    }
+}
+
+void UIMachineWindow::prepareWindowIcon()
+{
+#if !(defined (Q_WS_WIN) || defined (Q_WS_MAC))
+    /* The default application icon (will be changed to VM-specific icon little bit later):
+     * 1. On Win32, it's built-in to the executable;
+     * 2. On Mac OS X the icon referenced in info.plist is used. */
+    machineWindow()->setWindowIcon(QIcon(":/VirtualBox_48px.png"));
+#endif
+
+#ifndef Q_WS_MAC
+    /* Set the VM-specific application icon except Mac OS X: */
+    CMachine machine = machineLogic()->session().GetMachine();
+    machineWindow()->setWindowIcon(vboxGlobal().vmGuestOSTypeIcon(machine.GetOSTypeId()));
+#endif
+}
+
+void UIMachineWindow::loadWindowSettings()
+{
+#ifdef Q_WS_MAC
+    QString testStr = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateEnabled).toLower();
+    /* Default to true if it is an empty value */
+    bool bIsDockIconEnabled = testStr.isEmpty() || testStr == "true";
+    machineView()->setDockIconEnabled(bIsDockIconEnabled);
+    machineView()->updateDockOverlay();
+#endif
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h	(revision 26637)
@@ -0,0 +1,90 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineWindow class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIMachineWindow_h__
+#define __UIMachineWindow_h__
+
+/* Local includes */
+#include "UIMachineDefs.h"
+
+/* Global forwards */
+class QWidget;
+
+/* Local forwards */
+class UIMachineLogic;
+class UIMachineView;
+
+class UIMachineWindow
+{
+public:
+
+    /* Factory function to create required machine window child: */
+    static UIMachineWindow* create(UIMachineLogic *pMachineLogic, UIVisualStateType visualStateType);
+
+    /* Abstract slot to close machine window: */
+    virtual void sltTryClose() = 0;
+
+    /* Public getters: */
+    virtual UIMachineLogic* machineLogic() { return m_pMachineLogic; }
+    virtual QWidget* machineWindow() { return m_pMachineWindow; }
+    virtual UIMachineView* machineView() { return m_pMachineView; }
+
+protected:
+
+    /* Common machine window constructor: */
+    UIMachineWindow(UIMachineLogic *pMachineLogic);
+    virtual ~UIMachineWindow();
+
+    /* Translate routine: */
+    void retranslateWindow();
+
+    /* Update routines: */
+    virtual void updateAppearanceOf(int iElement);
+
+    /* Common machine window event handlers: */
+    void closeEvent(QCloseEvent *pEvent);
+
+    /* Protected getters: */
+    const QString& defaultWindowTitle() const { return m_strWindowTitlePrefix; }
+
+    /* Protected variables: */
+    QWidget *m_pMachineWindow;
+    UIMachineView *m_pMachineView;
+
+private:
+
+    /* Prepare helpers: */
+    void prepareWindowIcon();
+    void loadWindowSettings();
+
+    /* Cleanup helpers: */
+    //void saveWindowSettings();
+    //void cleanupWindowIcon();
+
+    /* Getter variables: */
+    UIMachineLogic *m_pMachineLogic;
+
+    /* Helper variables: */
+    QString m_strWindowTitlePrefix;
+};
+
+#endif // __UIMachineWindow_h__
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp	(revision 26637)
@@ -0,0 +1,225 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineLogicNormal class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Global includes */
+#include <QMenu>
+#include <QTimer>
+
+/* Local includes */
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+
+#include "UIFirstRunWzd.h"
+
+#include "UIActionsPool.h"
+#include "UIMachineLogicNormal.h"
+#include "UIMachineWindow.h"
+#include "UIMachineView.h"
+
+UIMachineLogicNormal::UIMachineLogicNormal(QObject *pParent, const CSession &session, UIActionsPool *pActionsPool)
+    : UIMachineLogic(pParent, session, pActionsPool, UIVisualStateType_Normal)
+{
+    /* Prepare action connections: */
+    prepareActionConnections();
+
+    /* Prepare normal machine window: */
+    prepareMachineWindow();
+}
+
+UIMachineLogicNormal::~UIMachineLogicNormal()
+{
+    /* Cleanup normal machine window: */
+    cleanupMachineWindow();
+}
+
+void UIMachineLogicNormal::sltPrepareNetworkAdaptersMenu()
+{
+    QMenu *menu = qobject_cast<QMenu*>(sender());
+    AssertMsg(menu, ("This slot should be called only on Network Adapters Menu show!\n"));
+    menu->clear();
+    menu->addAction(actionsPool()->action(UIActionIndex_Simple_NetworkAdaptersDialog));
+}
+
+void UIMachineLogicNormal::sltPrepareSharedFoldersMenu()
+{
+    QMenu *menu = qobject_cast<QMenu*>(sender());
+    AssertMsg(menu, ("This slot should be called only on Shared Folders Menu show!\n"));
+    menu->clear();
+    menu->addAction(actionsPool()->action(UIActionIndex_Simple_SharedFoldersDialog));
+}
+
+void UIMachineLogicNormal::updateAppearanceOf(int iElement)
+{
+    /* Update parent-class elements: */
+    UIMachineLogic::updateAppearanceOf(iElement);
+}
+
+void UIMachineLogicNormal::prepareActionConnections()
+{
+    connect(actionsPool()->action(UIActionIndex_Menu_NetworkAdapters)->menu(), SIGNAL(aboutToShow()),
+            this, SLOT(sltPrepareNetworkAdaptersMenu()));
+    connect(actionsPool()->action(UIActionIndex_Menu_SharedFolders)->menu(), SIGNAL(aboutToShow()),
+            this, SLOT(sltPrepareSharedFoldersMenu()));
+}
+
+void UIMachineLogicNormal::prepareMachineWindow()
+{
+    if (machineWindowWrapper())
+        return;
+
+#ifdef Q_WS_MAC
+    /* We have to make sure that we are getting the front most process.
+     * This is necessary for Qt versions > 4.3.3: */
+    ProcessSerialNumber psn = { 0, kCurrentProcess };
+    ::SetFrontProcess(&psn);
+#endif /* Q_WS_MAC */
+
+    m_pMachineWindowContainer = UIMachineWindow::create(this, visualStateType());
+
+    /* Get the correct initial machineState() value */
+    setMachineState(session().GetConsole().GetState());
+
+    /* Update all the stuff: */
+    updateAppearanceOf(UIVisualElement_AllStuff);
+
+    if (vboxGlobal().settings().autoCapture())
+        vboxProblem().remindAboutAutoCapture();
+
+    /* Notify the console scroll-view about the console-window is opened: */
+    machineWindowWrapper()->machineView()->onViewOpened();
+
+    bool saved = machineState() == KMachineState_Saved;
+
+    CMachine machine = session().GetMachine();
+    CConsole console = session().GetConsole();
+
+    if (isFirstTimeStarted())
+    {
+        UIFirstRunWzd wzd(machineWindowWrapper()->machineWindow(), machine);
+        wzd.exec();
+
+        /* Remove GUI_FirstRun extra data key from the machine settings
+         * file after showing the wizard once. */
+        machine.SetExtraData (VBoxDefs::GUI_FirstRun, QString::null);
+    }
+
+    /* Start VM: */
+    CProgress progress = vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled() ?
+                         console.PowerUpPaused() : console.PowerUp();
+
+    /* Check for an immediate failure */
+    if (!console.isOk())
+    {
+        vboxProblem().cannotStartMachine(console);
+        machineWindowWrapper()->machineWindow()->close();
+        return;
+    }
+
+    //machineWindowWrapper()->machineView()->attach();
+
+    /* Disable auto closure because we want to have a chance to show the error dialog on startup failure: */
+    setPreventAutoClose(true);
+
+    /* Show "Starting/Restoring" progress dialog: */
+    if (saved)
+        vboxProblem().showModalProgressDialog(progress, machine.GetName(), machineWindowWrapper()->machineView(), 0);
+    else
+        vboxProblem().showModalProgressDialog(progress, machine.GetName(), machineWindowWrapper()->machineView());
+
+    /* Check for an progress failure */
+    if (progress.GetResultCode() != 0)
+    {
+        vboxProblem().cannotStartMachine(progress);
+        machineWindowWrapper()->machineWindow()->close();
+        return;
+    }
+
+    /* Enable auto closure again: */
+    setPreventAutoClose(false);
+
+    /* Check if we missed a really quick termination after successful startup, and process it if we did: */
+    if (machineState() == KMachineState_PoweredOff || machineState() == KMachineState_Saved ||
+        machineState() == KMachineState_Teleported || machineState() == KMachineState_Aborted)
+    {
+        machineWindowWrapper()->machineWindow()->close();
+        return;
+    }
+
+#if 0 // TODO: Is it necessary now?
+     * Checking if the fullscreen mode should be activated: */
+    QString str = machine.GetExtraData (VBoxDefs::GUI_Fullscreen);
+    if (str == "on")
+        mVmFullscreenAction->setChecked (true);
+
+    /* If seamless mode should be enabled then check if it is enabled
+     * currently and re-enable it if seamless is supported: */
+    if (mVmSeamlessAction->isChecked() && m_bIsSeamlessSupported && m_bIsGraphicsSupported)
+        toggleFullscreenMode (true, true);
+
+# ifdef VBOX_WITH_DEBUGGER_GUI
+    /* Open the debugger in "full screen" mode requested by the user. */
+    else if (vboxGlobal().isDebuggerAutoShowEnabled())
+    {
+        /* console in upper left corner of the desktop. */
+        QRect rct (0, 0, 0, 0);
+        QDesktopWidget *desktop = QApplication::desktop();
+        if (desktop)
+            rct = desktop->availableGeometry(pos());
+        move (QPoint (rct.x(), rct.y()));
+
+        if (vboxGlobal().isDebuggerAutoShowStatisticsEnabled())
+            sltShowDebugStatistics();
+        if (vboxGlobal().isDebuggerAutoShowCommandLineEnabled())
+            sltShowDebugCommandLine();
+
+        if (!vboxGlobal().isStartPausedEnabled())
+            machineWindowWrapper()->machineView()->pause (false);
+    }
+# endif
+#endif
+
+    setOpenViewFinished(true);
+
+#ifdef VBOX_WITH_UPDATE_REQUEST
+    /* Check for updates if necessary: */
+    vboxGlobal().showUpdateDialog(false /* aForce */);
+#endif
+
+    connect(machineWindowWrapper()->machineView(), SIGNAL(machineStateChanged(KMachineState)), this, SLOT(sltUpdateMachineState(KMachineState)));
+    connect(machineWindowWrapper()->machineView(), SIGNAL(additionsStateChanged(const QString&, bool, bool, bool)),
+            this, SLOT(sltUpdateAdditionsState(const QString &, bool, bool, bool)));
+    connect(machineWindowWrapper()->machineView(), SIGNAL(mouseStateChanged(int)), this, SLOT(sltUpdateMouseState(int)));
+
+    /* Re-request all the static values finally after view is really opened and attached: */
+    updateAppearanceOf(UIVisualElement_VirtualizationStuff);
+}
+
+void UIMachineLogicNormal::cleanupMachineWindow()
+{
+    if (!machineWindowWrapper())
+        return;
+
+    // TODO: What should be done on window destruction?
+    //machineWindowWrapper()->machineView()->detach();
+    //m_session.Close();
+    //m_session.detach();
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.h	(revision 26637)
@@ -0,0 +1,68 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineLogicNormal class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIMachineLogicNormal_h__
+#define __UIMachineLogicNormal_h__
+
+/* Local includes */
+#include "UIMachineLogic.h"
+
+/* Local forwards */
+class UIActionsPool;
+
+class UIMachineLogicNormal : public UIMachineLogic
+{
+    Q_OBJECT;
+
+protected:
+
+    /* Normal machine logic constructor: */
+    UIMachineLogicNormal(QObject *pParent,
+                         const CSession &session,
+                         UIActionsPool *pActionsPool);
+    /* Normal machine logic destructor: */
+    virtual ~UIMachineLogicNormal();
+
+private slots:
+
+    /* Status-bar LED funtionality: */
+    void sltPrepareNetworkAdaptersMenu();
+    void sltPrepareSharedFoldersMenu();
+
+private:
+
+    /* Update routines: */
+    void updateAppearanceOf(int);
+
+    /* Prepare helpers: */
+    void prepareActionConnections();
+    void prepareMachineWindow();
+    //void loadLogicSettings();
+
+    /* Cleanup helpers: */
+    //void saveLogicSettings();
+    void cleanupMachineWindow();
+
+    friend class UIMachineLogic;
+};
+
+#endif // __UIMachineLogicNormal_h__
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp	(revision 26637)
@@ -0,0 +1,178 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineViewNormal class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Global includes */
+#include <QApplication>
+#include <QDesktopWidget>
+
+/* Local includes */
+#include "VBoxGlobal.h"
+#include "UIActionsPool.h"
+#include "UIMachineLogic.h"
+#include "UIMachineWindow.h"
+#include "UIMachineViewNormal.h"
+
+UIMachineViewNormal::UIMachineViewNormal(  UIMachineWindow *pMachineWindow
+                                         , VBoxDefs::RenderMode renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                                         , bool bAccelerate2DVideo
+#endif
+                                        )
+    : UIMachineView(  pMachineWindow
+                    , renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                    , bAccelerate2DVideo
+#endif
+                   )
+{
+    /* Connect actions to view: */
+    connect(machineWindowWrapper()->machineLogic()->actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize),
+            SIGNAL(toggled(bool)), this, SLOT(sltToggleGuestAutoresize(bool)));
+
+    /* Connect view to handlers */
+    connect(this, SIGNAL(additionsStateChanged(const QString&, bool, bool, bool)),
+            this, SLOT(sltAdditionsStateChanged(const QString &, bool, bool, bool)));
+}
+
+void UIMachineViewNormal::normalizeGeometry(bool bAdjustPosition /* = false */)
+{
+    /* Make no normalizeGeometry in case we are in manual resize mode or main window is maximized */
+    if (machineWindowWrapper()->machineWindow()->isMaximized())
+        return;
+
+    QWidget *pTopLevelWidget = window();
+
+    /* calculate client window offsets */
+    QRect fr = pTopLevelWidget->frameGeometry();
+    QRect r = pTopLevelWidget->geometry();
+    int dl = r.left() - fr.left();
+    int dt = r.top() - fr.top();
+    int dr = fr.right() - r.right();
+    int db = fr.bottom() - r.bottom();
+
+    /* get the best size w/o scroll bars */
+    QSize s = pTopLevelWidget->sizeHint();
+
+    /* resize the frame to fit the contents */
+    s -= pTopLevelWidget->size();
+    fr.setRight(fr.right() + s.width());
+    fr.setBottom(fr.bottom() + s.height());
+
+    if (bAdjustPosition)
+    {
+        QRegion ar;
+        QDesktopWidget *dwt = QApplication::desktop();
+        if (dwt->isVirtualDesktop())
+            /* Compose complex available region */
+            for (int i = 0; i < dwt->numScreens(); ++ i)
+                ar += dwt->availableGeometry(i);
+        else
+            /* Get just a simple available rectangle */
+            ar = dwt->availableGeometry(pTopLevelWidget->pos());
+
+        fr = VBoxGlobal::normalizeGeometry(fr, ar, mode != VBoxDefs::SDLMode /* canResize */);
+    }
+
+#if 0
+    /* Center the frame on the desktop: */
+    fr.moveCenter(ar.center());
+#endif
+
+    /* Finally, set the frame geometry */
+    pTopLevelWidget->setGeometry(fr.left() + dl, fr.top() + dt, fr.width() - dl - dr, fr.height() - dt - db);
+}
+
+void UIMachineViewNormal::maybeRestrictMinimumSize()
+{
+    /* Sets the minimum size restriction depending on the auto-resize feature state and the current rendering mode.
+     * Currently, the restriction is set only in SDL mode and only when the auto-resize feature is inactive.
+     * We need to do that because we cannot correctly draw in a scrolled window in SDL mode.
+     * In all other modes, or when auto-resize is in force, this function does nothing. */
+    if (mode == VBoxDefs::SDLMode)
+    {
+        if (!m_bIsGuestSupportsGraphics || !m_bIsGuestAutoresizeEnabled)
+            setMinimumSize(sizeHint());
+        else
+            setMinimumSize(0, 0);
+    }
+}
+
+void UIMachineViewNormal::doResizeHint(const QSize & /*toSize*/)
+{
+#if 0 // TODO: fix that logic!
+    if (m_bIsGuestSupportsGraphics && m_bIsGuestAutoresizeEnabled)
+    {
+        /* If this slot is invoked directly then use the passed size
+         * otherwise get the available size for the guest display.
+         * We assume here that the centralWidget() contains this view only
+         * and gives it all available space. */
+        QSize sz(toSize.isValid() ? toSize : machineWindow()->centralWidget()->size());
+        if (!toSize.isValid())
+            sz -= QSize(frameWidth() * 2, frameWidth() * 2);
+        /* Do not send out useless hints. */
+        if ((sz.width() == mStoredConsoleSize.width()) && (sz.height() == mStoredConsoleSize.height()))
+            return;
+        /* We only actually send the hint if
+         * 1) the autoresize property is set to true and
+         * 2) either an explicit new size was given (e.g. if the request
+         *    was triggered directly by a console resize event) or if no
+         *    explicit size was specified but a resize is flagged as being
+         *    needed (e.g. the autoresize was just enabled and the console
+         *    was resized while it was disabled). */
+        if (m_bIsGuestAutoresizeEnabled && (toSize.isValid() || mDoResize))
+        {
+            /* Remember the new size. */
+            storeConsoleSize(sz.width(), sz.height());
+
+            mConsole.GetDisplay().SetVideoModeHint(sz.width(), sz.height(), 0, 0);
+        }
+        /* We have resized now... */
+        mDoResize = false;
+    }
+#endif
+}
+
+/* If the desktop geometry is set automatically, this will update it. */
+void UIMachineViewNormal::doResizeDesktop(int)
+{
+    calculateDesktopGeometry();
+}
+
+void UIMachineViewNormal::sltToggleGuestAutoresize(bool bOn)
+{
+    if (m_bIsGuestAutoresizeEnabled != bOn)
+    {
+        m_bIsGuestAutoresizeEnabled = bOn;
+
+        maybeRestrictMinimumSize();
+
+        if (m_bIsGuestSupportsGraphics && m_bIsGuestAutoresizeEnabled)
+            doResizeHint();
+    }
+}
+
+void UIMachineViewNormal::sltAdditionsStateChanged(const QString & /* strVersion */, bool /* bIsActive */,
+                                                   bool /* bIsSeamlessSupported */, bool bIsGraphicsSupported)
+{
+    /* Enable/Disable guest auto-resizing depending on advanced graphics availablability: */
+    sltToggleGuestAutoresize(bIsGraphicsSupported && m_bIsGuestAutoresizeEnabled);
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.h	(revision 26637)
@@ -0,0 +1,63 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineViewNormal class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef ___UIMachineViewNormal_h___
+#define ___UIMachineViewNormal_h___
+
+/* Local includes */
+#include "UIMachineView.h"
+
+class UIMachineViewNormal : public UIMachineView
+{
+    Q_OBJECT;
+
+protected:
+
+    UIMachineViewNormal(  UIMachineWindow *pMachineWindow
+                        , VBoxDefs::RenderMode renderMode
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                        , bool bAccelerate2DVideo
+#endif
+    );
+
+    void normalizeGeometry(bool bAdjustPosition = false);
+
+    void maybeRestrictMinimumSize();
+
+private slots:
+
+    void doResizeHint(const QSize &aSize = QSize());
+
+    void doResizeDesktop(int);
+
+    void sltToggleGuestAutoresize(bool bOn);
+
+    void sltAdditionsStateChanged(const QString &strVersion, bool bIsActive,
+                                  bool bIsSeamlessSupported, bool bIsGraphicsSupported);
+private:
+
+    bool m_bIsGuestAutoresizeEnabled : 1;
+
+    friend class UIMachineView;
+};
+
+#endif // !___UIMachineViewNormal_h___
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp	(revision 26637)
@@ -0,0 +1,799 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineWindowNormal class implementation
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Global includes */
+#include <QDesktopWidget>
+#include <QMenuBar>
+#include <QTimer>
+#include <QContextMenuEvent>
+
+/* Local includes */
+#include "VBoxGlobal.h"
+
+#include "VBoxVMInformationDlg.h"
+
+#include "UIActionsPool.h"
+#include "UIIndicatorsPool.h"
+#include "UIMachineLogic.h"
+#include "UIMachineView.h"
+#include "UIMachineWindowNormal.h"
+
+#include "QIStatusBar.h"
+#include "QIStateIndicator.h"
+#include "QIHotKeyEdit.h"
+
+UIMachineWindowNormal::UIMachineWindowNormal(UIMachineLogic *pMachineLogic)
+    : QIWithRetranslateUI<QIMainDialog>(0)
+    , UIMachineWindow(pMachineLogic)
+    , m_pIndicatorsPool(new UIIndicatorsPool(this))
+    , m_pIdleTimer(0)
+{
+    /* "This" is machine window: */
+    m_pMachineWindow = this;
+
+    /* Prepare menu: */
+    prepareMenu();
+
+    /* Prepare status bar: */
+    prepareStatusBar();
+
+    /* Prepare connections: */
+    prepareConnections();
+
+    /* Prepare normal machine view: */
+    prepareMachineView();
+
+    /* Load normal window settings: */
+    loadWindowSettings();
+
+    /* Retranslate normal window finally: */
+    retranslateUi();
+}
+
+UIMachineWindowNormal::~UIMachineWindowNormal()
+{
+    /* Save normal window settings: */
+    saveWindowSettings();
+
+    /* Cleanup status-bar: */
+    cleanupStatusBar();
+}
+
+void UIMachineWindowNormal::sltTryClose()
+{
+    // TODO: Could be moved to parent class?
+
+    /* First close any open modal & popup widgets.
+     * Use a single shot with timeout 0 to allow the widgets to cleany close and test then again.
+     * If all open widgets are closed destroy ourself: */
+    QWidget *widget = QApplication::activeModalWidget() ?
+                      QApplication::activeModalWidget() :
+                      QApplication::activePopupWidget() ?
+                      QApplication::activePopupWidget() : 0;
+    if (widget)
+    {
+        widget->close();
+        QTimer::singleShot(0, this, SLOT(sltTryClose()));
+    }
+    else
+        close();
+}
+
+void UIMachineWindowNormal::sltPrepareMenuMachine()
+{
+    QMenu *menu = qobject_cast<QMenu*>(sender());
+    AssertMsg(menu == machineLogic()->actionsPool()->action(UIActionIndex_Menu_Machine)->menu(),
+              ("This slot should only be called on 'Machine' menu hovering!\n"));
+
+    menu->clear();
+
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Toggle_Fullscreen));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Toggle_Seamless));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_AdjustWindow));
+    menu->addSeparator();
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Toggle_MouseIntegration));
+    menu->addSeparator();
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_TypeCAD));
+#ifdef Q_WS_X11
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_TypeCABS));
+#endif
+    menu->addSeparator();
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_TakeSnapshot));
+    menu->addSeparator();
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_InformationDialog));
+    menu->addSeparator();
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_Reset));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Toggle_Pause));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_Shutdown));
+#ifndef Q_WS_MAC
+    menu->addSeparator();
+#endif /* Q_WS_MAC */
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_Close));
+}
+
+void UIMachineWindowNormal::sltPrepareMenuDevices()
+{
+    QMenu *menu = qobject_cast<QMenu*>(sender());
+    AssertMsg(menu == machineLogic()->actionsPool()->action(UIActionIndex_Menu_Devices)->menu(),
+              ("This slot should only be called on 'Devices' menu hovering!\n"));
+
+    menu->clear();
+
+    /* Devices submenu */
+    menu->addMenu(machineLogic()->actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu());
+    menu->addMenu(machineLogic()->actionsPool()->action(UIActionIndex_Menu_FloppyDevices)->menu());
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_NetworkAdaptersDialog));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_SharedFoldersDialog));
+    menu->addMenu(machineLogic()->actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu());
+    menu->addSeparator();
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Toggle_VRDP));
+    menu->addSeparator();
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_InstallGuestTools));
+}
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+void UIMachineWindowNormal::sltPrepareMenuDebug()
+{
+    QMenu *menu = qobject_cast<QMenu*>(sender());
+    AssertMsg(menu == machineLogic()->actionsPool()->action(UIActionIndex_Menu_Debug)->menu(),
+              ("This slot should only be called on 'Debug' menu hovering!\n"));
+
+    menu->clear();
+
+    /* Debug submenu */
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_Statistics));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Simple_CommandLine));
+    menu->addAction(machineLogic()->actionsPool()->action(UIActionIndex_Toggle_Logging));
+}
+#endif /* VBOX_WITH_DEBUGGER_GUI */
+
+void UIMachineWindowNormal::sltUpdateIndicators()
+{
+    CConsole console = machineLogic()->session().GetConsole();
+    QIStateIndicator *pStateIndicator = 0;
+
+    pStateIndicator = indicatorsPool()->indicator(UIIndicatorIndex_HardDisks);
+    if (pStateIndicator->state() != KDeviceActivity_Null)
+    {
+        int state = console.GetDeviceActivity(KDeviceType_HardDisk);
+        if (pStateIndicator->state() != state)
+            pStateIndicator->setState(state);
+    }
+    pStateIndicator = indicatorsPool()->indicator(UIIndicatorIndex_OpticalDisks);
+    if (pStateIndicator->state() != KDeviceActivity_Null)
+    {
+        int state = console.GetDeviceActivity(KDeviceType_DVD);
+        if (pStateIndicator->state() != state)
+            pStateIndicator->setState(state);
+    }
+    pStateIndicator = indicatorsPool()->indicator(UIIndicatorIndex_NetworkAdapters);
+    if (pStateIndicator->state() != KDeviceActivity_Null)
+    {
+        int state = console.GetDeviceActivity(KDeviceType_Network);
+        if (pStateIndicator->state() != state)
+            pStateIndicator->setState(state);
+    }
+    pStateIndicator = indicatorsPool()->indicator(UIIndicatorIndex_USBDevices);
+    if (pStateIndicator->state() != KDeviceActivity_Null)
+    {
+        int state = console.GetDeviceActivity(KDeviceType_USB);
+        if (pStateIndicator->state() != state)
+            pStateIndicator->setState(state);
+    }
+    pStateIndicator = indicatorsPool()->indicator(UIIndicatorIndex_SharedFolders);
+    if (pStateIndicator->state() != KDeviceActivity_Null)
+    {
+        int state = console.GetDeviceActivity(KDeviceType_SharedFolder);
+        if (pStateIndicator->state() != state)
+            pStateIndicator->setState(state);
+    }
+}
+
+void UIMachineWindowNormal::sltShowIndicatorsContextMenu(QIStateIndicator *pIndicator, QContextMenuEvent *pEvent)
+{
+    if (pIndicator == indicatorsPool()->indicator(UIIndicatorIndex_OpticalDisks))
+    {
+        if (machineLogic()->actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu()->isEnabled())
+            machineLogic()->actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu()->exec(pEvent->globalPos());
+    }
+    else if (pIndicator == indicatorsPool()->indicator(UIIndicatorIndex_NetworkAdapters))
+    {
+        if (machineLogic()->actionsPool()->action(UIActionIndex_Menu_NetworkAdapters)->menu()->isEnabled())
+            machineLogic()->actionsPool()->action(UIActionIndex_Menu_NetworkAdapters)->menu()->exec(pEvent->globalPos());
+    }
+    else if (pIndicator == indicatorsPool()->indicator(UIIndicatorIndex_USBDevices))
+    {
+        if (machineLogic()->actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu()->isEnabled())
+            machineLogic()->actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu()->exec(pEvent->globalPos());
+    }
+    else if (pIndicator == indicatorsPool()->indicator(UIIndicatorIndex_SharedFolders))
+    {
+        if (machineLogic()->actionsPool()->action(UIActionIndex_Menu_SharedFolders)->menu()->isEnabled())
+            machineLogic()->actionsPool()->action(UIActionIndex_Menu_SharedFolders)->menu()->exec(pEvent->globalPos());
+    }
+    else if (pIndicator == indicatorsPool()->indicator(UIIndicatorIndex_Mouse))
+    {
+        if (machineLogic()->actionsPool()->action(UIActionIndex_Menu_MouseIntegration)->menu()->isEnabled())
+            machineLogic()->actionsPool()->action(UIActionIndex_Menu_MouseIntegration)->menu()->exec(pEvent->globalPos());
+    }
+}
+
+void UIMachineWindowNormal::sltProcessGlobalSettingChange(const char * /* aPublicName */, const char * /* aName */)
+{
+    m_pNameHostkey->setText(QIHotKeyEdit::keyName(vboxGlobal().settings().hostKey()));
+}
+
+void UIMachineWindowNormal::sltUpdateMediaDriveState(VBoxDefs::MediumType type)
+{
+    Assert(type == VBoxDefs::MediumType_DVD || type == VBoxDefs::MediumType_Floppy);
+    updateAppearanceOf(type == VBoxDefs::MediumType_DVD ? UIVisualElement_CDStuff :
+                       type == VBoxDefs::MediumType_Floppy ? UIVisualElement_FDStuff :
+                       UIVisualElement_AllStuff);
+}
+
+void UIMachineWindowNormal::sltUpdateNetworkAdaptersState()
+{
+    updateAppearanceOf(UIVisualElement_NetworkStuff);
+}
+
+void UIMachineWindowNormal::sltUpdateUsbState()
+{
+    updateAppearanceOf(UIVisualElement_USBStuff);
+}
+
+void UIMachineWindowNormal::sltUpdateSharedFoldersState()
+{
+    updateAppearanceOf(UIVisualElement_SharedFolderStuff);
+}
+
+void UIMachineWindowNormal::sltUpdateMouseState(int iState)
+{
+    if ((iState & UIMouseStateType_MouseAbsoluteDisabled) &&
+        (iState & UIMouseStateType_MouseAbsolute) &&
+        !(iState & UIMouseStateType_MouseCaptured))
+    {
+        indicatorsPool()->indicator(UIIndicatorIndex_Mouse)->setState(4);
+    }
+    else
+    {
+        indicatorsPool()->indicator(UIIndicatorIndex_Mouse)->setState(
+            iState & (UIMouseStateType_MouseAbsolute | UIMouseStateType_MouseCaptured));
+    }
+}
+
+void UIMachineWindowNormal::retranslateUi()
+{
+    /* Translate parent class: */
+    retranslateWindow();
+}
+
+void UIMachineWindowNormal::updateAppearanceOf(int iElement)
+{
+    /* Update parent-class window: */
+    UIMachineWindow::updateAppearanceOf(iElement);
+
+    // TODO: Move most of this update code into indicators-pool!
+
+    /* Update that machine window: */
+    CMachine machine = machineLogic()->session().GetMachine();
+    CConsole console = machineLogic()->session().GetConsole();
+    bool bIsStrictRunningOrPaused = machineLogic()->machineState() == KMachineState_Running ||
+                                    machineLogic()->machineState() == KMachineState_Paused;
+
+    if (iElement & UIVisualElement_HDStuff)
+    {
+        QString strToolTip = tr("<p style='white-space:pre'><nobr>Indicates the activity "
+                                "of the virtual hard disks:</nobr>%1</p>", "HDD tooltip");
+
+        QString strFullData;
+        bool bAttachmentsPresent = false;
+
+        CStorageControllerVector controllers = machine.GetStorageControllers();
+        foreach (const CStorageController &controller, controllers)
+        {
+            QString strAttData;
+            CMediumAttachmentVector attachments = machine.GetMediumAttachmentsOfController(controller.GetName());
+            foreach (const CMediumAttachment &attachment, attachments)
+            {
+                if (attachment.GetType() != KDeviceType_HardDisk)
+                    continue;
+                strAttData += QString("<br>&nbsp;<nobr>%1:&nbsp;%2</nobr>")
+                    .arg(vboxGlobal().toString(StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice())))
+                    .arg(VBoxMedium(attachment.GetMedium(), VBoxDefs::MediumType_HardDisk).location());
+                bAttachmentsPresent = true;
+            }
+            if (!strAttData.isNull())
+                strFullData += QString("<br><nobr><b>%1</b></nobr>").arg(controller.GetName()) + strAttData;
+        }
+
+        if (!bAttachmentsPresent)
+            strFullData += tr("<br><nobr><b>No hard disks attached</b></nobr>", "HDD tooltip");
+
+        indicatorsPool()->indicator(UIIndicatorIndex_HardDisks)->setToolTip(strToolTip.arg(strFullData));
+        indicatorsPool()->indicator(UIIndicatorIndex_HardDisks)->setState(bAttachmentsPresent ? KDeviceActivity_Idle : KDeviceActivity_Null);
+    }
+    if (iElement & UIVisualElement_CDStuff)
+    {
+        QString strToolTip = tr("<p style='white-space:pre'><nobr>Indicates the activity "
+                                "of the CD/DVD devices:</nobr>%1</p>", "CD/DVD tooltip");
+
+        QString strFullData;
+        bool bAttachmentsPresent = false;
+
+        CStorageControllerVector controllers = machine.GetStorageControllers();
+        foreach (const CStorageController &controller, controllers)
+        {
+            QString strAttData;
+            CMediumAttachmentVector attachments = machine.GetMediumAttachmentsOfController(controller.GetName());
+            foreach (const CMediumAttachment &attachment, attachments)
+            {
+                if (attachment.GetType() != KDeviceType_DVD)
+                    continue;
+                VBoxMedium vboxMedium(attachment.GetMedium(), VBoxDefs::MediumType_DVD);
+                strAttData += QString("<br>&nbsp;<nobr>%1:&nbsp;%2</nobr>")
+                    .arg(vboxGlobal().toString(StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice())))
+                    .arg(vboxMedium.isNull() || vboxMedium.isHostDrive() ? vboxMedium.name() : vboxMedium.location());
+                if (!vboxMedium.isNull())
+                    bAttachmentsPresent = true;
+            }
+            if (!strAttData.isNull())
+                strFullData += QString("<br><nobr><b>%1</b></nobr>").arg(controller.GetName()) + strAttData;
+        }
+
+        if (strFullData.isNull())
+            strFullData = tr("<br><nobr><b>No CD/DVD devices attached</b></nobr>", "CD/DVD tooltip");
+
+        indicatorsPool()->indicator(UIIndicatorIndex_OpticalDisks)->setToolTip(strToolTip.arg(strFullData));
+        indicatorsPool()->indicator(UIIndicatorIndex_OpticalDisks)->setState(bAttachmentsPresent ? KDeviceActivity_Idle : KDeviceActivity_Null);
+    }
+    if (iElement & UIVisualElement_NetworkStuff)
+    {
+        ulong uMaxCount = vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount();
+        ulong uCount = 0;
+        for (ulong uSlot = 0; uSlot < uMaxCount; ++ uSlot)
+            if (machine.GetNetworkAdapter(uSlot).GetEnabled())
+                ++ uCount;
+        indicatorsPool()->indicator(UIIndicatorIndex_NetworkAdapters)->setState(uCount > 0 ? KDeviceActivity_Idle : KDeviceActivity_Null);
+
+        machineLogic()->actionsPool()->action(UIActionIndex_Simple_NetworkAdaptersDialog)->setEnabled(bIsStrictRunningOrPaused && uCount > 0);
+        machineLogic()->actionsPool()->action(UIActionIndex_Menu_NetworkAdapters)->setEnabled(bIsStrictRunningOrPaused && uCount > 0);
+
+        QString strToolTip = tr("<p style='white-space:pre'><nobr>Indicates the activity of the "
+                                "network interfaces:</nobr>%1</p>", "Network adapters tooltip");
+        QString strFullData;
+
+        for (ulong uSlot = 0; uSlot < uMaxCount; ++ uSlot)
+        {
+            CNetworkAdapter adapter = machine.GetNetworkAdapter(uSlot);
+            if (adapter.GetEnabled())
+                strFullData += tr("<br><nobr><b>Adapter %1 (%2)</b>: cable %3</nobr>", "Network adapters tooltip")
+                    .arg(uSlot + 1)
+                    .arg(vboxGlobal().toString(adapter.GetAttachmentType()))
+                    .arg(adapter.GetCableConnected() ?
+                          tr("connected", "Network adapters tooltip") :
+                          tr("disconnected", "Network adapters tooltip"));
+        }
+
+        if (strFullData.isNull())
+            strFullData = tr("<br><nobr><b>All network adapters are disabled</b></nobr>", "Network adapters tooltip");
+
+        indicatorsPool()->indicator(UIIndicatorIndex_NetworkAdapters)->setToolTip(strToolTip.arg(strFullData));
+    }
+    if (iElement & UIVisualElement_USBStuff)
+    {
+        if (!indicatorsPool()->indicator(UIIndicatorIndex_USBDevices)->isHidden())
+        {
+            QString strToolTip = tr("<p style='white-space:pre'><nobr>Indicates the activity of "
+                                    "the attached USB devices:</nobr>%1</p>", "USB device tooltip");
+            QString strFullData;
+
+            CUSBController usbctl = machine.GetUSBController();
+            if (!usbctl.isNull() && usbctl.GetEnabled())
+            {
+                machineLogic()->actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu()->setEnabled(bIsStrictRunningOrPaused);
+
+                CUSBDeviceVector devsvec = console.GetUSBDevices();
+                for (int i = 0; i < devsvec.size(); ++ i)
+                {
+                    CUSBDevice usb = devsvec[i];
+                    strFullData += QString("<br><b><nobr>%1</nobr></b>").arg(vboxGlobal().details(usb));
+                }
+                if (strFullData.isNull())
+                    strFullData = tr("<br><nobr><b>No USB devices attached</b></nobr>", "USB device tooltip");
+            }
+            else
+            {
+                machineLogic()->actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu()->setEnabled(false);
+                strFullData = tr("<br><nobr><b>USB Controller is disabled</b></nobr>", "USB device tooltip");
+            }
+
+            indicatorsPool()->indicator(UIIndicatorIndex_USBDevices)->setToolTip(strToolTip.arg(strFullData));
+        }
+    }
+    if (iElement & UIVisualElement_VRDPStuff)
+    {
+        CVRDPServer vrdpsrv = machineLogic()->session().GetMachine().GetVRDPServer();
+        if (!vrdpsrv.isNull())
+        {
+            /* Update menu&status icon state */
+            bool isVRDPEnabled = vrdpsrv.GetEnabled();
+            machineLogic()->actionsPool()->action(UIActionIndex_Toggle_VRDP)->setChecked(isVRDPEnabled);
+        }
+    }
+    if (iElement & UIVisualElement_SharedFolderStuff)
+    {
+        QString strToolTip = tr("<p style='white-space:pre'><nobr>Indicates the activity of "
+                                "the machine's shared folders:</nobr>%1</p>", "Shared folders tooltip");
+
+        QString strFullData;
+        QMap<QString, QString> sfs;
+
+        machineLogic()->actionsPool()->action(UIActionIndex_Menu_SharedFolders)->menu()->setEnabled(true);
+
+        /* Permanent folders */
+        CSharedFolderVector psfvec = machine.GetSharedFolders();
+
+        for (int i = 0; i < psfvec.size(); ++ i)
+        {
+            CSharedFolder sf = psfvec[i];
+            sfs.insert(sf.GetName(), sf.GetHostPath());
+        }
+
+        /* Transient folders */
+        CSharedFolderVector tsfvec = console.GetSharedFolders();
+
+        for (int i = 0; i < tsfvec.size(); ++ i)
+        {
+            CSharedFolder sf = tsfvec[i];
+            sfs.insert(sf.GetName(), sf.GetHostPath());
+        }
+
+        for (QMap<QString, QString>::const_iterator it = sfs.constBegin(); it != sfs.constEnd(); ++ it)
+        {
+            /* Select slashes depending on the OS type */
+            if (VBoxGlobal::isDOSType(console.GetGuest().GetOSTypeId()))
+                strFullData += QString("<br><nobr><b>\\\\vboxsvr\\%1&nbsp;</b></nobr><nobr>%2</nobr>")
+                                       .arg(it.key(), it.value());
+            else
+                strFullData += QString("<br><nobr><b>%1&nbsp;</b></nobr><nobr>%2</nobr>")
+                                       .arg(it.key(), it.value());
+        }
+
+        if (sfs.count() == 0)
+            strFullData = tr("<br><nobr><b>No shared folders</b></nobr>", "Shared folders tooltip");
+
+        indicatorsPool()->indicator(UIIndicatorIndex_SharedFolders)->setToolTip(strToolTip.arg(strFullData));
+    }
+    if (iElement & UIVisualElement_VirtualizationStuff)
+    {
+        bool bVirtEnabled = console.GetDebugger().GetHWVirtExEnabled();
+        QString virtualization = bVirtEnabled ?
+            VBoxGlobal::tr("Enabled", "details report (VT-x/AMD-V)") :
+            VBoxGlobal::tr("Disabled", "details report (VT-x/AMD-V)");
+
+        bool bNestEnabled = console.GetDebugger().GetHWVirtExNestedPagingEnabled();
+        QString nestedPaging = bNestEnabled ?
+            VBoxVMInformationDlg::tr("Enabled", "nested paging") :
+            VBoxVMInformationDlg::tr("Disabled", "nested paging");
+
+        QString tip(tr("Indicates the status of the hardware virtualization "
+                       "features used by this virtual machine:"
+                       "<br><nobr><b>%1:</b>&nbsp;%2</nobr>"
+                       "<br><nobr><b>%3:</b>&nbsp;%4</nobr>",
+                       "Virtualization Stuff LED")
+                       .arg(VBoxGlobal::tr("VT-x/AMD-V", "details report"), virtualization)
+                       .arg(VBoxVMInformationDlg::tr("Nested Paging"), nestedPaging));
+
+        int cpuCount = console.GetMachine().GetCPUCount();
+        if (cpuCount > 1)
+            tip += tr("<br><nobr><b>%1:</b>&nbsp;%2</nobr>", "Virtualization Stuff LED")
+                      .arg(VBoxGlobal::tr("Processor(s)", "details report")).arg(cpuCount);
+
+        indicatorsPool()->indicator(UIIndicatorIndex_Virtualization)->setToolTip(tip);
+        indicatorsPool()->indicator(UIIndicatorIndex_Virtualization)->setState(bVirtEnabled);
+    }
+}
+
+bool UIMachineWindowNormal::event(QEvent *pEvent)
+{
+    switch (pEvent->type())
+    {
+        case QEvent::Resize:
+        {
+            QResizeEvent *pResizeEvent = (QResizeEvent*)pEvent;
+
+            if (!isMaximized())
+            {
+                m_normalGeometry.setSize(pResizeEvent->size());
+#ifdef VBOX_WITH_DEBUGGER_GUI
+                // TODO: Update debugger window size!
+                //dbgAdjustRelativePos();
+#endif
+            }
+            break;
+        }
+        case QEvent::Move:
+        {
+            if (!isMaximized())
+            {
+                m_normalGeometry.moveTo(geometry().x(), geometry().y());
+#ifdef VBOX_WITH_DEBUGGER_GUI
+                // TODO: Update debugger window position!
+                //dbgAdjustRelativePos();
+#endif
+            }
+            break;
+        }
+        default:
+            break;
+    }
+    return QIWithRetranslateUI<QIMainDialog>::event(pEvent);
+}
+
+#ifdef Q_WS_X11
+bool UIMachineWindowNormal::x11Event(XEvent *pEvent)
+{
+    /* Qt bug: when the console view grabs the keyboard, FocusIn, FocusOut,
+     * WindowActivate and WindowDeactivate Qt events are not properly sent
+     * on top level window (i.e. this) deactivation. The fix is to substiute
+     * the mode in FocusOut X11 event structure to NotifyNormal to cause
+     * Qt to process it as desired. */
+    if (pEvent->type == FocusOut)
+    {
+        if (pEvent->xfocus.mode == NotifyWhileGrabbed  &&
+            (pEvent->xfocus.detail == NotifyAncestor ||
+             pEvent->xfocus.detail == NotifyInferior ||
+             pEvent->xfocus.detail == NotifyNonlinear))
+        {
+             pEvent->xfocus.mode = NotifyNormal;
+        }
+    }
+    return false;
+}
+#endif
+
+void UIMachineWindowNormal::prepareMenu()
+{
+    /* Machine submenu: */
+    QMenu *pMenuMachine = machineLogic()->actionsPool()->action(UIActionIndex_Menu_Machine)->menu();
+    menuBar()->addMenu(pMenuMachine);
+    connect(pMenuMachine, SIGNAL(aboutToShow()), this, SLOT(sltPrepareMenuMachine()));
+
+    /* Devices submenu: */
+    QMenu *pMenuDevices = machineLogic()->actionsPool()->action(UIActionIndex_Menu_Devices)->menu();
+    menuBar()->addMenu(pMenuDevices);
+    connect(pMenuDevices, SIGNAL(aboutToShow()), this, SLOT(sltPrepareMenuDevices()));
+
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    if (vboxGlobal().isDebuggerEnabled())
+    {
+        QMenu *pMenuDebug = machineLogic()->actionsPool()->action(UIActionIndex_Menu_Debug)->menu();
+        menuBar()->addMenu(pMenuDebug);
+        connect(pMenuDebug, SIGNAL(aboutToShow()), this, SLOT(sltPrepareMenuDebug()));
+    }
+#endif
+}
+
+void UIMachineWindowNormal::prepareStatusBar()
+{
+    /* Common setup: */
+    setStatusBar(new QIStatusBar(this));
+    QWidget *pIndicatorBox = new QWidget;
+    QHBoxLayout *pIndicatorBoxHLayout = new QHBoxLayout(pIndicatorBox);
+    VBoxGlobal::setLayoutMargin(pIndicatorBoxHLayout, 0);
+    pIndicatorBoxHLayout->setSpacing(5);
+
+    /* Hard Disks: */
+    pIndicatorBoxHLayout->addWidget(indicatorsPool()->indicator(UIIndicatorIndex_HardDisks));
+
+    /* Optical Disks: */
+    QIStateIndicator *pLedOpticalDisks = indicatorsPool()->indicator(UIIndicatorIndex_OpticalDisks);
+    pIndicatorBoxHLayout->addWidget(pLedOpticalDisks);
+    connect(pLedOpticalDisks, SIGNAL(contextMenuRequested(QIStateIndicator*, QContextMenuEvent*)),
+            this, SLOT(sltShowIndicatorsContextMenu(QIStateIndicator*, QContextMenuEvent*)));
+
+    /* Network Adapters: */
+    QIStateIndicator *pLedNetworkAdapters = indicatorsPool()->indicator(UIIndicatorIndex_NetworkAdapters);
+    pIndicatorBoxHLayout->addWidget(pLedNetworkAdapters);
+    connect(pLedNetworkAdapters, SIGNAL(contextMenuRequested(QIStateIndicator*, QContextMenuEvent*)),
+            this, SLOT(sltShowIndicatorsContextMenu(QIStateIndicator*, QContextMenuEvent*)));
+
+    /* USB Devices: */
+    QIStateIndicator *pLedUSBDevices = indicatorsPool()->indicator(UIIndicatorIndex_USBDevices);
+    pIndicatorBoxHLayout->addWidget(pLedUSBDevices);
+    connect(pLedUSBDevices, SIGNAL(contextMenuRequested(QIStateIndicator*, QContextMenuEvent*)),
+            this, SLOT(sltShowIndicatorsContextMenu(QIStateIndicator*, QContextMenuEvent*)));
+
+    /* Shared Folders: */
+    QIStateIndicator *pLedSharedFolders = indicatorsPool()->indicator(UIIndicatorIndex_SharedFolders);
+    pIndicatorBoxHLayout->addWidget(pLedSharedFolders);
+    connect(pLedSharedFolders, SIGNAL(contextMenuRequested(QIStateIndicator*, QContextMenuEvent*)),
+            this, SLOT(sltShowIndicatorsContextMenu(QIStateIndicator*, QContextMenuEvent*)));
+
+    /* Virtualization: */
+    pIndicatorBoxHLayout->addWidget(indicatorsPool()->indicator(UIIndicatorIndex_Virtualization));
+
+    /* Separator: */
+    QFrame *pSeparator = new QFrame;
+    pSeparator->setFrameStyle(QFrame::VLine | QFrame::Sunken);
+    pIndicatorBoxHLayout->addWidget(pSeparator);
+
+    /* Mouse: */
+    QIStateIndicator *pLedMouse = indicatorsPool()->indicator(UIIndicatorIndex_Mouse);
+    pIndicatorBoxHLayout->addWidget(pLedMouse);
+    connect(pLedMouse, SIGNAL(contextMenuRequested(QIStateIndicator*, QContextMenuEvent*)),
+            this, SLOT(sltShowIndicatorsContextMenu(QIStateIndicator*, QContextMenuEvent*)));
+
+    /* Host Key: */
+    m_pCntHostkey = new QWidget;
+    QHBoxLayout *pHostkeyLedContainerLayout = new QHBoxLayout(m_pCntHostkey);
+    VBoxGlobal::setLayoutMargin(pHostkeyLedContainerLayout, 0);
+    pHostkeyLedContainerLayout->setSpacing(3);
+    pIndicatorBoxHLayout->addWidget(m_pCntHostkey);
+    pHostkeyLedContainerLayout->addWidget(indicatorsPool()->indicator(UIIndicatorIndex_Hostkey));
+    m_pNameHostkey = new QLabel(QIHotKeyEdit::keyName(vboxGlobal().settings().hostKey()));
+    pHostkeyLedContainerLayout->addWidget(m_pNameHostkey);
+
+    /* Add to statusbar: */
+    statusBar()->addPermanentWidget(pIndicatorBox, 0);
+
+    /* Create & start timer to update LEDs: */
+    m_pIdleTimer = new QTimer(this);
+    connect(m_pIdleTimer, SIGNAL(timeout()), this, SLOT(sltUpdateIndicators()));
+    m_pIdleTimer->start(50);
+
+#ifdef Q_WS_MAC
+    /* For the status bar on Cocoa: */
+    setUnifiedTitleAndToolBarOnMac(true);
+#endif
+}
+
+void UIMachineWindowNormal::prepareConnections()
+{
+    /* Setup global settings <-> indicators connections: */
+    connect(&vboxGlobal().settings(), SIGNAL(propertyChanged(const char *, const char *)),
+            this, SLOT(sltProcessGlobalSettingChange(const char *, const char *)));
+}
+
+void UIMachineWindowNormal::prepareMachineView()
+{
+    CMachine machine = machineLogic()->session().GetMachine();
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    /* Need to force the QGL framebuffer in case 2D Video Acceleration is supported & enabled: */
+    bool bAccelerate2DVideo = machine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable();
+#endif
+
+    m_pMachineView = UIMachineView::create(  this
+                                           , vboxGlobal().vmRenderMode() // TODO: use correct variable here!
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                                           , bAccelerate2DVideo // TODO: use correct variable here!
+#endif
+                                           , machineLogic()->visualStateType());
+    qobject_cast<QGridLayout*>(centralWidget()->layout())->addWidget(m_pMachineView, 1, 1, Qt::AlignVCenter | Qt::AlignHCenter);
+
+    /* Setup machine view <-> indicators connections: */
+    connect(machineView(), SIGNAL(keyboardStateChanged(int)),
+            indicatorsPool()->indicator(UIIndicatorIndex_Hostkey), SLOT(setState(int)));
+    // TODO: Update these 5 indicators through indicators pool!
+    connect(machineView(), SIGNAL(mediaDriveChanged(VBoxDefs::MediumType)),
+            this, SLOT(sltUpdateMediaDriveState(VBoxDefs::MediumType)));
+    connect(machineView(), SIGNAL(networkStateChange()), this, SLOT(sltUpdateNetworkAdaptersState()));
+    connect(machineView(), SIGNAL(usbStateChange()), this, SLOT(sltUpdateUsbState()));
+    connect(machineView(), SIGNAL(sharedFoldersChanged()), this, SLOT(sltUpdateSharedFoldersState()));
+    connect(machineView(), SIGNAL(mouseStateChanged(int)), this, SLOT(sltUpdateMouseState(int)));
+}
+
+void UIMachineWindowNormal::loadWindowSettings()
+{
+    CMachine machine = machineLogic()->session().GetMachine();
+
+    /* Extra-data settings */
+    {
+        QString strPositionSettings = machine.GetExtraData(VBoxDefs::GUI_LastWindowPosition);
+
+        bool ok = false, max = false;
+        int x = 0, y = 0, w = 0, h = 0;
+        x = strPositionSettings.section(',', 0, 0).toInt(&ok);
+        if (ok)
+            y = strPositionSettings.section(',', 1, 1).toInt(&ok);
+        if (ok)
+            w = strPositionSettings.section(',', 2, 2).toInt(&ok);
+        if (ok)
+            h = strPositionSettings.section(',', 3, 3).toInt(&ok);
+        if (ok)
+            max = strPositionSettings.section(',', 4, 4) == VBoxDefs::GUI_LastWindowPosition_Max;
+
+        QRect ar = ok ? QApplication::desktop()->availableGeometry(QPoint(x, y)) :
+                        QApplication::desktop()->availableGeometry(machineWindow());
+
+        if (ok /* if previous parameters were read correctly */)
+        {
+            m_normalGeometry = QRect(x, y, w, h);
+            setGeometry(m_normalGeometry);
+
+            /* Normalize to the optimal size */
+            machineView()->normalizeGeometry(true /* adjust position? */);
+
+            /* Maximize if needed */
+            if (max)
+                setWindowState(windowState() | Qt::WindowMaximized);
+        }
+        else
+        {
+            /* Normalize to the optimal size */
+            machineView()->normalizeGeometry(true /* adjust position? */);
+
+            /* Move newly created window to the screen center: */
+            m_normalGeometry = geometry();
+            m_normalGeometry.moveCenter(ar.center());
+            setGeometry(m_normalGeometry);
+        }
+    }
+
+    /* Availability settings */
+    {
+        /* USB Stuff: */
+        CUSBController usbController = machine.GetUSBController();
+        if (usbController.isNull())
+        {
+            /* Hide USB Menu: */
+            indicatorsPool()->indicator(UIIndicatorIndex_USBDevices)->setHidden(true);
+        }
+        else
+        {
+            /* Toggle USB LED: */
+            indicatorsPool()->indicator(UIIndicatorIndex_USBDevices)->setState(
+                usbController.GetEnabled() ? KDeviceActivity_Idle : KDeviceActivity_Null);
+        }
+    }
+
+    /* Global settings */
+    {
+        VBoxGlobalSettings settings = vboxGlobal().settings();
+        menuBar()->setHidden(settings.isFeatureActive("noMenuBar"));
+        statusBar()->setHidden(settings.isFeatureActive("noStatusBar"));
+    }
+}
+
+void UIMachineWindowNormal::saveWindowSettings()
+{
+    CMachine machine = machineLogic()->session().GetMachine();
+
+    /* Extra-data settings */
+    {
+        QString strWindowPosition = QString("%1,%2,%3,%4")
+                                .arg(m_normalGeometry.x()).arg(m_normalGeometry.y())
+                                .arg(m_normalGeometry.width()).arg(m_normalGeometry.height());
+        if (isMaximized())
+            strWindowPosition += QString(",%1").arg(VBoxDefs::GUI_LastWindowPosition_Max);
+        machine.SetExtraData(VBoxDefs::GUI_LastWindowPosition, strWindowPosition);
+    }
+}
+
+void UIMachineWindowNormal::cleanupStatusBar()
+{
+    /* Stop LED-update timer: */
+    m_pIdleTimer->stop();
+    m_pIdleTimer->disconnect(SIGNAL(timeout()), this, SLOT(updateDeviceLights()));
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h	(revision 26637)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h	(revision 26637)
@@ -0,0 +1,117 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIMachineWindowNormal class declaration
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIMachineWindowNormal_h__
+#define __UIMachineWindowNormal_h__
+
+/* Global includes */
+#include <QLabel>
+
+/* Local includes */
+#include "VBoxDefs.h"
+#include "QIWithRetranslateUI.h"
+#include "QIMainDialog.h"
+#include "UIMachineWindow.h"
+#ifdef Q_WS_X11
+# include <X11/Xlib.h>
+#endif
+
+/* Local forwards */
+class UIIndicatorsPool;
+class QIStateIndicator;
+
+class UIMachineWindowNormal : public QIWithRetranslateUI<QIMainDialog>, public UIMachineWindow
+{
+    Q_OBJECT;
+
+protected:
+
+    UIMachineWindowNormal(UIMachineLogic *pMachineLogic);
+    virtual ~UIMachineWindowNormal();
+
+private slots:
+
+    void sltTryClose();
+
+    void sltPrepareMenuMachine();
+    void sltPrepareMenuDevices();
+#ifdef VBOX_WITH_DEBUGGER_GUI
+    void sltPrepareMenuDebug();
+#endif
+
+    void sltUpdateIndicators();
+    void sltShowIndicatorsContextMenu(QIStateIndicator *pIndicator, QContextMenuEvent *pEvent);
+
+    void sltProcessGlobalSettingChange(const char *aPublicName, const char *aName);
+
+    void sltUpdateMediaDriveState(VBoxDefs::MediumType type);
+    void sltUpdateNetworkAdaptersState();
+    void sltUpdateUsbState();
+    void sltUpdateSharedFoldersState();
+    void sltUpdateMouseState(int iState);
+
+private:
+
+    /* Translate routine: */
+    void retranslateUi();
+
+    /* Update routines: */
+    void updateAppearanceOf(int aElement);
+
+    /* Event handlers: */
+    bool event(QEvent *pEvent);
+#ifdef Q_WS_X11
+    bool x11Event(XEvent *pEvent);
+#endif
+
+    /* Private getters: */
+    UIIndicatorsPool* indicatorsPool() { return m_pIndicatorsPool; }
+
+    /* Prepare helpers: */
+    void prepareMenu();
+    void prepareStatusBar();
+    void prepareConnections();
+    void prepareMachineView();
+    void loadWindowSettings();
+
+    /* Cleanup helpers: */
+    void saveWindowSettings();
+    //void cleanupMachineView();
+    //void cleanupConnections();
+    void cleanupStatusBar();
+    //void cleanupMenu();
+
+    /* Indicators pool: */
+    UIIndicatorsPool *m_pIndicatorsPool;
+    /* Other QWidgets: */
+    QWidget *m_pCntHostkey;
+    QLabel *m_pNameHostkey;
+    /* Other QObjects: */
+    QTimer *m_pIdleTimer;
+    /* Other members: */
+    QRect m_normalGeometry;
+
+    /* Factory support: */
+    friend class UIMachineWindow;
+};
+
+#endif // __UIMachineWindowNormal_h__
