VirtualBox

Ignore:
Timestamp:
Mar 12, 2015 5:49:10 PM (10 years ago)
Author:
vboxsync
Message:

FE/Qt: 7676: Runtime UI: Disk Encryption (DE) support: Moving stuff into separate files, improving doxy.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
2 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r54731 r54733  
    299299        src/medium/UIMediumManager.h \
    300300        src/runtime/UIActionPoolRuntime.h \
     301        src/runtime/UIAddDiskEncryptionPasswordDialog.h \
    301302        src/runtime/UIConsoleEventHandler.h \
    302303        src/runtime/UIFrameBuffer.h \
     
    491492        src/medium/UIMediumManager.cpp \
    492493        src/runtime/UIActionPoolRuntime.cpp \
     494        src/runtime/UIAddDiskEncryptionPasswordDialog.cpp \
    493495        src/runtime/UIFrameBuffer.cpp \
    494496        src/runtime/UIIndicatorsPool.cpp \
    495497        src/runtime/UIStatusBarEditorWindow.cpp \
    496     src/runtime/UISession.cpp \
    497498        src/selector/UIActionPoolSelector.cpp \
    498499        src/selector/UIVMDesktop.cpp \
     
    579580        src/medium/UIMediumManager.cpp \
    580581        src/runtime/UIActionPoolRuntime.cpp \
     582        src/runtime/UIAddDiskEncryptionPasswordDialog.cpp \
    581583        src/runtime/UIConsoleEventHandler.cpp \
    582584        src/runtime/UIFrameBuffer.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.cpp

    r54732 r54733  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UISession class implementation.
     3 * VBox Qt GUI - UIAddDiskEncryptionPasswordDialog class implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121
    2222/* Qt includes: */
    23 # include <QApplication>
    24 # include <QDesktopWidget>
    25 # include <QWidget>
    26 # ifdef Q_WS_MAC
    27 #  include <QTimer>
    28 # endif /* Q_WS_MAC */
     23# include <QVBoxLayout>
     24# include <QLineEdit>
     25# include <QTableView>
     26# include <QHeaderView>
     27# include <QItemEditorFactory>
     28# include <QAbstractTableModel>
     29# include <QStandardItemEditorCreator>
    2930
    3031/* GUI includes: */
    31 # include "VBoxGlobal.h"
    32 # include "UIExtraDataManager.h"
    33 # include "UISession.h"
    34 # include "UIMachine.h"
    35 # include "UIMedium.h"
    36 # include "UIActionPoolRuntime.h"
    37 # include "UIMachineLogic.h"
    38 # include "UIMachineView.h"
    39 # include "UIMachineWindow.h"
    40 # include "UIMessageCenter.h"
    41 # include "UIPopupCenter.h"
    42 # include "UIWizardFirstRun.h"
    43 # include "UIConsoleEventHandler.h"
    44 # include "UIFrameBuffer.h"
    45 # include "UISettingsDialogSpecific.h"
    46 # ifdef VBOX_WITH_VIDEOHWACCEL
    47 #  include "VBoxFBOverlay.h"
    48 # endif /* VBOX_WITH_VIDEOHWACCEL */
    49 # ifdef Q_WS_MAC
    50 #  include "UIMenuBar.h"
    51 #  include "VBoxUtils-darwin.h"
    52 # endif /* Q_WS_MAC */
    53 
    54 # ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    55 #  include "UIKeyboardHandler.h"
    56 #  include <signal.h>
    57 # endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    58 
    59 /* COM includes: */
    60 # include "CSystemProperties.h"
    61 # include "CStorageController.h"
    62 # include "CMediumAttachment.h"
    63 # include "CNetworkAdapter.h"
    64 # include "CHostNetworkInterface.h"
    65 # include "CVRDEServer.h"
    66 # include "CUSBController.h"
    67 # include "CUSBDeviceFilters.h"
    68 # include "CHostVideoInputDevice.h"
    69 # include "CSnapshot.h"
    70 # include "CMedium.h"
     32# include "QILabel.h"
     33# include "QIDialogButtonBox.h"
     34# include "QIWithRetranslateUI.h"
     35# include "QIStyledItemDelegate.h"
     36# include "UIAddDiskEncryptionPasswordDialog.h"
     37
     38/* Other VBox includes: */
     39# include <iprt/assert.h>
    7140
    7241#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    7342
    74 #ifdef Q_WS_X11
    75 # include <QX11Info>
    76 # include <X11/Xlib.h>
    77 # include <X11/Xutil.h>
    78 # ifndef VBOX_WITHOUT_XCURSOR
    79 #  include <X11/Xcursor/Xcursor.h>
    80 # endif /* VBOX_WITHOUT_XCURSOR */
    81 #endif /* Q_WS_X11 */
    82 
    83 
    84 /* Qt includes: */
    85 #include <QDialog>
    86 #include <QVBoxLayout>
    87 #include <QLineEdit>
    88 #include <QTableView>
    89 #include <QHeaderView>
    90 #include <QItemEditorFactory>
    91 #include <QAbstractTableModel>
    92 #include <QStandardItemEditorCreator>
    93 /* GUI includes: */
    94 #include "QILabel.h"
    95 #include "QIDialogButtonBox.h"
    96 #include "QIWithRetranslateUI.h"
    97 #include "QIStyledItemDelegate.h"
    98 
    99 /* Type definitions: */
    100 typedef QMap<QString, QString> EncryptionPasswordsMap;
    101 typedef QMultiMap<QString, QString> EncryptedMediumsMap;
    102 
    103 /** Encryption-data table field indexes.
    104   * @todo To be moved into separate file.. */
    105 enum UIEncryptionTableSection
    106 {
    107     UIEncryptionTableSection_Id,
    108     UIEncryptionTableSection_Password,
    109     UIEncryptionTableSection_Max
     43/** UIEncryptionDataTable field indexes. */
     44enum UIEncryptionDataTableSection
     45{
     46    UIEncryptionDataTableSection_Id,
     47    UIEncryptionDataTableSection_Password,
     48    UIEncryptionDataTableSection_Max
    11049};
    11150
    112 /** QLineEdit implementation allowing to enter
    113   * disk encryption password for particular password id.
    114   * @todo To be moved into separate file.. */
    115 class UILineEdit : public QLineEdit
     51/** QLineEdit reimplementation used as
     52  * the embedded password editor for the UIEncryptionDataTable. */
     53class UIPasswordEditor : public QLineEdit
    11654{
    11755    Q_OBJECT;
     56
     57    /** Holds the current password of the editor. */
    11858    Q_PROPERTY(QString password READ password WRITE setPassword USER true);
    11959
    12060signals:
    12161
    122     /** Notifies listener about data should be committed. */
     62    /** Notifies listeners about data should be committed. */
    12363    void sigCommitData(QWidget *pThis);
    12464
     
    12767    /** Constructor.
    12868      * @param pParent being passed to the base-class. */
    129     UILineEdit(QWidget *pParent)
    130         : QLineEdit(pParent)
    131     {
    132         /* Prepare: */
    133         prepare();
    134     }
    135 
    136 public slots:
    137 
    138     /** Handles @s strText changes. */
    139     void sltTextChanged(const QString &strText)
    140     {
    141         Q_UNUSED(strText);
    142         /* Commit data to the listener: */
    143         emit sigCommitData(this);
    144     }
     69    UIPasswordEditor(QWidget *pParent);
     70
     71private slots:
     72
     73    /** Handles @s strPassword changes. */
     74    void sltPasswordChanged(const QString &strPassword);
    14575
    14676private:
    14777
    14878    /** Prepare routine. */
    149     void prepare()
    150     {
    151         /* Set alignment: */
    152         setAlignment(Qt::AlignCenter);
    153         /* Set echo mode: */
    154         setEchoMode(QLineEdit::Password);
    155         /* Listen for the text changes: */
    156         connect(this, SIGNAL(textChanged(const QString&)),
    157                 this, SLOT(sltTextChanged(const QString&)));
    158     }
    159 
    160     /** Returns the password from the editor. */
     79    void prepare();
     80
     81    /** Property: Returns the current password of the editor. */
    16182    QString password() const { return QLineEdit::text(); }
    162     /** Defines the @a strPassword to the editor. */
     83    /** Property: Defines the current @a strPassword of the editor. */
    16384    void setPassword(const QString &strPassword) { QLineEdit::setText(strPassword); }
    16485};
    16586
    166 /** QAbstractTableModel implementation reflecting
    167   * disk encryption passwords for particular password ids.
    168   * @todo To be moved into separate file.. */
     87/** QAbstractTableModel reimplementation used as
     88  * the data representation model for the UIEncryptionDataTable. */
    16989class UIEncryptionDataModel : public QAbstractTableModel
    17090{
     
    17696      * @param pParent          being passed to the base-class,
    17797      * @param encryptedMediums contains the lists of medium ids (values) encrypted with passwords with ids (keys). */
    178     UIEncryptionDataModel(QObject *pParent, const EncryptedMediumsMap &encryptedMediums)
    179         : QAbstractTableModel(pParent)
    180         , m_encryptedMediums(encryptedMediums)
    181     {
    182         /* Prepare: */
    183         prepare();
    184     }
    185 
    186     /** Returns encryption passwords. */
     98    UIEncryptionDataModel(QObject *pParent, const EncryptedMediumsMap &encryptedMediums);
     99
     100    /** Returns the shallow copy of the encryption password map instance. */
    187101    EncryptionPasswordsMap encryptionPasswords() const { return m_encryptionPasswords; }
    188102
     103    /** Returns the row count, taking optional @a parent instead of root if necessary. */
     104    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
     105    /** Returns the column count, taking optional @a parent instead of root if necessary. */
     106    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
     107
    189108    /** Returns the @a index flags. */
    190     virtual Qt::ItemFlags flags(const QModelIndex &index) const
    191     {
    192         /* Check index validness: */
    193         if (!index.isValid())
    194             return Qt::NoItemFlags;
    195         /* Depending on column index: */
    196         switch (index.column())
    197         {
    198             case UIEncryptionTableSection_Id:       return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    199             case UIEncryptionTableSection_Password: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    200             default: break;
    201         }
    202         /* No flags by default: */
    203         return Qt::NoItemFlags;
    204     }
    205 
    206     /** Returns the row count. Provide optional @a parent instead of root if necessary. */
    207     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
    208     {
    209         Q_UNUSED(parent);
    210         return m_encryptionPasswords.size();
    211     }
    212 
    213     /** Returns the column count. Provide optional @a parent instead of root if necessary. */
    214     virtual int columnCount(const QModelIndex &parent = QModelIndex()) const
    215     {
    216         Q_UNUSED(parent);
    217         return UIEncryptionTableSection_Max;
    218     }
    219 
    220     /** Returns header data for @a iSection, @a orientation and @a iRole. */
    221     virtual QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const
    222     {
    223         /* Check argument validness: */
    224         if (iRole != Qt::DisplayRole || orientation != Qt::Horizontal)
    225             return QVariant();
    226         /* Depending on column index: */
    227         switch (iSection)
    228         {
    229             case UIEncryptionTableSection_Id:       return tr("Password ID");
    230             case UIEncryptionTableSection_Password: return tr("Password");
    231             default: break;
    232         }
    233         /* Null value by default: */
    234         return QVariant();
    235     }
    236 
    237     /** Returns @a index data for @a iRole. */
    238     virtual QVariant data(const QModelIndex &index, int iRole /* = Qt::DisplayRole */) const
    239     {
    240         /* Check index validness: */
    241         if (!index.isValid())
    242             return QVariant();
    243         /* Depending on role: */
    244         switch (iRole)
    245         {
    246             case Qt::DisplayRole:
    247             {
    248                 /* Depending on column index: */
    249                 switch (index.column())
    250                 {
    251                     case UIEncryptionTableSection_Id:
    252                         return m_encryptionPasswords.keys().at(index.row());
    253                     case UIEncryptionTableSection_Password:
    254                         return QString().fill('*', m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row())).size());
    255                     default:
    256                         return QVariant();
    257                 }
    258                 break;
    259             }
    260             case Qt::EditRole:
    261             {
    262                 /* Depending on column index: */
    263                 switch (index.column())
    264                 {
    265                     case UIEncryptionTableSection_Password:
    266                         return m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row()));
    267                     default:
    268                         return QVariant();
    269                 }
    270                 break;
    271             }
    272             case Qt::TextAlignmentRole:
    273             {
    274                 /* Depending on column index: */
    275                 switch (index.column())
    276                 {
    277                     case UIEncryptionTableSection_Password:
    278                         return Qt::AlignCenter;
    279                     default: return QVariant();
    280                 }
    281                 break;
    282             }
    283             default:
    284                 break;
    285         }
    286         /* Null value by default: */
    287         return QVariant();
    288     }
    289 
    290     /** Defines @a index data for @a iRole as @a value. */
    291     virtual bool setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole */)
    292     {
    293         /* Check index validness: */
    294         if (!index.isValid())
    295             return false;
    296         /* Check argument validness: */
    297         if (iRole != Qt::EditRole)
    298             return false;
    299         /* Depending on column index: */
    300         switch (index.column())
    301         {
    302             case UIEncryptionTableSection_Password: m_encryptionPasswords[m_encryptionPasswords.keys().at(index.row())] = value.toString(); break;
    303             default: break;
    304         }
    305         /* Nothing to set by default: */
    306         return false;
    307     }
     109    virtual Qt::ItemFlags flags(const QModelIndex &index) const;
     110
     111    /** Returns the header data for the @a iSection, @a orientation and @a iRole. */
     112    virtual QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const;
     113
     114    /** Returns the @a index data for the @a iRole. */
     115    virtual QVariant data(const QModelIndex &index, int iRole = Qt::DisplayRole) const;
     116    /** Defines the @a index data for the @a iRole as @a value. */
     117    virtual bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole);
    308118
    309119private:
    310120
    311121    /** Prepare routine. */
    312     void prepare()
    313     {
    314         /* Populate the map of passwords. */
    315         foreach (const QString &strPasswordId, m_encryptedMediums.keys())
    316             m_encryptionPasswords.insert(strPasswordId, QString());
    317     }
     122    void prepare();
    318123
    319124    /** Holds the encrypted medium map reference. */
    320125    const EncryptedMediumsMap &m_encryptedMediums;
    321126
    322     /** Holds the encrypted password id map. */
     127    /** Holds the encryption password map instance. */
    323128    EncryptionPasswordsMap m_encryptionPasswords;
    324129};
    325130
    326 /** QTableView implementation allowing to enter
    327   * disk encryption passwords for particular password ids.
    328   * @todo To be moved into separate file.. */
     131/** QTableView reimplementation used to
     132  * allow the UIAddDiskEncryptionPasswordDialog to enter
     133  * disk encryption passwords for particular password ids. */
    329134class UIEncryptionDataTable : public QTableView
    330135{
     
    335140    /** Constructor.
    336141      * @param pParent being passed to the base-class. */
    337     UIEncryptionDataTable(const EncryptedMediumsMap &encryptedMediums)
    338         : m_encryptedMediums(encryptedMediums)
    339         , m_pModelEncryptionData(0)
    340     {
    341         /* Prepare: */
    342         prepare();
    343     }
    344 
    345     /** Returns encryption passwords. */
    346     EncryptionPasswordsMap encryptionPasswords() const
    347     {
    348         AssertPtrReturn(m_pModelEncryptionData, EncryptionPasswordsMap());
    349         return m_pModelEncryptionData->encryptionPasswords();
    350     }
     142    UIEncryptionDataTable(const EncryptedMediumsMap &encryptedMediums);
     143
     144    /** Returns the shallow copy of the encryption password map
     145      * acquired from the UIEncryptionDataModel instance. */
     146    EncryptionPasswordsMap encryptionPasswords() const;
    351147
    352148private:
    353149
    354150    /** Prepare routine. */
    355     void prepare()
    356     {
    357         /* Create encryption-data model: */
    358         m_pModelEncryptionData = new UIEncryptionDataModel(this, m_encryptedMediums);
    359         AssertPtrReturnVoid(m_pModelEncryptionData);
    360         {
    361             /* Assign configured model to table: */
    362             setModel(m_pModelEncryptionData);
    363         }
    364 
    365         /* Create item delegate: */
    366         QIStyledItemDelegate *pStyledItemDelegate = new QIStyledItemDelegate(this);
    367         AssertPtrReturnVoid(pStyledItemDelegate);
    368         {
    369             /* Create item editor factory: */
    370             QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    371             AssertPtrReturnVoid(pNewItemEditorFactory);
    372             {
    373                 /* Create item editor creator: */
    374                 QStandardItemEditorCreator<UILineEdit> *pQStringItemEditorCreator = new QStandardItemEditorCreator<UILineEdit>();
    375                 AssertPtrReturnVoid(pQStringItemEditorCreator);
    376                 {
    377                     /* Register UILineEdit as the QString editor: */
    378                     pNewItemEditorFactory->registerEditor(QVariant::String, pQStringItemEditorCreator);
    379                 }
    380                 /* Assign configured item editor factory to table delegate: */
    381                 pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
    382             }
    383             /* Assign configured item delegate to table: */
    384             delete itemDelegate();
    385             setItemDelegate(pStyledItemDelegate);
    386         }
    387 
    388         /* Configure table: */
    389         setTabKeyNavigation(false);
    390         setContextMenuPolicy(Qt::CustomContextMenu);
    391         setSelectionBehavior(QAbstractItemView::SelectRows);
    392         setSelectionMode(QAbstractItemView::SingleSelection);
    393         setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
    394 
    395         /* Configure headers: */
    396         verticalHeader()->hide();
    397         verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));
    398         horizontalHeader()->setStretchLastSection(false);
    399         horizontalHeader()->setResizeMode(UIEncryptionTableSection_Id, QHeaderView::Interactive);
    400         horizontalHeader()->setResizeMode(UIEncryptionTableSection_Password, QHeaderView::Stretch);
    401     }
     151    void prepare();
    402152
    403153    /** Holds the encrypted medium map reference. */
    404154    const EncryptedMediumsMap &m_encryptedMediums;
    405155
    406     /** Holds the encryption-data model. */
     156    /** Holds the encryption-data model instance. */
    407157    UIEncryptionDataModel *m_pModelEncryptionData;
    408158};
    409159
    410 /** QDialog implementation allowing to enter
    411   * disk encryption passwords for particular password ids.
    412   * @todo To be moved into separate files.. */
    413 class UIAddDiskEncryptionPasswordDialog : public QIWithRetranslateUI<QDialog>
    414 {
    415     Q_OBJECT;
    416 
    417 public:
    418 
    419     /** Constructor.
    420       * @param pParent          being passed to the base-class,
    421       * @param encryptedMediums contains the lists of medium ids (values) encrypted with passwords with ids (keys). */
    422     UIAddDiskEncryptionPasswordDialog(QWidget *pParent, const EncryptedMediumsMap &encryptedMediums)
    423         : QIWithRetranslateUI<QDialog>(pParent)
    424         , m_encryptedMediums(encryptedMediums)
    425         , m_pLabelDescription(0)
    426         , m_pTableEncryptionData(0)
    427     {
    428         /* Prepare: */
    429         prepare();
    430         /* Retranslate: */
    431         retranslateUi();
    432     }
    433 
    434     /** Returns encryption passwords. */
    435     EncryptionPasswordsMap encryptionPasswords() const
    436     {
    437         AssertPtrReturn(m_pTableEncryptionData, EncryptionPasswordsMap());
    438         return m_pTableEncryptionData->encryptionPasswords();
    439     }
    440 
    441 private:
    442 
    443     /** Prepare routine. */
    444     void prepare()
    445     {
    446         /* Create main-layout: */
    447         QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    448         AssertPtrReturnVoid(pMainLayout);
    449         {
    450             /* Create input-layout: */
    451             QVBoxLayout *pInputLayout = new QVBoxLayout;
    452             AssertPtrReturnVoid(pInputLayout);
    453             {
    454                 /* Create description label: */
    455                 m_pLabelDescription = new QILabel;
    456                 m_pLabelDescription->useSizeHintForWidth(450);
    457                 m_pLabelDescription->updateGeometry();
    458                 AssertPtrReturnVoid(m_pLabelDescription);
    459                 {
    460                     /* Configure description label: */
    461                     m_pLabelDescription->setWordWrap(true);
    462                     /* Add label into layout: */
    463                     pInputLayout->addWidget(m_pLabelDescription);
    464                 }
    465                 /* Create encryption-data table: */
    466                 m_pTableEncryptionData = new UIEncryptionDataTable(m_encryptedMediums);
    467                 AssertPtrReturnVoid(m_pTableEncryptionData);
    468                 {
    469                     /* Add label into layout: */
    470                     pInputLayout->addWidget(m_pTableEncryptionData);
    471                 }
    472                 /* Add layout into parent: */
    473                 pMainLayout->addLayout(pInputLayout);
    474             }
    475             /* Create button-box: */
    476             QIDialogButtonBox *pButtonBox = new QIDialogButtonBox;
    477             AssertPtrReturnVoid(pButtonBox);
    478             {
    479                 /* Configure button-box: */
    480                 pButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    481                 connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
    482                 connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
    483                 /* Add button-box into layout: */
    484                 pMainLayout->addWidget(pButtonBox);
    485             }
    486         }
    487     }
    488 
    489     /** Translation routine. */
    490     void retranslateUi()
    491     {
    492         AssertPtrReturnVoid(m_pLabelDescription);
    493         m_pLabelDescription->setText(tr("This virtual machine is password protected. "
    494                                         "Please enter the %n encryption password(s) below.",
    495                                         "This text is never used with n == 0. "
    496                                         "Feel free to drop the %n where possible, "
    497                                         "we only included it because of problems with Qt Linguist "
    498                                         "(but the user can see how many passwords are in the list "
    499                                         "and doesn't need to be told).",
    500                                         m_encryptedMediums.size()));
    501     }
    502 
    503     /** Holds the encrypted medium map reference. */
    504     const EncryptedMediumsMap &m_encryptedMediums;
    505 
    506     /** Holds the description label. */
    507     QILabel *m_pLabelDescription;
    508     /** Holds the encryption-data table. */
    509     UIEncryptionDataTable *m_pTableEncryptionData;
    510 };
    511 
    512 
    513 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    514 static void signalHandlerSIGUSR1(int sig, siginfo_t *, void *);
    515 #endif
    516 
    517 #ifdef Q_WS_MAC
    518 /**
    519  * MacOS X: Application Services: Core Graphics: Display reconfiguration callback.
    520  *
    521  * Notifies UISession about @a display configuration change.
    522  * Corresponding change described by Core Graphics @a flags.
    523  * Uses UISession @a pHandler to process this change.
    524  *
    525  * @note Last argument (@a pHandler) must always be valid pointer to UISession object.
    526  * @note Calls for UISession::sltHandleHostDisplayAboutToChange() slot if display configuration changed.
    527  */
    528 void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *pHandler)
    529 {
    530     /* Which flags we are handling? */
    531     int iHandledFlags = kCGDisplayAddFlag     /* display added */
    532                       | kCGDisplayRemoveFlag  /* display removed */
    533                       | kCGDisplaySetModeFlag /* display mode changed */;
    534 
    535     /* Handle 'display-add' case: */
    536     if (flags & kCGDisplayAddFlag)
    537         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display added.\n"));
    538     /* Handle 'display-remove' case: */
    539     else if (flags & kCGDisplayRemoveFlag)
    540         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display removed.\n"));
    541     /* Handle 'mode-set' case: */
    542     else if (flags & kCGDisplaySetModeFlag)
    543         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display mode changed.\n"));
    544 
    545     /* Ask handler to process our callback: */
    546     if (flags & iHandledFlags)
    547         QTimer::singleShot(0, static_cast<UISession*>(pHandler),
    548                            SLOT(sltHandleHostDisplayAboutToChange()));
    549 
    550     Q_UNUSED(display);
    551 }
    552 #endif /* Q_WS_MAC */
    553 
    554 /* static */
    555 bool UISession::create(UISession *&pSession, UIMachine *pMachine)
    556 {
    557     /* Make sure null pointer passed: */
    558     AssertReturn(pSession == 0, false);
    559 
    560     /* Create session UI: */
    561     pSession = new UISession(pMachine);
    562     /* Make sure it's prepared: */
    563     if (!pSession->prepare())
    564     {
    565         /* Destroy session UI otherwise: */
    566         destroy(pSession);
    567         /* False in that case: */
     160UIPasswordEditor::UIPasswordEditor(QWidget *pParent)
     161    : QLineEdit(pParent)
     162{
     163    /* Prepare: */
     164    prepare();
     165}
     166
     167void UIPasswordEditor::sltPasswordChanged(const QString &strPassword)
     168{
     169    Q_UNUSED(strPassword);
     170    /* Commit data to the listener: */
     171    emit sigCommitData(this);
     172}
     173
     174void UIPasswordEditor::prepare()
     175{
     176    /* Set alignment: */
     177    setAlignment(Qt::AlignCenter);
     178    /* Set echo mode: */
     179    setEchoMode(QLineEdit::Password);
     180    /* Listen for the text changes: */
     181    connect(this, SIGNAL(textChanged(const QString&)),
     182            this, SLOT(sltPasswordChanged(const QString&)));
     183}
     184
     185UIEncryptionDataModel::UIEncryptionDataModel(QObject *pParent, const EncryptedMediumsMap &encryptedMediums)
     186    : QAbstractTableModel(pParent)
     187    , m_encryptedMediums(encryptedMediums)
     188{
     189    /* Prepare: */
     190    prepare();
     191}
     192
     193int UIEncryptionDataModel::rowCount(const QModelIndex &parent /* = QModelIndex() */) const
     194{
     195    Q_UNUSED(parent);
     196    return m_encryptionPasswords.size();
     197}
     198
     199int UIEncryptionDataModel::columnCount(const QModelIndex &parent /* = QModelIndex() */) const
     200{
     201    Q_UNUSED(parent);
     202    return UIEncryptionDataTableSection_Max;
     203}
     204
     205Qt::ItemFlags UIEncryptionDataModel::flags(const QModelIndex &index) const
     206{
     207    /* Check index validness: */
     208    if (!index.isValid())
     209        return Qt::NoItemFlags;
     210    /* Depending on column index: */
     211    switch (index.column())
     212    {
     213        case UIEncryptionDataTableSection_Id:       return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
     214        case UIEncryptionDataTableSection_Password: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
     215        default: break;
     216    }
     217    /* No flags by default: */
     218    return Qt::NoItemFlags;
     219}
     220
     221QVariant UIEncryptionDataModel::headerData(int iSection, Qt::Orientation orientation, int iRole) const
     222{
     223    /* Check argument validness: */
     224    if (iRole != Qt::DisplayRole || orientation != Qt::Horizontal)
     225        return QVariant();
     226    /* Depending on column index: */
     227    switch (iSection)
     228    {
     229        case UIEncryptionDataTableSection_Id:       return tr("Password ID");
     230        case UIEncryptionDataTableSection_Password: return tr("Password");
     231        default: break;
     232    }
     233    /* Null value by default: */
     234    return QVariant();
     235}
     236
     237QVariant UIEncryptionDataModel::data(const QModelIndex &index, int iRole /* = Qt::DisplayRole */) const
     238{
     239    /* Check index validness: */
     240    if (!index.isValid())
     241        return QVariant();
     242    /* Depending on role: */
     243    switch (iRole)
     244    {
     245        case Qt::DisplayRole:
     246        {
     247            /* Depending on column index: */
     248            switch (index.column())
     249            {
     250                case UIEncryptionDataTableSection_Id:
     251                    return m_encryptionPasswords.keys().at(index.row());
     252                case UIEncryptionDataTableSection_Password:
     253                    return QString().fill('*', m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row())).size());
     254                default:
     255                    return QVariant();
     256            }
     257            break;
     258        }
     259        case Qt::EditRole:
     260        {
     261            /* Depending on column index: */
     262            switch (index.column())
     263            {
     264                case UIEncryptionDataTableSection_Password:
     265                    return m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row()));
     266                default:
     267                    return QVariant();
     268            }
     269            break;
     270        }
     271        case Qt::TextAlignmentRole:
     272        {
     273            /* Depending on column index: */
     274            switch (index.column())
     275            {
     276                case UIEncryptionDataTableSection_Password:
     277                    return Qt::AlignCenter;
     278                default: return QVariant();
     279            }
     280            break;
     281        }
     282        default:
     283            break;
     284    }
     285    /* Null value by default: */
     286    return QVariant();
     287}
     288
     289bool UIEncryptionDataModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole */)
     290{
     291    /* Check index validness: */
     292    if (!index.isValid())
    568293        return false;
    569     }
    570     /* True by default: */
    571     return true;
    572 }
    573 
    574 /* static */
    575 void UISession::destroy(UISession *&pSession)
    576 {
    577     /* Make sure valid pointer passed: */
    578     AssertReturnVoid(pSession != 0);
    579 
    580     /* Cleanup session UI: */
    581     pSession->cleanup();
    582     /* Destroy session: */
    583     delete pSession;
    584     pSession = 0;
    585 }
    586 
    587 bool UISession::initialize()
    588 {
    589     /* Preprocess initialization: */
    590     if (!preprocessInitialization())
     294    /* Check argument validness: */
     295    if (iRole != Qt::EditRole)
    591296        return false;
    592 
    593     /* Notify user about mouse&keyboard auto-capturing: */
    594     if (vboxGlobal().settings().autoCapture())
    595         popupCenter().remindAboutAutoCapture(machineLogic()->activeMachineWindow());
    596 
    597     /* Check if we are in teleportation waiting mode.
    598      * In that case no first run wizard is necessary. */
    599     m_machineState = machine().GetState();
    600     if (   isFirstTimeStarted()
    601         && !((   m_machineState == KMachineState_PoweredOff
    602               || m_machineState == KMachineState_Aborted
    603               || m_machineState == KMachineState_Teleported)
    604              && machine().GetTeleporterEnabled()))
    605     {
    606         UISafePointerWizard pWizard = new UIWizardFirstRun(mainMachineWindow(), machine());
    607         pWizard->prepare();
    608         pWizard->exec();
    609         if (pWizard)
    610             delete pWizard;
    611     }
    612 
    613     /* Apply debug settings from the command line. */
    614     if (!debugger().isNull() && debugger().isOk())
    615     {
    616         if (vboxGlobal().isPatmDisabled())
    617             debugger().SetPATMEnabled(false);
    618         if (vboxGlobal().isCsamDisabled())
    619             debugger().SetCSAMEnabled(false);
    620         if (vboxGlobal().isSupervisorCodeExecedRecompiled())
    621             debugger().SetRecompileSupervisor(true);
    622         if (vboxGlobal().isUserCodeExecedRecompiled())
    623             debugger().SetRecompileUser(true);
    624         if (vboxGlobal().areWeToExecuteAllInIem())
    625             debugger().SetExecuteAllInIEM(true);
    626         if (!vboxGlobal().isDefaultWarpPct())
    627             debugger().SetVirtualTimeRate(vboxGlobal().getWarpPct());
    628     }
    629 
    630     /* Power UP if this is NOT separate process: */
    631     if (!vboxGlobal().isSeparateProcess())
    632         if (!powerUp())
    633             return false;
    634 
    635     /* Check if we missed a really quick termination after successful startup: */
    636     if (isTurnedOff())
    637         return false;
    638 
    639     /* Postprocess initialization: */
    640     if (!postprocessInitialization())
    641         return false;
    642 
    643     /* Fetch corresponding states: */
    644     if (vboxGlobal().isSeparateProcess())
    645     {
    646         m_fIsMouseSupportsAbsolute = mouse().GetAbsoluteSupported();
    647         m_fIsMouseSupportsRelative = mouse().GetRelativeSupported();
    648         m_fIsMouseSupportsMultiTouch = mouse().GetMultiTouchSupported();
    649         m_fIsMouseHostCursorNeeded = mouse().GetNeedsHostCursor();
    650         sltAdditionsChange();
    651     }
    652     machineLogic()->initializePostPowerUp();
    653 
    654 #ifdef VBOX_WITH_VIDEOHWACCEL
    655     /* Log whether 2D video acceleration is enabled: */
    656     LogRel(("2D video acceleration is %s.\n",
    657            machine().GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()
    658            ? "enabled" : "disabled"));
    659 #endif /* VBOX_WITH_VIDEOHWACCEL */
    660 
    661 /* Log whether HID LEDs sync is enabled: */
    662 #if defined(Q_WS_MAC) || defined(Q_WS_WIN)
    663     LogRel(("HID LEDs sync is %s.\n",
    664             uimachine()->machineLogic()->isHidLedsSyncEnabled()
    665             ? "enabled" : "disabled"));
    666 #else /* !Q_WS_MAC && !Q_WS_WIN */
    667     LogRel(("HID LEDs sync is not supported on this platform.\n"));
    668 #endif /* !Q_WS_MAC && !Q_WS_WIN */
    669 
    670 #ifdef VBOX_GUI_WITH_PIDFILE
    671     vboxGlobal().createPidfile();
    672 #endif /* VBOX_GUI_WITH_PIDFILE */
    673 
    674     /* Warn listeners about we are initialized: */
    675     emit sigInitialized();
    676 
    677     /* True by default: */
    678     return true;
    679 }
    680 
    681 bool UISession::powerUp()
    682 {
    683     /* Prepare map of the encrypted ids: */
    684     EncryptedMediumsMap encryptedPasswordIds;
    685     foreach (const CMediumAttachment &attachment, machine().GetMediumAttachments())
    686     {
    687         /* Acquire hard-drives only: */
    688         if (attachment.GetType() == KDeviceType_HardDisk)
    689         {
    690             /* Get attachment medium: */
    691             const CMedium medium = attachment.GetMedium();
    692             /* Append our map if this medium has encryption: */
    693             const QString strKeyId = medium.GetProperty("CRYPT/KeyId");
    694             if (!strKeyId.isNull())
    695                 encryptedPasswordIds.insert(strKeyId, medium.GetId());
    696         }
    697     }
    698     /* Ask for disk encryption passwords if necessary: */
    699     EncryptionPasswordsMap encryptionPasswords;
    700     if (!encryptedPasswordIds.isEmpty())
    701     {
    702         QPointer<UIAddDiskEncryptionPasswordDialog> pDlg =
    703              new UIAddDiskEncryptionPasswordDialog(machineLogic()->activeMachineWindow(),
    704                                                    encryptedPasswordIds);
    705         if (pDlg->exec() == QDialog::Accepted)
    706             encryptionPasswords = pDlg->encryptionPasswords();
    707         if (pDlg)
    708             delete pDlg;
    709     }
    710 
    711     /* Power UP machine: */
    712 #ifdef VBOX_WITH_DEBUGGER_GUI
    713     CProgress progress = vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled() ?
    714                          console().PowerUpPaused() : console().PowerUp();
    715 #else /* !VBOX_WITH_DEBUGGER_GUI */
    716     CProgress progress = console().PowerUp();
    717 #endif /* !VBOX_WITH_DEBUGGER_GUI */
    718 
    719     /* Check for immediate failure: */
    720     if (!console().isOk() || progress.isNull())
    721     {
    722         if (vboxGlobal().showStartVMErrors())
    723             msgCenter().cannotStartMachine(console(), machineName());
    724         return false;
    725     }
    726 
    727     /* Guard progressbar warnings from auto-closing: */
    728     if (uimachine()->machineLogic())
    729         uimachine()->machineLogic()->setPreventAutoClose(true);
    730 
    731     /* Show "Starting/Restoring" progress dialog: */
    732     if (isSaved())
    733     {
    734         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_state_restore_90px.png", 0, 0);
    735         /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
    736         machineLogic()->adjustMachineWindowsGeometry();
    737     }
    738     else
    739         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_start_90px.png");
    740 
    741     /* Check for progress failure: */
    742     if (!progress.isOk() || progress.GetResultCode() != 0)
    743     {
    744         if (vboxGlobal().showStartVMErrors())
    745             msgCenter().cannotStartMachine(progress, machineName());
    746         return false;
    747     }
    748 
    749     /* Add the disk encryption passwords: */
    750     if (!encryptionPasswords.isEmpty())
    751     {
    752         foreach (const QString &strKey, encryptionPasswords.keys())
    753         {
    754             console().AddDiskEncryptionPassword(strKey, encryptionPasswords.value(strKey), true);
    755             if (!console().isOk())
    756                 msgCenter().cannotAddDiskEncryptionPassword(console());
    757         }
    758     }
    759 
    760     /* Allow further auto-closing: */
    761     if (uimachine()->machineLogic())
    762         uimachine()->machineLogic()->setPreventAutoClose(false);
    763 
    764     /* True by default: */
    765     return true;
    766 }
    767 
    768 bool UISession::saveState()
    769 {
    770     /* Prepare the saving progress: */
    771     CProgress progress = console().SaveState();
    772     if (console().isOk())
    773     {
    774         /* Show the saving progress: */
    775         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_state_save_90px.png");
    776         if (!progress.isOk() || progress.GetResultCode() != 0)
    777         {
    778             /* Failed in progress: */
    779             msgCenter().cannotSaveMachineState(progress, machineName());
    780             return false;
    781         }
    782     }
    783     else
    784     {
    785         /* Failed in console: */
    786         msgCenter().cannotSaveMachineState(console());
    787         return false;
    788     }
    789     /* Passed: */
    790     return true;
    791 }
    792 
    793 bool UISession::shutdown()
    794 {
    795     /* Send ACPI shutdown signal if possible: */
    796     console().PowerButton();
    797     if (!console().isOk())
    798     {
    799         /* Failed in console: */
    800         msgCenter().cannotACPIShutdownMachine(console());
    801         return false;
    802     }
    803     /* Passed: */
    804     return true;
    805 }
    806 
    807 bool UISession::powerOff(bool fIncludingDiscard, bool &fServerCrashed)
    808 {
    809     /* Prepare the power-off progress: */
    810     CProgress progress = console().PowerDown();
    811     if (console().isOk())
    812     {
    813         /* Show the power-off progress: */
    814         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_poweroff_90px.png");
    815         if (progress.isOk() && progress.GetResultCode() == 0)
    816         {
    817             /* Discard the current state if requested: */
    818             if (fIncludingDiscard)
    819                 return restoreCurrentSnapshot();
    820         }
    821         else
    822         {
    823             /* Failed in progress: */
    824             msgCenter().cannotPowerDownMachine(progress, machineName());
    825             return false;
    826         }
    827     }
    828     else
    829     {
    830         /* Check the machine state, it might be already gone: */
    831         if (!console().isNull())
    832         {
    833            /* Failed in console: */
    834            COMResult res(console());
    835            /* This can happen if VBoxSVC is not running: */
    836            if (FAILED_DEAD_INTERFACE(res.rc()))
    837                fServerCrashed = true;
    838            else
    839                msgCenter().cannotPowerDownMachine(console());
    840            return false;
    841         }
    842     }
    843     /* Passed: */
    844     return true;
    845 }
    846 
    847 bool UISession::restoreCurrentSnapshot()
    848 {
    849     /* Prepare result: */
    850     bool fResult = false;
    851 
    852     /* Simulate try-catch block: */
    853     do
    854     {
    855         /* Search for corresponding VM: */
    856         CVirtualBox vbox = vboxGlobal().virtualBox();
    857         const QString strMachineID = vboxGlobal().managedVMUuid();
    858         const CMachine mach = vbox.FindMachine(strMachineID);
    859         if (!vbox.isOk() || mach.isNull())
    860         {
    861             /* Unable to find VM: */
    862             msgCenter().cannotFindMachineById(vbox, strMachineID);
    863             break;
    864         }
    865 
    866         /* Open a direct session to modify that VM: */
    867         CSession sess = vboxGlobal().openSession(vboxGlobal().managedVMUuid(),
    868                                                  vboxGlobal().isSeparateProcess()
    869                                                  ? KLockType_Write : KLockType_Shared);
    870         if (sess.isNull())
    871         {
    872             /* Unable to open session: */
    873             break;
    874         }
    875 
    876         /* Simulate try-catch block: */
    877         do
    878         {
    879             /* Acquire console for this session: */
    880             CConsole cons = sess.GetConsole();
    881             if (cons.isNull())
    882             {
    883                 /* Unable to acquire console: */
    884                 break;
    885             }
    886 
    887             /* Prepare the snapshot-discard progress: */
    888             const CSnapshot snap = mach.GetCurrentSnapshot();
    889             CProgress prog = cons.RestoreSnapshot(snap);
    890             if (!cons.isOk() || prog.isNull())
    891             {
    892                 /* Unable to restore snapshot: */
    893                 msgCenter().cannotRestoreSnapshot(cons, snap.GetName(), machineName());
    894                 break;
    895             }
    896 
    897             /* Show the snapshot-discard progress: */
    898             msgCenter().showModalProgressDialog(prog, mach.GetName(), ":/progress_snapshot_discard_90px.png");
    899             if (prog.GetResultCode() != 0)
    900             {
    901                 /* Unable to restore snapshot: */
    902                 msgCenter().cannotRestoreSnapshot(prog, snap.GetName(), mach.GetName());
    903                 break;
    904             }
    905 
    906             /* Success: */
    907             fResult = true;
    908         }
    909         while (0);
    910 
    911         /* Unlock machine finally: */
    912         sess.UnlockMachine();
    913     }
    914     while (0);
    915 
    916     /* Return result: */
    917     return fResult;
    918 }
    919 
    920 void UISession::closeRuntimeUI()
    921 {
    922     /* Start corresponding slot asynchronously: */
    923     emit sigCloseRuntimeUI();
    924 }
    925 
    926 UIMachineLogic* UISession::machineLogic() const
    927 {
    928     return uimachine() ? uimachine()->machineLogic() : 0;
    929 }
    930 
    931 QWidget* UISession::mainMachineWindow() const
    932 {
    933     return machineLogic() ? machineLogic()->mainMachineWindow() : 0;
    934 }
    935 
    936 bool UISession::isVisualStateAllowed(UIVisualStateType state) const
    937 {
    938     return m_pMachine->isVisualStateAllowed(state);
    939 }
    940 
    941 void UISession::changeVisualState(UIVisualStateType visualStateType)
    942 {
    943     m_pMachine->asyncChangeVisualState(visualStateType);
    944 }
    945 
    946 bool UISession::setPause(bool fOn)
    947 {
    948     if (fOn)
    949         console().Pause();
    950     else
    951         console().Resume();
    952 
    953     bool ok = console().isOk();
    954     if (!ok)
    955     {
    956         if (fOn)
    957             msgCenter().cannotPauseMachine(console());
    958         else
    959             msgCenter().cannotResumeMachine(console());
    960     }
    961 
    962     return ok;
    963 }
    964 
    965 void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
    966 {
    967     /* This flag indicates whether we want to do the usual .ISO mounting or not.
    968      * First try updating the Guest Additions directly without mounting the .ISO. */
    969     bool fDoMount = false;
    970 
    971     /* Auto-update in GUI currently is disabled. */
    972 #ifndef VBOX_WITH_ADDITIONS_AUTOUPDATE_UI
    973     fDoMount = true;
    974 #else /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
    975     QVector<KAdditionsUpdateFlag> aFlagsUpdate;
    976     QVector<QString> aArgs;
    977     CProgress progressInstall = guest().UpdateGuestAdditions(strSource,
    978                                                              aArgs, aFlagsUpdate);
    979     bool fResult = guest().isOk();
    980     if (fResult)
    981     {
    982         msgCenter().showModalProgressDialog(progressInstall, tr("Updating Guest Additions"),
    983                                             ":/progress_install_guest_additions_90px.png",
    984                                             0, 500 /* 500ms delay. */);
    985         if (progressInstall.GetCanceled())
    986             return;
    987 
    988         HRESULT rc = progressInstall.GetResultCode();
    989         if (!progressInstall.isOk() || rc != S_OK)
    990         {
    991             /* If we got back a VBOX_E_NOT_SUPPORTED we don't complain (guest OS
    992              * simply isn't supported yet), so silently fall back to "old" .ISO
    993              * mounting method. */
    994             if (   !SUCCEEDED_WARNING(rc)
    995                 && rc != VBOX_E_NOT_SUPPORTED)
    996             {
    997                 msgCenter().cannotUpdateGuestAdditions(progressInstall);
    998 
    999                 /* Log the error message in the release log. */
    1000                 QString strErr = progressInstall.GetErrorInfo().GetText();
    1001                 if (!strErr.isEmpty())
    1002                     LogRel(("%s\n", strErr.toLatin1().constData()));
    1003             }
    1004             fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
    1005         }
    1006     }
    1007 #endif /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
    1008 
    1009     /* Do we still want mounting? */
    1010     if (!fDoMount)
    1011         return;
    1012 
    1013     /* Open corresponding medium: */
    1014     QString strMediumID;
    1015     CVirtualBox vbox = vboxGlobal().virtualBox();
    1016     CMedium image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
    1017     if (vbox.isOk() && !image.isNull())
    1018         strMediumID = image.GetId();
    1019     else
    1020     {
    1021         msgCenter().cannotOpenMedium(vbox, UIMediumType_DVD, strSource, mainMachineWindow());
    1022         return;
    1023     }
    1024 
    1025     /* Make sure GA medium ID is valid: */
    1026     AssertReturnVoid(!strMediumID.isNull());
    1027 
    1028     /* Searching for the first suitable controller/slot: */
    1029     QString strControllerName;
    1030     LONG iCntPort = -1, iCntDevice = -1;
    1031     foreach (const CStorageController &controller, machine().GetStorageControllers())
    1032     {
    1033         foreach (const CMediumAttachment &attachment, machine().GetMediumAttachmentsOfController(controller.GetName()))
    1034         {
    1035             if (attachment.GetType() == KDeviceType_DVD)
    1036             {
    1037                 strControllerName = controller.GetName();
    1038                 iCntPort = attachment.GetPort();
    1039                 iCntDevice = attachment.GetDevice();
    1040                 break;
    1041             }
    1042         }
    1043         if (!strControllerName.isNull())
    1044             break;
    1045     }
    1046 
    1047     /* Make sure suitable controller/slot were found: */
    1048     if (strControllerName.isNull())
    1049     {
    1050         msgCenter().cannotMountGuestAdditions(machineName());
    1051         return;
    1052     }
    1053 
    1054     /* Try to find UIMedium among cached: */
    1055     UIMedium medium = vboxGlobal().medium(strMediumID);
    1056     if (medium.isNull())
    1057     {
    1058         /* Create new one if necessary: */
    1059         medium = UIMedium(image, UIMediumType_DVD, KMediumState_Created);
    1060         vboxGlobal().createMedium(medium);
    1061     }
    1062 
    1063     /* Mount medium to corresponding controller/slot: */
    1064     machine().MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), false /* force */);
    1065     if (!machine().isOk())
    1066     {
    1067         /* Ask for force mounting: */
    1068         if (msgCenter().cannotRemountMedium(machine(), medium, true /* mount? */,
    1069                                             true /* retry? */, mainMachineWindow()))
    1070         {
    1071             /* Force mount medium to the predefined port/device: */
    1072             machine().MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), true /* force */);
    1073             if (!machine().isOk())
    1074                 msgCenter().cannotRemountMedium(machine(), medium, true /* mount? */,
    1075                                                 false /* retry? */, mainMachineWindow());
    1076         }
    1077     }
    1078 }
    1079 
    1080 void UISession::sltCloseRuntimeUI()
    1081 {
    1082     /* First, we have to hide any opened modal/popup widgets.
    1083      * They then should unlock their event-loops synchronously.
    1084      * If all such loops are unlocked, we can close Runtime UI: */
    1085     if (QWidget *pWidget = QApplication::activeModalWidget() ?
    1086                            QApplication::activeModalWidget() :
    1087                            QApplication::activePopupWidget() ?
    1088                            QApplication::activePopupWidget() : 0)
    1089     {
    1090         /* First we should try to close this widget: */
    1091         pWidget->close();
    1092         /* If widget rejected the 'close-event' we can
    1093          * still hide it and hope it will behave correctly
    1094          * and unlock his event-loop if any: */
    1095         if (!pWidget->isHidden())
    1096             pWidget->hide();
    1097         /* Restart this slot: */
    1098         emit sigCloseRuntimeUI();
    1099         return;
    1100     }
    1101 
    1102     /* Finally close the Runtime UI: */
    1103     UIMachine::destroy();
    1104 }
    1105 
    1106 #ifdef RT_OS_DARWIN
    1107 void UISession::sltHandleMenuBarConfigurationChange(const QString &strMachineID)
    1108 {
    1109     /* Skip unrelated machine IDs: */
    1110     if (vboxGlobal().managedVMUuid() != strMachineID)
    1111         return;
    1112 
    1113     /* Update Mac OS X menu-bar: */
    1114     updateMenu();
    1115 }
    1116 #endif /* RT_OS_DARWIN */
    1117 
    1118 void UISession::sltMousePointerShapeChange(bool fVisible, bool fAlpha, QPoint hotCorner, QSize size, QVector<uint8_t> shape)
    1119 {
    1120     /* In case of shape data is present: */
    1121     if (shape.size() > 0)
    1122     {
    1123         /* We are ignoring visibility flag: */
    1124         m_fIsHidingHostPointer = false;
    1125 
    1126         /* And updating current cursor shape: */
    1127         setPointerShape(shape.data(), fAlpha,
    1128                         hotCorner.x(), hotCorner.y(),
    1129                         size.width(), size.height());
    1130     }
    1131     /* In case of shape data is NOT present: */
    1132     else
    1133     {
    1134         /* Remember if we should hide the cursor: */
    1135         m_fIsHidingHostPointer = !fVisible;
    1136     }
    1137 
    1138     /* Notify listeners about mouse capability changed: */
    1139     emit sigMousePointerShapeChange();
    1140 
    1141 }
    1142 
    1143 void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative, bool fSupportsMultiTouch, bool fNeedsHostCursor)
    1144 {
    1145     LogRelFlow(("UISession::sltMouseCapabilityChange: "
    1146                 "Supports absolute: %s, Supports relative: %s, "
    1147                 "Supports multi-touch: %s, Needs host cursor: %s\n",
    1148                 fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
    1149                 fSupportsMultiTouch ? "TRUE" : "FALSE", fNeedsHostCursor ? "TRUE" : "FALSE"));
    1150 
    1151     /* Check if something had changed: */
    1152     if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
    1153         || m_fIsMouseSupportsRelative != fSupportsRelative
    1154         || m_fIsMouseSupportsMultiTouch != fSupportsMultiTouch
    1155         || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
    1156     {
    1157         /* Store new data: */
    1158         m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
    1159         m_fIsMouseSupportsRelative = fSupportsRelative;
    1160         m_fIsMouseSupportsMultiTouch = fSupportsMultiTouch;
    1161         m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
    1162 
    1163         /* Notify listeners about mouse capability changed: */
    1164         emit sigMouseCapabilityChange();
    1165     }
    1166 }
    1167 
    1168 void UISession::sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
    1169 {
    1170     /* Check if something had changed: */
    1171     if (   m_fNumLock != fNumLock
    1172         || m_fCapsLock != fCapsLock
    1173         || m_fScrollLock != fScrollLock)
    1174     {
    1175         /* Store new num lock data: */
    1176         if (m_fNumLock != fNumLock)
    1177         {
    1178             m_fNumLock = fNumLock;
    1179             m_uNumLockAdaptionCnt = 2;
    1180         }
    1181 
    1182         /* Store new caps lock data: */
    1183         if (m_fCapsLock != fCapsLock)
    1184         {
    1185             m_fCapsLock = fCapsLock;
    1186             m_uCapsLockAdaptionCnt = 2;
    1187         }
    1188 
    1189         /* Store new scroll lock data: */
    1190         if (m_fScrollLock != fScrollLock)
    1191         {
    1192             m_fScrollLock = fScrollLock;
    1193         }
    1194 
    1195         /* Notify listeners about mouse capability changed: */
    1196         emit sigKeyboardLedsChange();
    1197     }
    1198 }
    1199 
    1200 void UISession::sltStateChange(KMachineState state)
    1201 {
    1202     /* Check if something had changed: */
    1203     if (m_machineState != state)
    1204     {
    1205         /* Store new data: */
    1206         m_machineStatePrevious = m_machineState;
    1207         m_machineState = state;
    1208 
    1209         /* Notify listeners about machine state changed: */
    1210         emit sigMachineStateChange();
    1211     }
    1212 }
    1213 
    1214 void UISession::sltVRDEChange()
    1215 {
    1216     /* Make sure VRDE server is present: */
    1217     const CVRDEServer server = machine().GetVRDEServer();
    1218     AssertMsgReturnVoid(machine().isOk() && !server.isNull(),
    1219                         ("VRDE server should NOT be null!\n"));
    1220 
    1221     /* Check/Uncheck VRDE Server action depending on feature status: */
    1222     actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->blockSignals(true);
    1223     actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->setChecked(server.GetEnabled());
    1224     actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->blockSignals(false);
    1225 
    1226     /* Notify listeners about VRDE change: */
    1227     emit sigVRDEChange();
    1228 }
    1229 
    1230 void UISession::sltVideoCaptureChange()
    1231 {
    1232     /* Check/Uncheck Video Capture action depending on feature status: */
    1233     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->blockSignals(true);
    1234     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->setChecked(machine().GetVideoCaptureEnabled());
    1235     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->blockSignals(false);
    1236 
    1237     /* Notify listeners about Video Capture change: */
    1238     emit sigVideoCaptureChange();
    1239 }
    1240 
    1241 void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
    1242 {
    1243     /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
    1244     if (changeType == KGuestMonitorChangedEventType_NewOrigin)
    1245         return;
    1246     /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
    1247     AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
    1248     if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
    1249         return;
    1250 
    1251     /* Process KGuestMonitorChangedEventType_Enabled change event: */
    1252     if (   !isScreenVisible(uScreenId)
    1253         && changeType == KGuestMonitorChangedEventType_Enabled)
    1254         setScreenVisible(uScreenId, true);
    1255     /* Process KGuestMonitorChangedEventType_Disabled change event: */
    1256     else if (   isScreenVisible(uScreenId)
    1257              && changeType == KGuestMonitorChangedEventType_Disabled)
    1258         setScreenVisible(uScreenId, false);
    1259 
    1260     /* Notify listeners about the change: */
    1261     emit sigGuestMonitorChange(changeType, uScreenId, screenGeo);
    1262 }
    1263 
    1264 #ifdef RT_OS_DARWIN
    1265 /**
    1266  * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
    1267  * @note Watchdog is trying to determine display reconfiguration in
    1268  *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
    1269  */
    1270 void UISession::sltHandleHostDisplayAboutToChange()
    1271 {
    1272     LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
    1273 
    1274     if (m_pWatchdogDisplayChange->isActive())
    1275         m_pWatchdogDisplayChange->stop();
    1276     m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
    1277     m_pWatchdogDisplayChange->start();
    1278 }
    1279 
    1280 /**
    1281  * MacOS X: Determines display reconfiguration.
    1282  * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
    1283  * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
    1284  */
    1285 void UISession::sltCheckIfHostDisplayChanged()
    1286 {
    1287     LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
    1288 
    1289     /* Acquire desktop wrapper: */
    1290     QDesktopWidget *pDesktop = QApplication::desktop();
    1291 
    1292     /* Check if display count changed: */
    1293     if (pDesktop->screenCount() != m_hostScreens.size())
    1294     {
    1295         /* Reset watchdog: */
    1296         m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    1297         /* Notify listeners about screen-count changed: */
    1298         return sltHandleHostScreenCountChange();
    1299     }
    1300     else
    1301     {
    1302         /* Check if at least one display geometry changed: */
    1303         for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
    1304         {
    1305             if (pDesktop->screenGeometry(iScreenIndex) != m_hostScreens.at(iScreenIndex))
    1306             {
    1307                 /* Reset watchdog: */
    1308                 m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    1309                 /* Notify listeners about screen-geometry changed: */
    1310                 return sltHandleHostScreenGeometryChange();
    1311             }
    1312         }
    1313     }
    1314 
    1315     /* Check if watchdog expired, restart if not: */
    1316     int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
    1317     if (cTryNumber > 0 && cTryNumber < 40)
    1318     {
    1319         /* Restart watchdog again: */
    1320         m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
    1321         m_pWatchdogDisplayChange->start();
    1322     }
    1323     else
    1324     {
    1325         /* Reset watchdog: */
    1326         m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    1327     }
    1328 }
    1329 #endif /* RT_OS_DARWIN */
    1330 
    1331 void UISession::sltHandleHostScreenCountChange()
    1332 {
    1333     LogRelFlow(("UISession: Host-screen count changed.\n"));
    1334 
    1335     /* Recache display data: */
    1336     updateHostScreenData();
    1337 
    1338     /* Notify current machine-logic: */
    1339     emit sigHostScreenCountChange();
    1340 }
    1341 
    1342 void UISession::sltHandleHostScreenGeometryChange()
    1343 {
    1344     LogRelFlow(("UISession: Host-screen geometry changed.\n"));
    1345 
    1346     /* Recache display data: */
    1347     updateHostScreenData();
    1348 
    1349     /* Notify current machine-logic: */
    1350     emit sigHostScreenGeometryChange();
    1351 }
    1352 
    1353 void UISession::sltHandleHostScreenAvailableAreaChange()
    1354 {
    1355     LogRelFlow(("UISession: Host-screen available-area changed.\n"));
    1356 
    1357     /* Notify current machine-logic: */
    1358     emit sigHostScreenAvailableAreaChange();
    1359 }
    1360 
    1361 void UISession::sltAdditionsChange()
    1362 {
    1363     /* Variable flags: */
    1364     ULONG ulGuestAdditionsRunLevel = guest().GetAdditionsRunLevel();
    1365     LONG64 lLastUpdatedIgnored;
    1366     bool fIsGuestSupportsGraphics = guest().GetFacilityStatus(KAdditionsFacilityType_Graphics, lLastUpdatedIgnored)
    1367                                     == KAdditionsFacilityStatus_Active;
    1368     bool fIsGuestSupportsSeamless = guest().GetFacilityStatus(KAdditionsFacilityType_Seamless, lLastUpdatedIgnored)
    1369                                     == KAdditionsFacilityStatus_Active;
    1370     /* Check if something had changed: */
    1371     if (m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel ||
    1372         m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
    1373         m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
    1374     {
    1375         /* Store new data: */
    1376         m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
    1377         m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
    1378         m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
    1379 
    1380         /* Notify listeners about guest additions state really changed: */
    1381         emit sigAdditionsStateActualChange();
    1382     }
    1383 
    1384     /* Notify listeners about guest additions state event came: */
    1385     emit sigAdditionsStateChange();
    1386 }
    1387 
    1388 UISession::UISession(UIMachine *pMachine)
    1389     : QObject(pMachine)
    1390     /* Base variables: */
    1391     , m_pMachine(pMachine)
    1392     , m_pActionPool(0)
    1393 #ifdef Q_WS_MAC
    1394     , m_pMenuBar(0)
    1395 #endif /* Q_WS_MAC */
    1396     /* Common variables: */
    1397     , m_machineStatePrevious(KMachineState_Null)
    1398     , m_machineState(KMachineState_Null)
    1399 #ifndef Q_WS_MAC
    1400     , m_pMachineWindowIcon(0)
    1401 #endif /* !Q_WS_MAC */
    1402     , m_mouseCapturePolicy(MouseCapturePolicy_Default)
    1403     , m_guruMeditationHandlerType(GuruMeditationHandlerType_Default)
    1404     , m_hiDPIOptimizationType(HiDPIOptimizationType_None)
    1405     , m_requestedVisualStateType(UIVisualStateType_Invalid)
    1406 #ifdef Q_WS_WIN
    1407     , m_alphaCursor(0)
    1408 #endif /* Q_WS_WIN */
    1409 #ifdef Q_WS_MAC
    1410     , m_pWatchdogDisplayChange(0)
    1411 #endif /* Q_WS_MAC */
    1412     , m_defaultCloseAction(MachineCloseAction_Invalid)
    1413     , m_restrictedCloseActions(MachineCloseAction_Invalid)
    1414     , m_fAllCloseActionsRestricted(false)
    1415     /* Common flags: */
    1416     , m_fInitialized(false)
    1417     , m_fIsFirstTimeStarted(false)
    1418     , m_fIsGuestResizeIgnored(false)
    1419     , m_fIsAutoCaptureDisabled(false)
    1420     /* Guest additions flags: */
    1421     , m_ulGuestAdditionsRunLevel(0)
    1422     , m_fIsGuestSupportsGraphics(false)
    1423     , m_fIsGuestSupportsSeamless(false)
    1424     /* Mouse flags: */
    1425     , m_fNumLock(false)
    1426     , m_fCapsLock(false)
    1427     , m_fScrollLock(false)
    1428     , m_uNumLockAdaptionCnt(2)
    1429     , m_uCapsLockAdaptionCnt(2)
    1430     /* Mouse flags: */
    1431     , m_fIsMouseSupportsAbsolute(false)
    1432     , m_fIsMouseSupportsRelative(false)
    1433     , m_fIsMouseSupportsMultiTouch(false)
    1434     , m_fIsMouseHostCursorNeeded(false)
    1435     , m_fIsMouseCaptured(false)
    1436     , m_fIsMouseIntegrated(true)
    1437     , m_fIsValidPointerShapePresent(false)
    1438     , m_fIsHidingHostPointer(true)
    1439 {
    1440 }
    1441 
    1442 UISession::~UISession()
    1443 {
    1444 }
    1445 
    1446 bool UISession::prepare()
    1447 {
    1448     /* Prepare session: */
    1449     if (!prepareSession())
    1450         return false;
    1451 
    1452     /* Prepare actions: */
    1453     prepareActions();
    1454 
    1455     /* Prepare connections: */
    1456     prepareConnections();
    1457 
    1458     /* Prepare console event-handlers: */
    1459     prepareConsoleEventHandlers();
    1460 
    1461     /* Prepare screens: */
    1462     prepareScreens();
    1463 
    1464     /* Prepare framebuffers: */
    1465     prepareFramebuffers();
    1466 
    1467     /* Load settings: */
    1468     loadSessionSettings();
    1469 
    1470 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    1471     struct sigaction sa;
    1472     sa.sa_sigaction = &signalHandlerSIGUSR1;
    1473     sigemptyset(&sa.sa_mask);
    1474     sa.sa_flags = SA_RESTART | SA_SIGINFO;
    1475     sigaction(SIGUSR1, &sa, NULL);
    1476 #endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    1477 
    1478     /* True by default: */
    1479     return true;
    1480 }
    1481 
    1482 bool UISession::prepareSession()
    1483 {
    1484     /* Open session: */
    1485     m_session = vboxGlobal().openSession(vboxGlobal().managedVMUuid(),
    1486                                          vboxGlobal().isSeparateProcess()
    1487                                          ? KLockType_Shared : KLockType_VM);
    1488     if (m_session.isNull())
    1489         return false;
    1490 
    1491     /* Get machine: */
    1492     m_machine = m_session.GetMachine();
    1493     if (m_machine.isNull())
    1494         return false;
    1495 
    1496     /* Get console: */
    1497     m_console = m_session.GetConsole();
    1498     if (m_console.isNull())
    1499         return false;
    1500 
    1501     /* Get display: */
    1502     m_display = m_console.GetDisplay();
    1503     if (m_display.isNull())
    1504         return false;
    1505 
    1506     /* Get guest: */
    1507     m_guest = m_console.GetGuest();
    1508     if (m_guest.isNull())
    1509         return false;
    1510 
    1511     /* Get mouse: */
    1512     m_mouse = m_console.GetMouse();
    1513     if (m_mouse.isNull())
    1514         return false;
    1515 
    1516     /* Get keyboard: */
    1517     m_keyboard = m_console.GetKeyboard();
    1518     if (m_keyboard.isNull())
    1519         return false;
    1520 
    1521     /* Get debugger: */
    1522     m_debugger = m_console.GetDebugger();
    1523     if (m_debugger.isNull())
    1524         return false;
    1525 
    1526     /* Update machine-name: */
    1527     m_strMachineName = machine().GetName();
    1528 
    1529     /* Update machine-state: */
    1530     m_machineState = machine().GetState();
    1531 
    1532     /* True by default: */
    1533     return true;
    1534 }
    1535 
    1536 void UISession::prepareActions()
    1537 {
    1538     /* Create action-pool: */
    1539     m_pActionPool = UIActionPool::create(UIActionPoolType_Runtime);
    1540     AssertPtrReturnVoid(actionPool());
    1541     {
    1542         /* Configure action-pool: */
    1543         actionPool()->toRuntime()->setSession(this);
    1544 
    1545         /* Get host: */
    1546         const CHost host = vboxGlobal().host();
    1547         UIExtraDataMetaDefs::RuntimeMenuViewActionType restrictionForView = UIExtraDataMetaDefs::RuntimeMenuViewActionType_Invalid;
    1548         UIExtraDataMetaDefs::RuntimeMenuDevicesActionType restrictionForDevices = UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Invalid;
    1549 
    1550         /* VRDE server stuff: */
    1551         {
    1552             /* Initialize 'View' menu: */
    1553             const CVRDEServer server = machine().GetVRDEServer();
    1554             if (server.isNull())
    1555                 restrictionForView = (UIExtraDataMetaDefs::RuntimeMenuViewActionType)(restrictionForView | UIExtraDataMetaDefs::RuntimeMenuViewActionType_VRDEServer);
    1556         }
    1557 
    1558         /* Storage stuff: */
    1559         {
    1560             /* Initialize CD/FD menus: */
    1561             int iDevicesCountCD = 0;
    1562             int iDevicesCountFD = 0;
    1563             foreach (const CMediumAttachment &attachment, machine().GetMediumAttachments())
    1564             {
    1565                 if (attachment.GetType() == KDeviceType_DVD)
    1566                     ++iDevicesCountCD;
    1567                 if (attachment.GetType() == KDeviceType_Floppy)
    1568                     ++iDevicesCountFD;
    1569             }
    1570             QAction *pOpticalDevicesMenu = actionPool()->action(UIActionIndexRT_M_Devices_M_OpticalDevices);
    1571             QAction *pFloppyDevicesMenu = actionPool()->action(UIActionIndexRT_M_Devices_M_FloppyDevices);
    1572             pOpticalDevicesMenu->setData(iDevicesCountCD);
    1573             pFloppyDevicesMenu->setData(iDevicesCountFD);
    1574             if (!iDevicesCountCD)
    1575                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_OpticalDevices);
    1576             if (!iDevicesCountFD)
    1577                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_FloppyDevices);
    1578         }
    1579 
    1580         /* Network stuff: */
    1581         {
    1582             /* Initialize Network menu: */
    1583             bool fAtLeastOneAdapterActive = false;
    1584             const KChipsetType chipsetType = machine().GetChipsetType();
    1585             ULONG uSlots = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(chipsetType);
    1586             for (ULONG uSlot = 0; uSlot < uSlots; ++uSlot)
    1587             {
    1588                 const CNetworkAdapter &adapter = machine().GetNetworkAdapter(uSlot);
    1589                 if (adapter.GetEnabled())
    1590                 {
    1591                     fAtLeastOneAdapterActive = true;
    1592                     break;
    1593                 }
    1594             }
    1595             if (!fAtLeastOneAdapterActive)
    1596                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Network);
    1597         }
    1598 
    1599         /* USB stuff: */
    1600         {
    1601             /* Check whether there is at least one USB controller with an available proxy. */
    1602             const bool fUSBEnabled =    !machine().GetUSBDeviceFilters().isNull()
    1603                                      && !machine().GetUSBControllers().isEmpty()
    1604                                      && machine().GetUSBProxyAvailable();
    1605             if (!fUSBEnabled)
    1606                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_USBDevices);
    1607         }
    1608 
    1609         /* WebCams stuff: */
    1610         {
    1611             /* Check whether there is an accessible video input devices pool: */
    1612             host.GetVideoInputDevices();
    1613             const bool fWebCamsEnabled = host.isOk() && !machine().GetUSBControllers().isEmpty();
    1614             if (!fWebCamsEnabled)
    1615                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_WebCams);
    1616         }
    1617 
    1618         /* Apply cumulative restriction for 'View' menu: */
    1619         actionPool()->toRuntime()->setRestrictionForMenuView(UIActionRestrictionLevel_Session, restrictionForView);
    1620         /* Apply cumulative restriction for 'Devices' menu: */
    1621         actionPool()->toRuntime()->setRestrictionForMenuDevices(UIActionRestrictionLevel_Session, restrictionForDevices);
    1622 
    1623 #ifdef Q_WS_MAC
    1624         /* Create Mac OS X menu-bar: */
    1625         m_pMenuBar = new UIMenuBar;
    1626         AssertPtrReturnVoid(m_pMenuBar);
    1627         {
    1628             /* Configure Mac OS X menu-bar: */
    1629             connect(gEDataManager, SIGNAL(sigMenuBarConfigurationChange(const QString&)),
    1630                     this, SLOT(sltHandleMenuBarConfigurationChange(const QString&)));
    1631             /* Update Mac OS X menu-bar: */
    1632             updateMenu();
    1633         }
    1634 #endif /* Q_WS_MAC */
    1635     }
    1636 }
    1637 
    1638 void UISession::prepareConnections()
    1639 {
    1640     connect(this, SIGNAL(sigInitialized()), this, SLOT(sltMarkInitialized()));
    1641     connect(this, SIGNAL(sigCloseRuntimeUI()), this, SLOT(sltCloseRuntimeUI()));
    1642 
    1643 #ifdef Q_WS_MAC
    1644     /* Install native display reconfiguration callback: */
    1645     CGDisplayRegisterReconfigurationCallback(cgDisplayReconfigurationCallback, this);
    1646 #else /* !Q_WS_MAC */
    1647     /* Install Qt display reconfiguration callbacks: */
    1648     connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)),
    1649             this, SLOT(sltHandleHostScreenCountChange()));
    1650     connect(QApplication::desktop(), SIGNAL(resized(int)),
    1651             this, SLOT(sltHandleHostScreenGeometryChange()));
    1652     connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
    1653             this, SLOT(sltHandleHostScreenAvailableAreaChange()));
    1654 #endif /* !Q_WS_MAC */
    1655 }
    1656 
    1657 void UISession::prepareConsoleEventHandlers()
    1658 {
    1659     /* Create console event-handler: */
    1660     UIConsoleEventHandler::create(this);
    1661 
    1662     /* Add console event connections: */
    1663     connect(gConsoleEvents, SIGNAL(sigMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)),
    1664             this, SLOT(sltMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)));
    1665 
    1666     connect(gConsoleEvents, SIGNAL(sigMouseCapabilityChange(bool, bool, bool, bool)),
    1667             this, SLOT(sltMouseCapabilityChange(bool, bool, bool, bool)));
    1668 
    1669     connect(gConsoleEvents, SIGNAL(sigKeyboardLedsChangeEvent(bool, bool, bool)),
    1670             this, SLOT(sltKeyboardLedsChangeEvent(bool, bool, bool)));
    1671 
    1672     connect(gConsoleEvents, SIGNAL(sigStateChange(KMachineState)),
    1673             this, SLOT(sltStateChange(KMachineState)));
    1674 
    1675     connect(gConsoleEvents, SIGNAL(sigAdditionsChange()),
    1676             this, SLOT(sltAdditionsChange()));
    1677 
    1678     connect(gConsoleEvents, SIGNAL(sigVRDEChange()),
    1679             this, SLOT(sltVRDEChange()));
    1680 
    1681     connect(gConsoleEvents, SIGNAL(sigVideoCaptureChange()),
    1682             this, SLOT(sltVideoCaptureChange()));
    1683 
    1684     connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
    1685             this, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)));
    1686 
    1687     connect(gConsoleEvents, SIGNAL(sigMediumChange(CMediumAttachment)),
    1688             this, SIGNAL(sigMediumChange(CMediumAttachment)));
    1689 
    1690     connect(gConsoleEvents, SIGNAL(sigUSBControllerChange()),
    1691             this, SIGNAL(sigUSBControllerChange()));
    1692 
    1693     connect(gConsoleEvents, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)),
    1694             this, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)));
    1695 
    1696     connect(gConsoleEvents, SIGNAL(sigSharedFolderChange()),
    1697             this, SIGNAL(sigSharedFolderChange()));
    1698 
    1699     connect(gConsoleEvents, SIGNAL(sigRuntimeError(bool, QString, QString)),
    1700             this, SIGNAL(sigRuntimeError(bool, QString, QString)));
    1701 
    1702 #ifdef Q_WS_MAC
    1703     connect(gConsoleEvents, SIGNAL(sigShowWindow()),
    1704             this, SIGNAL(sigShowWindows()), Qt::QueuedConnection);
    1705 #endif /* Q_WS_MAC */
    1706 
    1707     connect(gConsoleEvents, SIGNAL(sigCPUExecutionCapChange()),
    1708             this, SIGNAL(sigCPUExecutionCapChange()));
    1709 
    1710     connect(gConsoleEvents, SIGNAL(sigGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)),
    1711             this, SLOT(sltGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)));
    1712 }
    1713 
    1714 void UISession::prepareScreens()
    1715 {
    1716     /* Recache display data: */
    1717     updateHostScreenData();
    1718 
    1719 #ifdef Q_WS_MAC
    1720     /* Prepare display-change watchdog: */
    1721     m_pWatchdogDisplayChange = new QTimer(this);
    1722     {
    1723         m_pWatchdogDisplayChange->setInterval(500);
    1724         m_pWatchdogDisplayChange->setSingleShot(true);
    1725         connect(m_pWatchdogDisplayChange, SIGNAL(timeout()),
    1726                 this, SLOT(sltCheckIfHostDisplayChanged()));
    1727     }
    1728 #endif /* Q_WS_MAC */
    1729 
    1730     /* Prepare initial screen visibility status: */
    1731     m_monitorVisibilityVector.resize(machine().GetMonitorCount());
    1732     m_monitorVisibilityVector.fill(false);
    1733     m_monitorVisibilityVector[0] = true;
    1734 
    1735     /* If machine is in 'saved' state: */
    1736     if (isSaved())
    1737     {
    1738         /* Update screen visibility status from saved-state: */
    1739         for (int iScreenIndex = 0; iScreenIndex < m_monitorVisibilityVector.size(); ++iScreenIndex)
    1740         {
    1741             BOOL fEnabled = true;
    1742             ULONG uGuestOriginX = 0, uGuestOriginY = 0, uGuestWidth = 0, uGuestHeight = 0;
    1743             machine().QuerySavedGuestScreenInfo(iScreenIndex,
    1744                                                 uGuestOriginX, uGuestOriginY,
    1745                                                 uGuestWidth, uGuestHeight, fEnabled);
    1746             m_monitorVisibilityVector[iScreenIndex] = fEnabled;
    1747         }
    1748         /* And make sure at least one of them is visible (primary if others are hidden): */
    1749         if (countOfVisibleWindows() < 1)
    1750             m_monitorVisibilityVector[0] = true;
    1751     }
    1752     else if (vboxGlobal().isSeparateProcess())
    1753     {
    1754         /* Update screen visibility status from display directly: */
    1755         for (int iScreenIndex = 0; iScreenIndex < m_monitorVisibilityVector.size(); ++iScreenIndex)
    1756         {
    1757             KGuestMonitorStatus enmStatus = KGuestMonitorStatus_Disabled;
    1758             ULONG uGuestWidth = 0, uGuestHeight = 0, uBpp = 0;
    1759             LONG iGuestOriginX = 0, iGuestOriginY = 0;
    1760             display().GetScreenResolution(iScreenIndex,
    1761                                           uGuestWidth, uGuestHeight, uBpp,
    1762                                           iGuestOriginX, iGuestOriginY, enmStatus);
    1763             m_monitorVisibilityVector[iScreenIndex] = (enmStatus == KGuestMonitorStatus_Enabled);
    1764         }
    1765         /* And make sure at least one of them is visible (primary if others are hidden): */
    1766         if (countOfVisibleWindows() < 1)
    1767             m_monitorVisibilityVector[0] = true;
    1768     }
    1769 }
    1770 
    1771 void UISession::prepareFramebuffers()
    1772 {
    1773     /* Each framebuffer will be really prepared on first UIMachineView creation: */
    1774     m_frameBufferVector.resize(machine().GetMonitorCount());
    1775 }
    1776 
    1777 void UISession::loadSessionSettings()
    1778 {
    1779     /* Load extra-data settings: */
    1780     {
    1781         /* Get machine ID: */
    1782         const QString strMachineID = vboxGlobal().managedVMUuid();
    1783 
    1784 #ifndef Q_WS_MAC
    1785         /* Load/prepare user's machine-window icon: */
    1786         QIcon icon;
    1787         foreach (const QString &strIconName, gEDataManager->machineWindowIconNames(strMachineID))
    1788             if (!strIconName.isEmpty())
    1789                 icon.addFile(strIconName);
    1790         if (!icon.isNull())
    1791             m_pMachineWindowIcon = new QIcon(icon);
    1792 
    1793         /* Load user's machine-window name postfix: */
    1794         m_strMachineWindowNamePostfix = gEDataManager->machineWindowNamePostfix(strMachineID);
    1795 #endif /* !Q_WS_MAC */
    1796 
    1797         /* Determine mouse-capture policy: */
    1798         m_mouseCapturePolicy = gEDataManager->mouseCapturePolicy(strMachineID);
    1799 
    1800         /* Determine Guru Meditation handler type: */
    1801         m_guruMeditationHandlerType = gEDataManager->guruMeditationHandlerType(strMachineID);
    1802 
    1803         /* Determine HiDPI optimization type: */
    1804         m_hiDPIOptimizationType = gEDataManager->hiDPIOptimizationType(strMachineID);
    1805 
    1806         /* Is there should be First RUN Wizard? */
    1807         m_fIsFirstTimeStarted = gEDataManager->machineFirstTimeStarted(strMachineID);
    1808 
    1809         /* Should guest autoresize? */
    1810         QAction *pGuestAutoresizeSwitch = actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize);
    1811         pGuestAutoresizeSwitch->setChecked(gEDataManager->guestScreenAutoResizeEnabled(strMachineID));
    1812 
    1813 #ifndef Q_WS_MAC
    1814         /* Menu-bar options: */
    1815         {
    1816             const bool fEnabledGlobally = !vboxGlobal().settings().isFeatureActive("noMenuBar");
    1817             const bool fEnabledForMachine = gEDataManager->menuBarEnabled(strMachineID);
    1818             const bool fEnabled = fEnabledGlobally && fEnabledForMachine;
    1819             QAction *pActionMenuBarSettings = actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_S_Settings);
    1820             pActionMenuBarSettings->setEnabled(fEnabled);
    1821             QAction *pActionMenuBarSwitch = actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_T_Visibility);
    1822             pActionMenuBarSwitch->blockSignals(true);
    1823             pActionMenuBarSwitch->setChecked(fEnabled);
    1824             pActionMenuBarSwitch->blockSignals(false);
    1825         }
    1826 #endif /* !Q_WS_MAC */
    1827 
    1828         /* Status-bar options: */
    1829         {
    1830             const bool fEnabledGlobally = !vboxGlobal().settings().isFeatureActive("noStatusBar");
    1831             const bool fEnabledForMachine = gEDataManager->statusBarEnabled(strMachineID);
    1832             const bool fEnabled = fEnabledGlobally && fEnabledForMachine;
    1833             QAction *pActionStatusBarSettings = actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_S_Settings);
    1834             pActionStatusBarSettings->setEnabled(fEnabled);
    1835             QAction *pActionStatusBarSwitch = actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_T_Visibility);
    1836             pActionStatusBarSwitch->blockSignals(true);
    1837             pActionStatusBarSwitch->setChecked(fEnabled);
    1838             pActionStatusBarSwitch->blockSignals(false);
    1839         }
    1840 
    1841         /* Input options: */
    1842         actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration)->setChecked(isMouseIntegrated());
    1843 
    1844         /* What is the default close action and the restricted are? */
    1845         m_defaultCloseAction = gEDataManager->defaultMachineCloseAction(strMachineID);
    1846         m_restrictedCloseActions = gEDataManager->restrictedMachineCloseActions(strMachineID);
    1847         m_fAllCloseActionsRestricted =  (!vboxGlobal().isSeparateProcess() || (m_restrictedCloseActions & MachineCloseAction_Detach))
    1848                                      && (m_restrictedCloseActions & MachineCloseAction_SaveState)
    1849                                      && (m_restrictedCloseActions & MachineCloseAction_Shutdown)
    1850                                      && (m_restrictedCloseActions & MachineCloseAction_PowerOff);
    1851                                      // Close VM Dialog hides PowerOff_RestoringSnapshot implicitly if PowerOff is hidden..
    1852                                      // && (m_restrictedCloseActions & MachineCloseAction_PowerOff_RestoringSnapshot);
    1853     }
    1854 }
    1855 
    1856 void UISession::saveSessionSettings()
    1857 {
    1858     /* Save extra-data settings: */
    1859     {
    1860         /* Disable First RUN Wizard: */
    1861         gEDataManager->setMachineFirstTimeStarted(false, vboxGlobal().managedVMUuid());
    1862 
    1863         /* Remember if guest should autoresize: */
    1864         if (actionPool())
    1865         {
    1866             const QAction *pGuestAutoresizeSwitch = actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize);
    1867             gEDataManager->setGuestScreenAutoResizeEnabled(pGuestAutoresizeSwitch->isChecked(), vboxGlobal().managedVMUuid());
    1868         }
    1869 
    1870 #ifndef Q_WS_MAC
    1871         /* Cleanup user's machine-window icon: */
    1872         delete m_pMachineWindowIcon;
    1873         m_pMachineWindowIcon = 0;
    1874 #endif /* !Q_WS_MAC */
    1875     }
    1876 }
    1877 
    1878 void UISession::cleanupFramebuffers()
    1879 {
    1880     /* Cleanup framebuffers finally: */
    1881     for (int i = m_frameBufferVector.size() - 1; i >= 0; --i)
    1882     {
    1883         UIFrameBuffer *pFrameBuffer = m_frameBufferVector[i];
    1884         if (pFrameBuffer)
    1885         {
    1886             /* Mark framebuffer as unused: */
    1887             pFrameBuffer->setMarkAsUnused(true);
    1888             /* Detach framebuffer from Display: */
    1889             pFrameBuffer->detach();
    1890             /* Delete framebuffer reference: */
    1891             delete pFrameBuffer;
    1892         }
    1893     }
    1894     m_frameBufferVector.clear();
    1895 }
    1896 
    1897 void UISession::cleanupConsoleEventHandlers()
    1898 {
    1899     /* Destroy console event-handler if necessary: */
    1900     if (gConsoleEvents)
    1901         UIConsoleEventHandler::destroy();
    1902 }
    1903 
    1904 void UISession::cleanupConnections()
    1905 {
    1906 #ifdef Q_WS_MAC
    1907     /* Remove display reconfiguration callback: */
    1908     CGDisplayRemoveReconfigurationCallback(cgDisplayReconfigurationCallback, this);
    1909 #endif /* Q_WS_MAC */
    1910 }
    1911 
    1912 void UISession::cleanupActions()
    1913 {
    1914 #ifdef Q_WS_MAC
    1915     /* Destroy Mac OS X menu-bar: */
    1916     delete m_pMenuBar;
    1917     m_pMenuBar = 0;
    1918 #endif /* Q_WS_MAC */
    1919 
    1920     /* Destroy action-pool if necessary: */
    1921     if (actionPool())
    1922         UIActionPool::destroy(actionPool());
    1923 }
    1924 
    1925 void UISession::cleanupSession()
    1926 {
    1927     /* Detach debugger: */
    1928     if (!m_debugger.isNull())
    1929         m_debugger.detach();
    1930 
    1931     /* Detach keyboard: */
    1932     if (!m_keyboard.isNull())
    1933         m_keyboard.detach();
    1934 
    1935     /* Detach mouse: */
    1936     if (!m_mouse.isNull())
    1937         m_mouse.detach();
    1938 
    1939     /* Detach guest: */
    1940     if (!m_guest.isNull())
    1941         m_guest.detach();
    1942 
    1943     /* Detach display: */
    1944     if (!m_display.isNull())
    1945         m_display.detach();
    1946 
    1947     /* Detach console: */
    1948     if (!m_console.isNull())
    1949         m_console.detach();
    1950 
    1951     /* Detach machine: */
    1952     if (!m_machine.isNull())
    1953         m_machine.detach();
    1954 
    1955     /* Close session: */
    1956     if (!m_session.isNull() && vboxGlobal().isVBoxSVCAvailable())
    1957     {
    1958         m_session.UnlockMachine();
    1959         m_session.detach();
    1960     }
    1961 }
    1962 
    1963 void UISession::cleanup()
    1964 {
    1965 #ifdef Q_WS_WIN
    1966     /* Destroy alpha cursor: */
    1967     if (m_alphaCursor)
    1968         DestroyIcon(m_alphaCursor);
    1969 #endif /* Q_WS_WIN */
    1970 
    1971     /* Save settings: */
    1972     saveSessionSettings();
    1973 
    1974     /* Cleanup framebuffers: */
    1975     cleanupFramebuffers();
    1976 
    1977     /* Cleanup console event-handlers: */
    1978     cleanupConsoleEventHandlers();
    1979 
    1980     /* Cleanup connections: */
    1981     cleanupConnections();
    1982 
    1983     /* Cleanup actions: */
    1984     cleanupActions();
    1985 
    1986     /* Cleanup session: */
    1987     cleanupSession();
    1988 }
    1989 
    1990 #ifdef Q_WS_MAC
    1991 void UISession::updateMenu()
    1992 {
    1993     /* Rebuild Mac OS X menu-bar: */
    1994     m_pMenuBar->clear();
    1995     foreach (QMenu *pMenu, actionPool()->menus())
    1996     {
    1997         UIMenu *pMenuUI = qobject_cast<UIMenu*>(pMenu);
    1998         if (!pMenuUI->isConsumable() || !pMenuUI->isConsumed())
    1999             m_pMenuBar->addMenu(pMenuUI);
    2000         if (pMenuUI->isConsumable() && !pMenuUI->isConsumed())
    2001             pMenuUI->setConsumed(true);
    2002     }
    2003 }
    2004 #endif /* Q_WS_MAC */
    2005 
    2006 WId UISession::winId() const
    2007 {
    2008     return mainMachineWindow()->winId();
    2009 }
    2010 
    2011 void UISession::setPointerShape(const uchar *pShapeData, bool fHasAlpha,
    2012                                 uint uXHot, uint uYHot, uint uWidth, uint uHeight)
    2013 {
    2014     AssertMsg(pShapeData, ("Shape data must not be NULL!\n"));
    2015 
    2016     m_fIsValidPointerShapePresent = false;
    2017     const uchar *srcAndMaskPtr = pShapeData;
    2018     uint andMaskSize = (uWidth + 7) / 8 * uHeight;
    2019     const uchar *srcShapePtr = pShapeData + ((andMaskSize + 3) & ~3);
    2020     uint srcShapePtrScan = uWidth * 4;
    2021 
    2022 #if defined (Q_WS_WIN)
    2023 
    2024     BITMAPV5HEADER bi;
    2025     HBITMAP hBitmap;
    2026     void *lpBits;
    2027 
    2028     ::ZeroMemory(&bi, sizeof (BITMAPV5HEADER));
    2029     bi.bV5Size = sizeof(BITMAPV5HEADER);
    2030     bi.bV5Width = uWidth;
    2031     bi.bV5Height = - (LONG)uHeight;
    2032     bi.bV5Planes = 1;
    2033     bi.bV5BitCount = 32;
    2034     bi.bV5Compression = BI_BITFIELDS;
    2035     bi.bV5RedMask   = 0x00FF0000;
    2036     bi.bV5GreenMask = 0x0000FF00;
    2037     bi.bV5BlueMask  = 0x000000FF;
    2038     if (fHasAlpha)
    2039         bi.bV5AlphaMask = 0xFF000000;
    2040     else
    2041         bi.bV5AlphaMask = 0;
    2042 
    2043     HDC hdc = GetDC(NULL);
    2044 
    2045     /* Create the DIB section with an alpha channel: */
    2046     hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, (DWORD) 0);
    2047 
    2048     ReleaseDC(NULL, hdc);
    2049 
    2050     HBITMAP hMonoBitmap = NULL;
    2051     if (fHasAlpha)
    2052     {
    2053         /* Create an empty mask bitmap: */
    2054         hMonoBitmap = CreateBitmap(uWidth, uHeight, 1, 1, NULL);
    2055     }
    2056     else
    2057     {
    2058         /* Word aligned AND mask. Will be allocated and created if necessary. */
    2059         uint8_t *pu8AndMaskWordAligned = NULL;
    2060 
    2061         /* Width in bytes of the original AND mask scan line. */
    2062         uint32_t cbAndMaskScan = (uWidth + 7) / 8;
    2063 
    2064         if (cbAndMaskScan & 1)
    2065         {
    2066             /* Original AND mask is not word aligned. */
    2067 
    2068             /* Allocate memory for aligned AND mask. */
    2069             pu8AndMaskWordAligned = (uint8_t *)RTMemTmpAllocZ((cbAndMaskScan + 1) * uHeight);
    2070 
    2071             Assert(pu8AndMaskWordAligned);
    2072 
    2073             if (pu8AndMaskWordAligned)
    2074             {
    2075                 /* According to MSDN the padding bits must be 0.
    2076                  * Compute the bit mask to set padding bits to 0 in the last byte of original AND mask. */
    2077                 uint32_t u32PaddingBits = cbAndMaskScan * 8  - uWidth;
    2078                 Assert(u32PaddingBits < 8);
    2079                 uint8_t u8LastBytesPaddingMask = (uint8_t)(0xFF << u32PaddingBits);
    2080 
    2081                 Log(("u8LastBytesPaddingMask = %02X, aligned w = %d, width = %d, cbAndMaskScan = %d\n",
    2082                       u8LastBytesPaddingMask, (cbAndMaskScan + 1) * 8, uWidth, cbAndMaskScan));
    2083 
    2084                 uint8_t *src = (uint8_t *)srcAndMaskPtr;
    2085                 uint8_t *dst = pu8AndMaskWordAligned;
    2086 
    2087                 unsigned i;
    2088                 for (i = 0; i < uHeight; i++)
    2089                 {
    2090                     memcpy(dst, src, cbAndMaskScan);
    2091 
    2092                     dst[cbAndMaskScan - 1] &= u8LastBytesPaddingMask;
    2093 
    2094                     src += cbAndMaskScan;
    2095                     dst += cbAndMaskScan + 1;
    2096                 }
    2097             }
    2098         }
    2099 
    2100         /* Create the AND mask bitmap: */
    2101         hMonoBitmap = ::CreateBitmap(uWidth, uHeight, 1, 1,
    2102                                      pu8AndMaskWordAligned? pu8AndMaskWordAligned: srcAndMaskPtr);
    2103 
    2104         if (pu8AndMaskWordAligned)
    2105         {
    2106             RTMemTmpFree(pu8AndMaskWordAligned);
    2107         }
    2108     }
    2109 
    2110     Assert(hBitmap);
    2111     Assert(hMonoBitmap);
    2112     if (hBitmap && hMonoBitmap)
    2113     {
    2114         DWORD *dstShapePtr = (DWORD *) lpBits;
    2115 
    2116         for (uint y = 0; y < uHeight; y ++)
    2117         {
    2118             memcpy(dstShapePtr, srcShapePtr, srcShapePtrScan);
    2119             srcShapePtr += srcShapePtrScan;
    2120             dstShapePtr += uWidth;
    2121         }
    2122 
    2123         ICONINFO ii;
    2124         ii.fIcon = FALSE;
    2125         ii.xHotspot = uXHot;
    2126         ii.yHotspot = uYHot;
    2127         ii.hbmMask = hMonoBitmap;
    2128         ii.hbmColor = hBitmap;
    2129 
    2130         HCURSOR hAlphaCursor = CreateIconIndirect(&ii);
    2131         Assert(hAlphaCursor);
    2132         if (hAlphaCursor)
    2133         {
    2134             /* Set the new cursor: */
    2135             m_cursor = QCursor(hAlphaCursor);
    2136             if (m_alphaCursor)
    2137                 DestroyIcon(m_alphaCursor);
    2138             m_alphaCursor = hAlphaCursor;
    2139             m_fIsValidPointerShapePresent = true;
    2140         }
    2141     }
    2142 
    2143     if (hMonoBitmap)
    2144         DeleteObject(hMonoBitmap);
    2145     if (hBitmap)
    2146         DeleteObject(hBitmap);
    2147 
    2148 #elif defined (Q_WS_X11) && !defined (VBOX_WITHOUT_XCURSOR)
    2149 
    2150     XcursorImage *img = XcursorImageCreate(uWidth, uHeight);
    2151     Assert(img);
    2152     if (img)
    2153     {
    2154         img->xhot = uXHot;
    2155         img->yhot = uYHot;
    2156 
    2157         XcursorPixel *dstShapePtr = img->pixels;
    2158 
    2159         for (uint y = 0; y < uHeight; y ++)
    2160         {
    2161             memcpy (dstShapePtr, srcShapePtr, srcShapePtrScan);
    2162 
    2163             if (!fHasAlpha)
    2164             {
    2165                 /* Convert AND mask to the alpha channel: */
    2166                 uchar byte = 0;
    2167                 for (uint x = 0; x < uWidth; x ++)
    2168                 {
    2169                     if (!(x % 8))
    2170                         byte = *(srcAndMaskPtr ++);
    2171                     else
    2172                         byte <<= 1;
    2173 
    2174                     if (byte & 0x80)
    2175                     {
    2176                         /* Linux doesn't support inverted pixels (XOR ops,
    2177                          * to be exact) in cursor shapes, so we detect such
    2178                          * pixels and always replace them with black ones to
    2179                          * make them visible at least over light colors */
    2180                         if (dstShapePtr [x] & 0x00FFFFFF)
    2181                             dstShapePtr [x] = 0xFF000000;
    2182                         else
    2183                             dstShapePtr [x] = 0x00000000;
    2184                     }
    2185                     else
    2186                         dstShapePtr [x] |= 0xFF000000;
    2187                 }
    2188             }
    2189 
    2190             srcShapePtr += srcShapePtrScan;
    2191             dstShapePtr += uWidth;
    2192         }
    2193 
    2194         /* Set the new cursor: */
    2195         m_cursor = QCursor(XcursorImageLoadCursor(QX11Info::display(), img));
    2196         m_fIsValidPointerShapePresent = true;
    2197 
    2198         XcursorImageDestroy(img);
    2199     }
    2200 
    2201 #elif defined(Q_WS_MAC)
    2202 
    2203     /* Create a ARGB image out of the shape data. */
    2204     QImage image  (uWidth, uHeight, QImage::Format_ARGB32);
    2205     const uint8_t* pbSrcMask = static_cast<const uint8_t*> (srcAndMaskPtr);
    2206     unsigned cbSrcMaskLine = RT_ALIGN (uWidth, 8) / 8;
    2207     for (unsigned int y = 0; y < uHeight; ++y)
    2208     {
    2209         for (unsigned int x = 0; x < uWidth; ++x)
    2210         {
    2211            unsigned int color = ((unsigned int*)srcShapePtr)[y*uWidth+x];
    2212            /* If the alpha channel isn't in the shape data, we have to
    2213             * create them from the and-mask. This is a bit field where 1
    2214             * represent transparency & 0 opaque respectively. */
    2215            if (!fHasAlpha)
    2216            {
    2217                if (!(pbSrcMask[x / 8] & (1 << (7 - (x % 8)))))
    2218                    color  |= 0xff000000;
    2219                else
    2220                {
    2221                    /* This isn't quite right, but it's the best we can do I think... */
    2222                    if (color & 0x00ffffff)
    2223                        color = 0xff000000;
    2224                    else
    2225                        color = 0x00000000;
    2226                }
    2227            }
    2228            image.setPixel (x, y, color);
    2229         }
    2230         /* Move one scanline forward. */
    2231         pbSrcMask += cbSrcMaskLine;
    2232     }
    2233 
    2234     /* Set the new cursor: */
    2235     m_cursor = QCursor(QPixmap::fromImage(image), uXHot, uYHot);
    2236     m_fIsValidPointerShapePresent = true;
    2237     NOREF(srcShapePtrScan);
    2238 
    2239 #else
    2240 
    2241 # warning "port me"
    2242 
    2243 #endif
    2244 }
    2245 
    2246 bool UISession::preprocessInitialization()
    2247 {
    2248 #ifdef VBOX_WITH_NETFLT
    2249     /* Skip further checks if VM in saved state */
    2250     if (isSaved())
    2251         return true;
    2252 
    2253     /* Make sure all the attached and enabled network
    2254      * adapters are present on the host. This check makes sense
    2255      * in two cases only - when attachement type is Bridged Network
    2256      * or Host-only Interface. NOTE: Only currently enabled
    2257      * attachement type is checked (incorrect parameters check for
    2258      * currently disabled attachement types is skipped). */
    2259     QStringList failedInterfaceNames;
    2260     QStringList availableInterfaceNames;
    2261 
    2262     /* Create host network interface names list */
    2263     foreach (const CHostNetworkInterface &iface, vboxGlobal().host().GetNetworkInterfaces())
    2264     {
    2265         availableInterfaceNames << iface.GetName();
    2266         availableInterfaceNames << iface.GetShortName();
    2267     }
    2268 
    2269     ulong cCount = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(machine().GetChipsetType());
    2270     for (ulong uAdapterIndex = 0; uAdapterIndex < cCount; ++uAdapterIndex)
    2271     {
    2272         CNetworkAdapter na = machine().GetNetworkAdapter(uAdapterIndex);
    2273 
    2274         if (na.GetEnabled())
    2275         {
    2276             QString strIfName = QString();
    2277 
    2278             /* Get physical network interface name for currently
    2279              * enabled network attachement type */
    2280             switch (na.GetAttachmentType())
    2281             {
    2282                 case KNetworkAttachmentType_Bridged:
    2283                     strIfName = na.GetBridgedInterface();
    2284                     break;
    2285                 case KNetworkAttachmentType_HostOnly:
    2286                     strIfName = na.GetHostOnlyInterface();
    2287                     break;
    2288             }
    2289 
    2290             if (!strIfName.isEmpty() &&
    2291                 !availableInterfaceNames.contains(strIfName))
    2292             {
    2293                 LogFlow(("Found invalid network interface: %s\n", strIfName.toStdString().c_str()));
    2294                 failedInterfaceNames << QString("%1 (adapter %2)").arg(strIfName).arg(uAdapterIndex + 1);
    2295             }
    2296         }
    2297     }
    2298 
    2299     /* Check if non-existent interfaces found */
    2300     if (!failedInterfaceNames.isEmpty())
    2301     {
    2302         if (msgCenter().cannotStartWithoutNetworkIf(machineName(), failedInterfaceNames.join(", ")))
    2303             machineLogic()->openNetworkSettingsDialog();
    2304         else
    2305             return false;
    2306     }
    2307 #endif /* VBOX_WITH_NETFLT */
    2308 
    2309     /* True by default: */
    2310     return true;
    2311 }
    2312 
    2313 bool UISession::postprocessInitialization()
    2314 {
    2315     /* Check if the required virtualization features are active. We get this info only when the session is active. */
    2316     const bool fIs64BitsGuest = vboxGlobal().virtualBox().GetGuestOSType(guest().GetOSTypeId()).GetIs64Bit();
    2317     const bool fRecommendVirtEx = vboxGlobal().virtualBox().GetGuestOSType(guest().GetOSTypeId()).GetRecommendedVirtEx();
    2318     AssertMsg(!fIs64BitsGuest || fRecommendVirtEx, ("Virtualization support missed for 64bit guest!\n"));
    2319     const bool fIsVirtActive = debugger().GetHWVirtExEnabled();
    2320     if (fRecommendVirtEx && !fIsVirtActive)
    2321     {
    2322         /* Check whether vt-x / amd-v supported: */
    2323         bool fVTxAMDVSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
    2324 
    2325         /* Pause VM: */
    2326         setPause(true);
    2327 
    2328         /* Ask the user about further actions: */
    2329         bool fShouldWeClose;
    2330         if (fIs64BitsGuest)
    2331             fShouldWeClose = msgCenter().warnAboutVirtExInactiveFor64BitsGuest(fVTxAMDVSupported);
    2332         else
    2333             fShouldWeClose = msgCenter().warnAboutVirtExInactiveForRecommendedGuest(fVTxAMDVSupported);
    2334 
    2335         /* If user asked to close VM: */
    2336         if (fShouldWeClose)
    2337         {
    2338             /* Prevent auto-closure during power off sequence: */
    2339             machineLogic()->setPreventAutoClose(true);
    2340             /* Power off VM: */
    2341             bool fServerCrashed = false;
    2342             powerOff(false, fServerCrashed);
    2343             return false;
    2344         }
    2345 
    2346         /* Resume VM: */
    2347         setPause(false);
    2348     }
    2349 
    2350     /* True by default: */
    2351     return true;
    2352 }
    2353 
    2354 bool UISession::isScreenVisible(ulong uScreenId) const
    2355 {
    2356     Assert(uScreenId < (ulong)m_monitorVisibilityVector.size());
    2357     return m_monitorVisibilityVector.value((int)uScreenId, false);
    2358 }
    2359 
    2360 void UISession::setScreenVisible(ulong uScreenId, bool fIsMonitorVisible)
    2361 {
    2362     Assert(uScreenId < (ulong)m_monitorVisibilityVector.size());
    2363     if (uScreenId < (ulong)m_monitorVisibilityVector.size())
    2364         m_monitorVisibilityVector[(int)uScreenId] = fIsMonitorVisible;
    2365 }
    2366 
    2367 int UISession::countOfVisibleWindows()
    2368 {
    2369     int cCountOfVisibleWindows = 0;
    2370     for (int i = 0; i < m_monitorVisibilityVector.size(); ++i)
    2371         if (m_monitorVisibilityVector[i])
    2372             ++cCountOfVisibleWindows;
    2373     return cCountOfVisibleWindows;
    2374 }
    2375 
    2376 UIFrameBuffer* UISession::frameBuffer(ulong uScreenId) const
    2377 {
    2378     Assert(uScreenId < (ulong)m_frameBufferVector.size());
    2379     return m_frameBufferVector.value((int)uScreenId, 0);
    2380 }
    2381 
    2382 void UISession::setFrameBuffer(ulong uScreenId, UIFrameBuffer* pFrameBuffer)
    2383 {
    2384     Assert(uScreenId < (ulong)m_frameBufferVector.size());
    2385     if (uScreenId < (ulong)m_frameBufferVector.size())
    2386         m_frameBufferVector[(int)uScreenId] = pFrameBuffer;
    2387 }
    2388 
    2389 void UISession::updateHostScreenData()
    2390 {
    2391     m_hostScreens.clear();
    2392     QDesktopWidget *pDesktop = QApplication::desktop();
    2393     for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
    2394         m_hostScreens << pDesktop->screenGeometry(iScreenIndex);
    2395 }
    2396 
    2397 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    2398 /**
    2399  * Custom signal handler. When switching VTs, we might not get release events
    2400  * for Ctrl-Alt and in case a savestate is performed on the new VT, the VM will
    2401  * be saved with modifier keys stuck. This is annoying enough for introducing
    2402  * this hack.
    2403  */
    2404 /* static */
    2405 static void signalHandlerSIGUSR1(int sig, siginfo_t * /* pInfo */, void * /*pSecret */)
    2406 {
    2407     /* only SIGUSR1 is interesting */
    2408     if (sig == SIGUSR1)
    2409         if (UIMachine *pMachine = vboxGlobal().virtualMachine())
    2410             pMachine->uisession()->machineLogic()->keyboardHandler()->releaseAllPressedKeys();
    2411 }
    2412 #endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    2413 
    2414 #include "UISession.moc"
    2415 
     297    /* Depending on column index: */
     298    switch (index.column())
     299    {
     300        case UIEncryptionDataTableSection_Password: m_encryptionPasswords[m_encryptionPasswords.keys().at(index.row())] = value.toString(); break;
     301        default: break;
     302    }
     303    /* Nothing to set by default: */
     304    return false;
     305}
     306
     307void UIEncryptionDataModel::prepare()
     308{
     309    /* Populate the map of passwords. */
     310    foreach (const QString &strPasswordId, m_encryptedMediums.keys())
     311        m_encryptionPasswords.insert(strPasswordId, QString());
     312}
     313
     314UIEncryptionDataTable::UIEncryptionDataTable(const EncryptedMediumsMap &encryptedMediums)
     315    : m_encryptedMediums(encryptedMediums)
     316    , m_pModelEncryptionData(0)
     317{
     318    /* Prepare: */
     319    prepare();
     320}
     321
     322EncryptionPasswordsMap UIEncryptionDataTable::encryptionPasswords() const
     323{
     324    AssertPtrReturn(m_pModelEncryptionData, EncryptionPasswordsMap());
     325    return m_pModelEncryptionData->encryptionPasswords();
     326}
     327
     328void UIEncryptionDataTable::prepare()
     329{
     330    /* Create encryption-data model: */
     331    m_pModelEncryptionData = new UIEncryptionDataModel(this, m_encryptedMediums);
     332    AssertPtrReturnVoid(m_pModelEncryptionData);
     333    {
     334        /* Assign configured model to table: */
     335        setModel(m_pModelEncryptionData);
     336    }
     337
     338    /* Create item delegate: */
     339    QIStyledItemDelegate *pStyledItemDelegate = new QIStyledItemDelegate(this);
     340    AssertPtrReturnVoid(pStyledItemDelegate);
     341    {
     342        /* Create item editor factory: */
     343        QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
     344        AssertPtrReturnVoid(pNewItemEditorFactory);
     345        {
     346            /* Create item editor creator: */
     347            QStandardItemEditorCreator<UIPasswordEditor> *pQStringItemEditorCreator = new QStandardItemEditorCreator<UIPasswordEditor>();
     348            AssertPtrReturnVoid(pQStringItemEditorCreator);
     349            {
     350                /* Register UIPasswordEditor as the QString editor: */
     351                pNewItemEditorFactory->registerEditor(QVariant::String, pQStringItemEditorCreator);
     352            }
     353            /* Assign configured item editor factory to table delegate: */
     354            pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
     355        }
     356        /* Assign configured item delegate to table: */
     357        delete itemDelegate();
     358        setItemDelegate(pStyledItemDelegate);
     359    }
     360
     361    /* Configure table: */
     362    setTabKeyNavigation(false);
     363    setContextMenuPolicy(Qt::CustomContextMenu);
     364    setSelectionBehavior(QAbstractItemView::SelectRows);
     365    setSelectionMode(QAbstractItemView::SingleSelection);
     366    setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
     367
     368    /* Configure headers: */
     369    verticalHeader()->hide();
     370    verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));
     371    horizontalHeader()->setStretchLastSection(false);
     372    horizontalHeader()->setResizeMode(UIEncryptionDataTableSection_Id, QHeaderView::Interactive);
     373    horizontalHeader()->setResizeMode(UIEncryptionDataTableSection_Password, QHeaderView::Stretch);
     374}
     375
     376UIAddDiskEncryptionPasswordDialog::UIAddDiskEncryptionPasswordDialog(QWidget *pParent, const EncryptedMediumsMap &encryptedMediums)
     377    : QIWithRetranslateUI<QDialog>(pParent)
     378    , m_encryptedMediums(encryptedMediums)
     379    , m_pLabelDescription(0)
     380    , m_pTableEncryptionData(0)
     381{
     382    /* Prepare: */
     383    prepare();
     384    /* Retranslate: */
     385    retranslateUi();
     386}
     387
     388EncryptionPasswordsMap UIAddDiskEncryptionPasswordDialog::encryptionPasswords() const
     389{
     390    AssertPtrReturn(m_pTableEncryptionData, EncryptionPasswordsMap());
     391    return m_pTableEncryptionData->encryptionPasswords();
     392}
     393
     394void UIAddDiskEncryptionPasswordDialog::prepare()
     395{
     396    /* Create main-layout: */
     397    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     398    AssertPtrReturnVoid(pMainLayout);
     399    {
     400        /* Create input-layout: */
     401        QVBoxLayout *pInputLayout = new QVBoxLayout;
     402        AssertPtrReturnVoid(pInputLayout);
     403        {
     404            /* Create description label: */
     405            m_pLabelDescription = new QILabel;
     406            m_pLabelDescription->useSizeHintForWidth(450);
     407            m_pLabelDescription->updateGeometry();
     408            AssertPtrReturnVoid(m_pLabelDescription);
     409            {
     410                /* Configure description label: */
     411                m_pLabelDescription->setWordWrap(true);
     412                /* Add label into layout: */
     413                pInputLayout->addWidget(m_pLabelDescription);
     414            }
     415            /* Create encryption-data table: */
     416            m_pTableEncryptionData = new UIEncryptionDataTable(m_encryptedMediums);
     417            AssertPtrReturnVoid(m_pTableEncryptionData);
     418            {
     419                /* Add label into layout: */
     420                pInputLayout->addWidget(m_pTableEncryptionData);
     421            }
     422            /* Add layout into parent: */
     423            pMainLayout->addLayout(pInputLayout);
     424        }
     425        /* Create button-box: */
     426        QIDialogButtonBox *pButtonBox = new QIDialogButtonBox;
     427        AssertPtrReturnVoid(pButtonBox);
     428        {
     429            /* Configure button-box: */
     430            pButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
     431            connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
     432            connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
     433            /* Add button-box into layout: */
     434            pMainLayout->addWidget(pButtonBox);
     435        }
     436    }
     437}
     438
     439void UIAddDiskEncryptionPasswordDialog::retranslateUi()
     440{
     441    AssertPtrReturnVoid(m_pLabelDescription);
     442    m_pLabelDescription->setText(tr("This virtual machine is password protected. "
     443                                    "Please enter the %n encryption password(s) below.",
     444                                    "This text is never used with n == 0. "
     445                                    "Feel free to drop the %n where possible, "
     446                                    "we only included it because of problems with Qt Linguist "
     447                                    "(but the user can see how many passwords are in the list "
     448                                    "and doesn't need to be told).",
     449                                    m_encryptedMediums.size()));
     450}
     451
     452#include "UIAddDiskEncryptionPasswordDialog.moc"
     453
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.h

    r54732 r54733  
    1 /* $Id$ */
    21/** @file
    3  * VBox Qt GUI - UISession class implementation.
     2 * VBox Qt GUI - UIAddDiskEncryptionPasswordDialog class declaration.
    43 */
    54
    65/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     6 * Copyright (C) 2006-2015 Oracle Corporation
    87 *
    98 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1615 */
    1716
    18 #ifdef VBOX_WITH_PRECOMPILED_HEADERS
    19 # include <precomp.h>
    20 #else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
    21 
    22 /* Qt includes: */
    23 # include <QApplication>
    24 # include <QDesktopWidget>
    25 # include <QWidget>
    26 # ifdef Q_WS_MAC
    27 #  include <QTimer>
    28 # endif /* Q_WS_MAC */
    29 
    30 /* GUI includes: */
    31 # include "VBoxGlobal.h"
    32 # include "UIExtraDataManager.h"
    33 # include "UISession.h"
    34 # include "UIMachine.h"
    35 # include "UIMedium.h"
    36 # include "UIActionPoolRuntime.h"
    37 # include "UIMachineLogic.h"
    38 # include "UIMachineView.h"
    39 # include "UIMachineWindow.h"
    40 # include "UIMessageCenter.h"
    41 # include "UIPopupCenter.h"
    42 # include "UIWizardFirstRun.h"
    43 # include "UIConsoleEventHandler.h"
    44 # include "UIFrameBuffer.h"
    45 # include "UISettingsDialogSpecific.h"
    46 # ifdef VBOX_WITH_VIDEOHWACCEL
    47 #  include "VBoxFBOverlay.h"
    48 # endif /* VBOX_WITH_VIDEOHWACCEL */
    49 # ifdef Q_WS_MAC
    50 #  include "UIMenuBar.h"
    51 #  include "VBoxUtils-darwin.h"
    52 # endif /* Q_WS_MAC */
    53 
    54 # ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    55 #  include "UIKeyboardHandler.h"
    56 #  include <signal.h>
    57 # endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    58 
    59 /* COM includes: */
    60 # include "CSystemProperties.h"
    61 # include "CStorageController.h"
    62 # include "CMediumAttachment.h"
    63 # include "CNetworkAdapter.h"
    64 # include "CHostNetworkInterface.h"
    65 # include "CVRDEServer.h"
    66 # include "CUSBController.h"
    67 # include "CUSBDeviceFilters.h"
    68 # include "CHostVideoInputDevice.h"
    69 # include "CSnapshot.h"
    70 # include "CMedium.h"
    71 
    72 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    73 
    74 #ifdef Q_WS_X11
    75 # include <QX11Info>
    76 # include <X11/Xlib.h>
    77 # include <X11/Xutil.h>
    78 # ifndef VBOX_WITHOUT_XCURSOR
    79 #  include <X11/Xcursor/Xcursor.h>
    80 # endif /* VBOX_WITHOUT_XCURSOR */
    81 #endif /* Q_WS_X11 */
    82 
     17#ifndef ___UIAddDiskEncryptionPasswordDialog_h___
     18#define ___UIAddDiskEncryptionPasswordDialog_h___
    8319
    8420/* Qt includes: */
    8521#include <QDialog>
    86 #include <QVBoxLayout>
    87 #include <QLineEdit>
    88 #include <QTableView>
    89 #include <QHeaderView>
    90 #include <QItemEditorFactory>
    91 #include <QAbstractTableModel>
    92 #include <QStandardItemEditorCreator>
     22#include <QMultiMap>
     23#include <QMap>
     24
    9325/* GUI includes: */
    94 #include "QILabel.h"
    95 #include "QIDialogButtonBox.h"
    9626#include "QIWithRetranslateUI.h"
    97 #include "QIStyledItemDelegate.h"
     27
     28/* Forward declarations: */
     29class UIEncryptionDataTable;
     30class QILabel;
    9831
    9932/* Type definitions: */
     33typedef QMultiMap<QString, QString> EncryptedMediumsMap;
    10034typedef QMap<QString, QString> EncryptionPasswordsMap;
    101 typedef QMultiMap<QString, QString> EncryptedMediumsMap;
    10235
    103 /** Encryption-data table field indexes.
    104   * @todo To be moved into separate file.. */
    105 enum UIEncryptionTableSection
    106 {
    107     UIEncryptionTableSection_Id,
    108     UIEncryptionTableSection_Password,
    109     UIEncryptionTableSection_Max
    110 };
    111 
    112 /** QLineEdit implementation allowing to enter
    113   * disk encryption password for particular password id.
    114   * @todo To be moved into separate file.. */
    115 class UILineEdit : public QLineEdit
    116 {
    117     Q_OBJECT;
    118     Q_PROPERTY(QString password READ password WRITE setPassword USER true);
    119 
    120 signals:
    121 
    122     /** Notifies listener about data should be committed. */
    123     void sigCommitData(QWidget *pThis);
    124 
    125 public:
    126 
    127     /** Constructor.
    128       * @param pParent being passed to the base-class. */
    129     UILineEdit(QWidget *pParent)
    130         : QLineEdit(pParent)
    131     {
    132         /* Prepare: */
    133         prepare();
    134     }
    135 
    136 public slots:
    137 
    138     /** Handles @s strText changes. */
    139     void sltTextChanged(const QString &strText)
    140     {
    141         Q_UNUSED(strText);
    142         /* Commit data to the listener: */
    143         emit sigCommitData(this);
    144     }
    145 
    146 private:
    147 
    148     /** Prepare routine. */
    149     void prepare()
    150     {
    151         /* Set alignment: */
    152         setAlignment(Qt::AlignCenter);
    153         /* Set echo mode: */
    154         setEchoMode(QLineEdit::Password);
    155         /* Listen for the text changes: */
    156         connect(this, SIGNAL(textChanged(const QString&)),
    157                 this, SLOT(sltTextChanged(const QString&)));
    158     }
    159 
    160     /** Returns the password from the editor. */
    161     QString password() const { return QLineEdit::text(); }
    162     /** Defines the @a strPassword to the editor. */
    163     void setPassword(const QString &strPassword) { QLineEdit::setText(strPassword); }
    164 };
    165 
    166 /** QAbstractTableModel implementation reflecting
    167   * disk encryption passwords for particular password ids.
    168   * @todo To be moved into separate file.. */
    169 class UIEncryptionDataModel : public QAbstractTableModel
    170 {
    171     Q_OBJECT;
    172 
    173 public:
    174 
    175     /** Constructor.
    176       * @param pParent          being passed to the base-class,
    177       * @param encryptedMediums contains the lists of medium ids (values) encrypted with passwords with ids (keys). */
    178     UIEncryptionDataModel(QObject *pParent, const EncryptedMediumsMap &encryptedMediums)
    179         : QAbstractTableModel(pParent)
    180         , m_encryptedMediums(encryptedMediums)
    181     {
    182         /* Prepare: */
    183         prepare();
    184     }
    185 
    186     /** Returns encryption passwords. */
    187     EncryptionPasswordsMap encryptionPasswords() const { return m_encryptionPasswords; }
    188 
    189     /** Returns the @a index flags. */
    190     virtual Qt::ItemFlags flags(const QModelIndex &index) const
    191     {
    192         /* Check index validness: */
    193         if (!index.isValid())
    194             return Qt::NoItemFlags;
    195         /* Depending on column index: */
    196         switch (index.column())
    197         {
    198             case UIEncryptionTableSection_Id:       return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    199             case UIEncryptionTableSection_Password: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    200             default: break;
    201         }
    202         /* No flags by default: */
    203         return Qt::NoItemFlags;
    204     }
    205 
    206     /** Returns the row count. Provide optional @a parent instead of root if necessary. */
    207     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
    208     {
    209         Q_UNUSED(parent);
    210         return m_encryptionPasswords.size();
    211     }
    212 
    213     /** Returns the column count. Provide optional @a parent instead of root if necessary. */
    214     virtual int columnCount(const QModelIndex &parent = QModelIndex()) const
    215     {
    216         Q_UNUSED(parent);
    217         return UIEncryptionTableSection_Max;
    218     }
    219 
    220     /** Returns header data for @a iSection, @a orientation and @a iRole. */
    221     virtual QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const
    222     {
    223         /* Check argument validness: */
    224         if (iRole != Qt::DisplayRole || orientation != Qt::Horizontal)
    225             return QVariant();
    226         /* Depending on column index: */
    227         switch (iSection)
    228         {
    229             case UIEncryptionTableSection_Id:       return tr("Password ID");
    230             case UIEncryptionTableSection_Password: return tr("Password");
    231             default: break;
    232         }
    233         /* Null value by default: */
    234         return QVariant();
    235     }
    236 
    237     /** Returns @a index data for @a iRole. */
    238     virtual QVariant data(const QModelIndex &index, int iRole /* = Qt::DisplayRole */) const
    239     {
    240         /* Check index validness: */
    241         if (!index.isValid())
    242             return QVariant();
    243         /* Depending on role: */
    244         switch (iRole)
    245         {
    246             case Qt::DisplayRole:
    247             {
    248                 /* Depending on column index: */
    249                 switch (index.column())
    250                 {
    251                     case UIEncryptionTableSection_Id:
    252                         return m_encryptionPasswords.keys().at(index.row());
    253                     case UIEncryptionTableSection_Password:
    254                         return QString().fill('*', m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row())).size());
    255                     default:
    256                         return QVariant();
    257                 }
    258                 break;
    259             }
    260             case Qt::EditRole:
    261             {
    262                 /* Depending on column index: */
    263                 switch (index.column())
    264                 {
    265                     case UIEncryptionTableSection_Password:
    266                         return m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row()));
    267                     default:
    268                         return QVariant();
    269                 }
    270                 break;
    271             }
    272             case Qt::TextAlignmentRole:
    273             {
    274                 /* Depending on column index: */
    275                 switch (index.column())
    276                 {
    277                     case UIEncryptionTableSection_Password:
    278                         return Qt::AlignCenter;
    279                     default: return QVariant();
    280                 }
    281                 break;
    282             }
    283             default:
    284                 break;
    285         }
    286         /* Null value by default: */
    287         return QVariant();
    288     }
    289 
    290     /** Defines @a index data for @a iRole as @a value. */
    291     virtual bool setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole */)
    292     {
    293         /* Check index validness: */
    294         if (!index.isValid())
    295             return false;
    296         /* Check argument validness: */
    297         if (iRole != Qt::EditRole)
    298             return false;
    299         /* Depending on column index: */
    300         switch (index.column())
    301         {
    302             case UIEncryptionTableSection_Password: m_encryptionPasswords[m_encryptionPasswords.keys().at(index.row())] = value.toString(); break;
    303             default: break;
    304         }
    305         /* Nothing to set by default: */
    306         return false;
    307     }
    308 
    309 private:
    310 
    311     /** Prepare routine. */
    312     void prepare()
    313     {
    314         /* Populate the map of passwords. */
    315         foreach (const QString &strPasswordId, m_encryptedMediums.keys())
    316             m_encryptionPasswords.insert(strPasswordId, QString());
    317     }
    318 
    319     /** Holds the encrypted medium map reference. */
    320     const EncryptedMediumsMap &m_encryptedMediums;
    321 
    322     /** Holds the encrypted password id map. */
    323     EncryptionPasswordsMap m_encryptionPasswords;
    324 };
    325 
    326 /** QTableView implementation allowing to enter
    327   * disk encryption passwords for particular password ids.
    328   * @todo To be moved into separate file.. */
    329 class UIEncryptionDataTable : public QTableView
    330 {
    331     Q_OBJECT;
    332 
    333 public:
    334 
    335     /** Constructor.
    336       * @param pParent being passed to the base-class. */
    337     UIEncryptionDataTable(const EncryptedMediumsMap &encryptedMediums)
    338         : m_encryptedMediums(encryptedMediums)
    339         , m_pModelEncryptionData(0)
    340     {
    341         /* Prepare: */
    342         prepare();
    343     }
    344 
    345     /** Returns encryption passwords. */
    346     EncryptionPasswordsMap encryptionPasswords() const
    347     {
    348         AssertPtrReturn(m_pModelEncryptionData, EncryptionPasswordsMap());
    349         return m_pModelEncryptionData->encryptionPasswords();
    350     }
    351 
    352 private:
    353 
    354     /** Prepare routine. */
    355     void prepare()
    356     {
    357         /* Create encryption-data model: */
    358         m_pModelEncryptionData = new UIEncryptionDataModel(this, m_encryptedMediums);
    359         AssertPtrReturnVoid(m_pModelEncryptionData);
    360         {
    361             /* Assign configured model to table: */
    362             setModel(m_pModelEncryptionData);
    363         }
    364 
    365         /* Create item delegate: */
    366         QIStyledItemDelegate *pStyledItemDelegate = new QIStyledItemDelegate(this);
    367         AssertPtrReturnVoid(pStyledItemDelegate);
    368         {
    369             /* Create item editor factory: */
    370             QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    371             AssertPtrReturnVoid(pNewItemEditorFactory);
    372             {
    373                 /* Create item editor creator: */
    374                 QStandardItemEditorCreator<UILineEdit> *pQStringItemEditorCreator = new QStandardItemEditorCreator<UILineEdit>();
    375                 AssertPtrReturnVoid(pQStringItemEditorCreator);
    376                 {
    377                     /* Register UILineEdit as the QString editor: */
    378                     pNewItemEditorFactory->registerEditor(QVariant::String, pQStringItemEditorCreator);
    379                 }
    380                 /* Assign configured item editor factory to table delegate: */
    381                 pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
    382             }
    383             /* Assign configured item delegate to table: */
    384             delete itemDelegate();
    385             setItemDelegate(pStyledItemDelegate);
    386         }
    387 
    388         /* Configure table: */
    389         setTabKeyNavigation(false);
    390         setContextMenuPolicy(Qt::CustomContextMenu);
    391         setSelectionBehavior(QAbstractItemView::SelectRows);
    392         setSelectionMode(QAbstractItemView::SingleSelection);
    393         setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
    394 
    395         /* Configure headers: */
    396         verticalHeader()->hide();
    397         verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));
    398         horizontalHeader()->setStretchLastSection(false);
    399         horizontalHeader()->setResizeMode(UIEncryptionTableSection_Id, QHeaderView::Interactive);
    400         horizontalHeader()->setResizeMode(UIEncryptionTableSection_Password, QHeaderView::Stretch);
    401     }
    402 
    403     /** Holds the encrypted medium map reference. */
    404     const EncryptedMediumsMap &m_encryptedMediums;
    405 
    406     /** Holds the encryption-data model. */
    407     UIEncryptionDataModel *m_pModelEncryptionData;
    408 };
    409 
    410 /** QDialog implementation allowing to enter
    411   * disk encryption passwords for particular password ids.
    412   * @todo To be moved into separate files.. */
     36/** QDialog reimplementation used to
     37  * allow the user to enter disk encryption passwords for particular password ids. */
    41338class UIAddDiskEncryptionPasswordDialog : public QIWithRetranslateUI<QDialog>
    41439{
     
    42045      * @param pParent          being passed to the base-class,
    42146      * @param encryptedMediums contains the lists of medium ids (values) encrypted with passwords with ids (keys). */
    422     UIAddDiskEncryptionPasswordDialog(QWidget *pParent, const EncryptedMediumsMap &encryptedMediums)
    423         : QIWithRetranslateUI<QDialog>(pParent)
    424         , m_encryptedMediums(encryptedMediums)
    425         , m_pLabelDescription(0)
    426         , m_pTableEncryptionData(0)
    427     {
    428         /* Prepare: */
    429         prepare();
    430         /* Retranslate: */
    431         retranslateUi();
    432     }
     47    UIAddDiskEncryptionPasswordDialog(QWidget *pParent, const EncryptedMediumsMap &encryptedMediums);
    43348
    434     /** Returns encryption passwords. */
    435     EncryptionPasswordsMap encryptionPasswords() const
    436     {
    437         AssertPtrReturn(m_pTableEncryptionData, EncryptionPasswordsMap());
    438         return m_pTableEncryptionData->encryptionPasswords();
    439     }
     49    /** Returns the shallow copy of the encryption password map
     50      * acquired from the UIEncryptionDataTable instance. */
     51    EncryptionPasswordsMap encryptionPasswords() const;
    44052
    44153private:
    44254
    44355    /** Prepare routine. */
    444     void prepare()
    445     {
    446         /* Create main-layout: */
    447         QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    448         AssertPtrReturnVoid(pMainLayout);
    449         {
    450             /* Create input-layout: */
    451             QVBoxLayout *pInputLayout = new QVBoxLayout;
    452             AssertPtrReturnVoid(pInputLayout);
    453             {
    454                 /* Create description label: */
    455                 m_pLabelDescription = new QILabel;
    456                 m_pLabelDescription->useSizeHintForWidth(450);
    457                 m_pLabelDescription->updateGeometry();
    458                 AssertPtrReturnVoid(m_pLabelDescription);
    459                 {
    460                     /* Configure description label: */
    461                     m_pLabelDescription->setWordWrap(true);
    462                     /* Add label into layout: */
    463                     pInputLayout->addWidget(m_pLabelDescription);
    464                 }
    465                 /* Create encryption-data table: */
    466                 m_pTableEncryptionData = new UIEncryptionDataTable(m_encryptedMediums);
    467                 AssertPtrReturnVoid(m_pTableEncryptionData);
    468                 {
    469                     /* Add label into layout: */
    470                     pInputLayout->addWidget(m_pTableEncryptionData);
    471                 }
    472                 /* Add layout into parent: */
    473                 pMainLayout->addLayout(pInputLayout);
    474             }
    475             /* Create button-box: */
    476             QIDialogButtonBox *pButtonBox = new QIDialogButtonBox;
    477             AssertPtrReturnVoid(pButtonBox);
    478             {
    479                 /* Configure button-box: */
    480                 pButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    481                 connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
    482                 connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
    483                 /* Add button-box into layout: */
    484                 pMainLayout->addWidget(pButtonBox);
    485             }
    486         }
    487     }
     56    void prepare();
    48857
    48958    /** Translation routine. */
    490     void retranslateUi()
    491     {
    492         AssertPtrReturnVoid(m_pLabelDescription);
    493         m_pLabelDescription->setText(tr("This virtual machine is password protected. "
    494                                         "Please enter the %n encryption password(s) below.",
    495                                         "This text is never used with n == 0. "
    496                                         "Feel free to drop the %n where possible, "
    497                                         "we only included it because of problems with Qt Linguist "
    498                                         "(but the user can see how many passwords are in the list "
    499                                         "and doesn't need to be told).",
    500                                         m_encryptedMediums.size()));
    501     }
     59    void retranslateUi();
    50260
    50361    /** Holds the encrypted medium map reference. */
    50462    const EncryptedMediumsMap &m_encryptedMediums;
    50563
    506     /** Holds the description label. */
     64    /** Holds the description label instance. */
    50765    QILabel *m_pLabelDescription;
    508     /** Holds the encryption-data table. */
     66    /** Holds the encryption-data table instance. */
    50967    UIEncryptionDataTable *m_pTableEncryptionData;
    51068};
    51169
    512 
    513 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    514 static void signalHandlerSIGUSR1(int sig, siginfo_t *, void *);
    515 #endif
    516 
    517 #ifdef Q_WS_MAC
    518 /**
    519  * MacOS X: Application Services: Core Graphics: Display reconfiguration callback.
    520  *
    521  * Notifies UISession about @a display configuration change.
    522  * Corresponding change described by Core Graphics @a flags.
    523  * Uses UISession @a pHandler to process this change.
    524  *
    525  * @note Last argument (@a pHandler) must always be valid pointer to UISession object.
    526  * @note Calls for UISession::sltHandleHostDisplayAboutToChange() slot if display configuration changed.
    527  */
    528 void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *pHandler)
    529 {
    530     /* Which flags we are handling? */
    531     int iHandledFlags = kCGDisplayAddFlag     /* display added */
    532                       | kCGDisplayRemoveFlag  /* display removed */
    533                       | kCGDisplaySetModeFlag /* display mode changed */;
    534 
    535     /* Handle 'display-add' case: */
    536     if (flags & kCGDisplayAddFlag)
    537         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display added.\n"));
    538     /* Handle 'display-remove' case: */
    539     else if (flags & kCGDisplayRemoveFlag)
    540         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display removed.\n"));
    541     /* Handle 'mode-set' case: */
    542     else if (flags & kCGDisplaySetModeFlag)
    543         LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display mode changed.\n"));
    544 
    545     /* Ask handler to process our callback: */
    546     if (flags & iHandledFlags)
    547         QTimer::singleShot(0, static_cast<UISession*>(pHandler),
    548                            SLOT(sltHandleHostDisplayAboutToChange()));
    549 
    550     Q_UNUSED(display);
    551 }
    552 #endif /* Q_WS_MAC */
    553 
    554 /* static */
    555 bool UISession::create(UISession *&pSession, UIMachine *pMachine)
    556 {
    557     /* Make sure null pointer passed: */
    558     AssertReturn(pSession == 0, false);
    559 
    560     /* Create session UI: */
    561     pSession = new UISession(pMachine);
    562     /* Make sure it's prepared: */
    563     if (!pSession->prepare())
    564     {
    565         /* Destroy session UI otherwise: */
    566         destroy(pSession);
    567         /* False in that case: */
    568         return false;
    569     }
    570     /* True by default: */
    571     return true;
    572 }
    573 
    574 /* static */
    575 void UISession::destroy(UISession *&pSession)
    576 {
    577     /* Make sure valid pointer passed: */
    578     AssertReturnVoid(pSession != 0);
    579 
    580     /* Cleanup session UI: */
    581     pSession->cleanup();
    582     /* Destroy session: */
    583     delete pSession;
    584     pSession = 0;
    585 }
    586 
    587 bool UISession::initialize()
    588 {
    589     /* Preprocess initialization: */
    590     if (!preprocessInitialization())
    591         return false;
    592 
    593     /* Notify user about mouse&keyboard auto-capturing: */
    594     if (vboxGlobal().settings().autoCapture())
    595         popupCenter().remindAboutAutoCapture(machineLogic()->activeMachineWindow());
    596 
    597     /* Check if we are in teleportation waiting mode.
    598      * In that case no first run wizard is necessary. */
    599     m_machineState = machine().GetState();
    600     if (   isFirstTimeStarted()
    601         && !((   m_machineState == KMachineState_PoweredOff
    602               || m_machineState == KMachineState_Aborted
    603               || m_machineState == KMachineState_Teleported)
    604              && machine().GetTeleporterEnabled()))
    605     {
    606         UISafePointerWizard pWizard = new UIWizardFirstRun(mainMachineWindow(), machine());
    607         pWizard->prepare();
    608         pWizard->exec();
    609         if (pWizard)
    610             delete pWizard;
    611     }
    612 
    613     /* Apply debug settings from the command line. */
    614     if (!debugger().isNull() && debugger().isOk())
    615     {
    616         if (vboxGlobal().isPatmDisabled())
    617             debugger().SetPATMEnabled(false);
    618         if (vboxGlobal().isCsamDisabled())
    619             debugger().SetCSAMEnabled(false);
    620         if (vboxGlobal().isSupervisorCodeExecedRecompiled())
    621             debugger().SetRecompileSupervisor(true);
    622         if (vboxGlobal().isUserCodeExecedRecompiled())
    623             debugger().SetRecompileUser(true);
    624         if (vboxGlobal().areWeToExecuteAllInIem())
    625             debugger().SetExecuteAllInIEM(true);
    626         if (!vboxGlobal().isDefaultWarpPct())
    627             debugger().SetVirtualTimeRate(vboxGlobal().getWarpPct());
    628     }
    629 
    630     /* Power UP if this is NOT separate process: */
    631     if (!vboxGlobal().isSeparateProcess())
    632         if (!powerUp())
    633             return false;
    634 
    635     /* Check if we missed a really quick termination after successful startup: */
    636     if (isTurnedOff())
    637         return false;
    638 
    639     /* Postprocess initialization: */
    640     if (!postprocessInitialization())
    641         return false;
    642 
    643     /* Fetch corresponding states: */
    644     if (vboxGlobal().isSeparateProcess())
    645     {
    646         m_fIsMouseSupportsAbsolute = mouse().GetAbsoluteSupported();
    647         m_fIsMouseSupportsRelative = mouse().GetRelativeSupported();
    648         m_fIsMouseSupportsMultiTouch = mouse().GetMultiTouchSupported();
    649         m_fIsMouseHostCursorNeeded = mouse().GetNeedsHostCursor();
    650         sltAdditionsChange();
    651     }
    652     machineLogic()->initializePostPowerUp();
    653 
    654 #ifdef VBOX_WITH_VIDEOHWACCEL
    655     /* Log whether 2D video acceleration is enabled: */
    656     LogRel(("2D video acceleration is %s.\n",
    657            machine().GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()
    658            ? "enabled" : "disabled"));
    659 #endif /* VBOX_WITH_VIDEOHWACCEL */
    660 
    661 /* Log whether HID LEDs sync is enabled: */
    662 #if defined(Q_WS_MAC) || defined(Q_WS_WIN)
    663     LogRel(("HID LEDs sync is %s.\n",
    664             uimachine()->machineLogic()->isHidLedsSyncEnabled()
    665             ? "enabled" : "disabled"));
    666 #else /* !Q_WS_MAC && !Q_WS_WIN */
    667     LogRel(("HID LEDs sync is not supported on this platform.\n"));
    668 #endif /* !Q_WS_MAC && !Q_WS_WIN */
    669 
    670 #ifdef VBOX_GUI_WITH_PIDFILE
    671     vboxGlobal().createPidfile();
    672 #endif /* VBOX_GUI_WITH_PIDFILE */
    673 
    674     /* Warn listeners about we are initialized: */
    675     emit sigInitialized();
    676 
    677     /* True by default: */
    678     return true;
    679 }
    680 
    681 bool UISession::powerUp()
    682 {
    683     /* Prepare map of the encrypted ids: */
    684     EncryptedMediumsMap encryptedPasswordIds;
    685     foreach (const CMediumAttachment &attachment, machine().GetMediumAttachments())
    686     {
    687         /* Acquire hard-drives only: */
    688         if (attachment.GetType() == KDeviceType_HardDisk)
    689         {
    690             /* Get attachment medium: */
    691             const CMedium medium = attachment.GetMedium();
    692             /* Append our map if this medium has encryption: */
    693             const QString strKeyId = medium.GetProperty("CRYPT/KeyId");
    694             if (!strKeyId.isNull())
    695                 encryptedPasswordIds.insert(strKeyId, medium.GetId());
    696         }
    697     }
    698     /* Ask for disk encryption passwords if necessary: */
    699     EncryptionPasswordsMap encryptionPasswords;
    700     if (!encryptedPasswordIds.isEmpty())
    701     {
    702         QPointer<UIAddDiskEncryptionPasswordDialog> pDlg =
    703              new UIAddDiskEncryptionPasswordDialog(machineLogic()->activeMachineWindow(),
    704                                                    encryptedPasswordIds);
    705         if (pDlg->exec() == QDialog::Accepted)
    706             encryptionPasswords = pDlg->encryptionPasswords();
    707         if (pDlg)
    708             delete pDlg;
    709     }
    710 
    711     /* Power UP machine: */
    712 #ifdef VBOX_WITH_DEBUGGER_GUI
    713     CProgress progress = vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled() ?
    714                          console().PowerUpPaused() : console().PowerUp();
    715 #else /* !VBOX_WITH_DEBUGGER_GUI */
    716     CProgress progress = console().PowerUp();
    717 #endif /* !VBOX_WITH_DEBUGGER_GUI */
    718 
    719     /* Check for immediate failure: */
    720     if (!console().isOk() || progress.isNull())
    721     {
    722         if (vboxGlobal().showStartVMErrors())
    723             msgCenter().cannotStartMachine(console(), machineName());
    724         return false;
    725     }
    726 
    727     /* Guard progressbar warnings from auto-closing: */
    728     if (uimachine()->machineLogic())
    729         uimachine()->machineLogic()->setPreventAutoClose(true);
    730 
    731     /* Show "Starting/Restoring" progress dialog: */
    732     if (isSaved())
    733     {
    734         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_state_restore_90px.png", 0, 0);
    735         /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
    736         machineLogic()->adjustMachineWindowsGeometry();
    737     }
    738     else
    739         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_start_90px.png");
    740 
    741     /* Check for progress failure: */
    742     if (!progress.isOk() || progress.GetResultCode() != 0)
    743     {
    744         if (vboxGlobal().showStartVMErrors())
    745             msgCenter().cannotStartMachine(progress, machineName());
    746         return false;
    747     }
    748 
    749     /* Add the disk encryption passwords: */
    750     if (!encryptionPasswords.isEmpty())
    751     {
    752         foreach (const QString &strKey, encryptionPasswords.keys())
    753         {
    754             console().AddDiskEncryptionPassword(strKey, encryptionPasswords.value(strKey), true);
    755             if (!console().isOk())
    756                 msgCenter().cannotAddDiskEncryptionPassword(console());
    757         }
    758     }
    759 
    760     /* Allow further auto-closing: */
    761     if (uimachine()->machineLogic())
    762         uimachine()->machineLogic()->setPreventAutoClose(false);
    763 
    764     /* True by default: */
    765     return true;
    766 }
    767 
    768 bool UISession::saveState()
    769 {
    770     /* Prepare the saving progress: */
    771     CProgress progress = console().SaveState();
    772     if (console().isOk())
    773     {
    774         /* Show the saving progress: */
    775         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_state_save_90px.png");
    776         if (!progress.isOk() || progress.GetResultCode() != 0)
    777         {
    778             /* Failed in progress: */
    779             msgCenter().cannotSaveMachineState(progress, machineName());
    780             return false;
    781         }
    782     }
    783     else
    784     {
    785         /* Failed in console: */
    786         msgCenter().cannotSaveMachineState(console());
    787         return false;
    788     }
    789     /* Passed: */
    790     return true;
    791 }
    792 
    793 bool UISession::shutdown()
    794 {
    795     /* Send ACPI shutdown signal if possible: */
    796     console().PowerButton();
    797     if (!console().isOk())
    798     {
    799         /* Failed in console: */
    800         msgCenter().cannotACPIShutdownMachine(console());
    801         return false;
    802     }
    803     /* Passed: */
    804     return true;
    805 }
    806 
    807 bool UISession::powerOff(bool fIncludingDiscard, bool &fServerCrashed)
    808 {
    809     /* Prepare the power-off progress: */
    810     CProgress progress = console().PowerDown();
    811     if (console().isOk())
    812     {
    813         /* Show the power-off progress: */
    814         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_poweroff_90px.png");
    815         if (progress.isOk() && progress.GetResultCode() == 0)
    816         {
    817             /* Discard the current state if requested: */
    818             if (fIncludingDiscard)
    819                 return restoreCurrentSnapshot();
    820         }
    821         else
    822         {
    823             /* Failed in progress: */
    824             msgCenter().cannotPowerDownMachine(progress, machineName());
    825             return false;
    826         }
    827     }
    828     else
    829     {
    830         /* Check the machine state, it might be already gone: */
    831         if (!console().isNull())
    832         {
    833            /* Failed in console: */
    834            COMResult res(console());
    835            /* This can happen if VBoxSVC is not running: */
    836            if (FAILED_DEAD_INTERFACE(res.rc()))
    837                fServerCrashed = true;
    838            else
    839                msgCenter().cannotPowerDownMachine(console());
    840            return false;
    841         }
    842     }
    843     /* Passed: */
    844     return true;
    845 }
    846 
    847 bool UISession::restoreCurrentSnapshot()
    848 {
    849     /* Prepare result: */
    850     bool fResult = false;
    851 
    852     /* Simulate try-catch block: */
    853     do
    854     {
    855         /* Search for corresponding VM: */
    856         CVirtualBox vbox = vboxGlobal().virtualBox();
    857         const QString strMachineID = vboxGlobal().managedVMUuid();
    858         const CMachine mach = vbox.FindMachine(strMachineID);
    859         if (!vbox.isOk() || mach.isNull())
    860         {
    861             /* Unable to find VM: */
    862             msgCenter().cannotFindMachineById(vbox, strMachineID);
    863             break;
    864         }
    865 
    866         /* Open a direct session to modify that VM: */
    867         CSession sess = vboxGlobal().openSession(vboxGlobal().managedVMUuid(),
    868                                                  vboxGlobal().isSeparateProcess()
    869                                                  ? KLockType_Write : KLockType_Shared);
    870         if (sess.isNull())
    871         {
    872             /* Unable to open session: */
    873             break;
    874         }
    875 
    876         /* Simulate try-catch block: */
    877         do
    878         {
    879             /* Acquire console for this session: */
    880             CConsole cons = sess.GetConsole();
    881             if (cons.isNull())
    882             {
    883                 /* Unable to acquire console: */
    884                 break;
    885             }
    886 
    887             /* Prepare the snapshot-discard progress: */
    888             const CSnapshot snap = mach.GetCurrentSnapshot();
    889             CProgress prog = cons.RestoreSnapshot(snap);
    890             if (!cons.isOk() || prog.isNull())
    891             {
    892                 /* Unable to restore snapshot: */
    893                 msgCenter().cannotRestoreSnapshot(cons, snap.GetName(), machineName());
    894                 break;
    895             }
    896 
    897             /* Show the snapshot-discard progress: */
    898             msgCenter().showModalProgressDialog(prog, mach.GetName(), ":/progress_snapshot_discard_90px.png");
    899             if (prog.GetResultCode() != 0)
    900             {
    901                 /* Unable to restore snapshot: */
    902                 msgCenter().cannotRestoreSnapshot(prog, snap.GetName(), mach.GetName());
    903                 break;
    904             }
    905 
    906             /* Success: */
    907             fResult = true;
    908         }
    909         while (0);
    910 
    911         /* Unlock machine finally: */
    912         sess.UnlockMachine();
    913     }
    914     while (0);
    915 
    916     /* Return result: */
    917     return fResult;
    918 }
    919 
    920 void UISession::closeRuntimeUI()
    921 {
    922     /* Start corresponding slot asynchronously: */
    923     emit sigCloseRuntimeUI();
    924 }
    925 
    926 UIMachineLogic* UISession::machineLogic() const
    927 {
    928     return uimachine() ? uimachine()->machineLogic() : 0;
    929 }
    930 
    931 QWidget* UISession::mainMachineWindow() const
    932 {
    933     return machineLogic() ? machineLogic()->mainMachineWindow() : 0;
    934 }
    935 
    936 bool UISession::isVisualStateAllowed(UIVisualStateType state) const
    937 {
    938     return m_pMachine->isVisualStateAllowed(state);
    939 }
    940 
    941 void UISession::changeVisualState(UIVisualStateType visualStateType)
    942 {
    943     m_pMachine->asyncChangeVisualState(visualStateType);
    944 }
    945 
    946 bool UISession::setPause(bool fOn)
    947 {
    948     if (fOn)
    949         console().Pause();
    950     else
    951         console().Resume();
    952 
    953     bool ok = console().isOk();
    954     if (!ok)
    955     {
    956         if (fOn)
    957             msgCenter().cannotPauseMachine(console());
    958         else
    959             msgCenter().cannotResumeMachine(console());
    960     }
    961 
    962     return ok;
    963 }
    964 
    965 void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
    966 {
    967     /* This flag indicates whether we want to do the usual .ISO mounting or not.
    968      * First try updating the Guest Additions directly without mounting the .ISO. */
    969     bool fDoMount = false;
    970 
    971     /* Auto-update in GUI currently is disabled. */
    972 #ifndef VBOX_WITH_ADDITIONS_AUTOUPDATE_UI
    973     fDoMount = true;
    974 #else /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
    975     QVector<KAdditionsUpdateFlag> aFlagsUpdate;
    976     QVector<QString> aArgs;
    977     CProgress progressInstall = guest().UpdateGuestAdditions(strSource,
    978                                                              aArgs, aFlagsUpdate);
    979     bool fResult = guest().isOk();
    980     if (fResult)
    981     {
    982         msgCenter().showModalProgressDialog(progressInstall, tr("Updating Guest Additions"),
    983                                             ":/progress_install_guest_additions_90px.png",
    984                                             0, 500 /* 500ms delay. */);
    985         if (progressInstall.GetCanceled())
    986             return;
    987 
    988         HRESULT rc = progressInstall.GetResultCode();
    989         if (!progressInstall.isOk() || rc != S_OK)
    990         {
    991             /* If we got back a VBOX_E_NOT_SUPPORTED we don't complain (guest OS
    992              * simply isn't supported yet), so silently fall back to "old" .ISO
    993              * mounting method. */
    994             if (   !SUCCEEDED_WARNING(rc)
    995                 && rc != VBOX_E_NOT_SUPPORTED)
    996             {
    997                 msgCenter().cannotUpdateGuestAdditions(progressInstall);
    998 
    999                 /* Log the error message in the release log. */
    1000                 QString strErr = progressInstall.GetErrorInfo().GetText();
    1001                 if (!strErr.isEmpty())
    1002                     LogRel(("%s\n", strErr.toLatin1().constData()));
    1003             }
    1004             fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
    1005         }
    1006     }
    1007 #endif /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
    1008 
    1009     /* Do we still want mounting? */
    1010     if (!fDoMount)
    1011         return;
    1012 
    1013     /* Open corresponding medium: */
    1014     QString strMediumID;
    1015     CVirtualBox vbox = vboxGlobal().virtualBox();
    1016     CMedium image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
    1017     if (vbox.isOk() && !image.isNull())
    1018         strMediumID = image.GetId();
    1019     else
    1020     {
    1021         msgCenter().cannotOpenMedium(vbox, UIMediumType_DVD, strSource, mainMachineWindow());
    1022         return;
    1023     }
    1024 
    1025     /* Make sure GA medium ID is valid: */
    1026     AssertReturnVoid(!strMediumID.isNull());
    1027 
    1028     /* Searching for the first suitable controller/slot: */
    1029     QString strControllerName;
    1030     LONG iCntPort = -1, iCntDevice = -1;
    1031     foreach (const CStorageController &controller, machine().GetStorageControllers())
    1032     {
    1033         foreach (const CMediumAttachment &attachment, machine().GetMediumAttachmentsOfController(controller.GetName()))
    1034         {
    1035             if (attachment.GetType() == KDeviceType_DVD)
    1036             {
    1037                 strControllerName = controller.GetName();
    1038                 iCntPort = attachment.GetPort();
    1039                 iCntDevice = attachment.GetDevice();
    1040                 break;
    1041             }
    1042         }
    1043         if (!strControllerName.isNull())
    1044             break;
    1045     }
    1046 
    1047     /* Make sure suitable controller/slot were found: */
    1048     if (strControllerName.isNull())
    1049     {
    1050         msgCenter().cannotMountGuestAdditions(machineName());
    1051         return;
    1052     }
    1053 
    1054     /* Try to find UIMedium among cached: */
    1055     UIMedium medium = vboxGlobal().medium(strMediumID);
    1056     if (medium.isNull())
    1057     {
    1058         /* Create new one if necessary: */
    1059         medium = UIMedium(image, UIMediumType_DVD, KMediumState_Created);
    1060         vboxGlobal().createMedium(medium);
    1061     }
    1062 
    1063     /* Mount medium to corresponding controller/slot: */
    1064     machine().MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), false /* force */);
    1065     if (!machine().isOk())
    1066     {
    1067         /* Ask for force mounting: */
    1068         if (msgCenter().cannotRemountMedium(machine(), medium, true /* mount? */,
    1069                                             true /* retry? */, mainMachineWindow()))
    1070         {
    1071             /* Force mount medium to the predefined port/device: */
    1072             machine().MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), true /* force */);
    1073             if (!machine().isOk())
    1074                 msgCenter().cannotRemountMedium(machine(), medium, true /* mount? */,
    1075                                                 false /* retry? */, mainMachineWindow());
    1076         }
    1077     }
    1078 }
    1079 
    1080 void UISession::sltCloseRuntimeUI()
    1081 {
    1082     /* First, we have to hide any opened modal/popup widgets.
    1083      * They then should unlock their event-loops synchronously.
    1084      * If all such loops are unlocked, we can close Runtime UI: */
    1085     if (QWidget *pWidget = QApplication::activeModalWidget() ?
    1086                            QApplication::activeModalWidget() :
    1087                            QApplication::activePopupWidget() ?
    1088                            QApplication::activePopupWidget() : 0)
    1089     {
    1090         /* First we should try to close this widget: */
    1091         pWidget->close();
    1092         /* If widget rejected the 'close-event' we can
    1093          * still hide it and hope it will behave correctly
    1094          * and unlock his event-loop if any: */
    1095         if (!pWidget->isHidden())
    1096             pWidget->hide();
    1097         /* Restart this slot: */
    1098         emit sigCloseRuntimeUI();
    1099         return;
    1100     }
    1101 
    1102     /* Finally close the Runtime UI: */
    1103     UIMachine::destroy();
    1104 }
    1105 
    1106 #ifdef RT_OS_DARWIN
    1107 void UISession::sltHandleMenuBarConfigurationChange(const QString &strMachineID)
    1108 {
    1109     /* Skip unrelated machine IDs: */
    1110     if (vboxGlobal().managedVMUuid() != strMachineID)
    1111         return;
    1112 
    1113     /* Update Mac OS X menu-bar: */
    1114     updateMenu();
    1115 }
    1116 #endif /* RT_OS_DARWIN */
    1117 
    1118 void UISession::sltMousePointerShapeChange(bool fVisible, bool fAlpha, QPoint hotCorner, QSize size, QVector<uint8_t> shape)
    1119 {
    1120     /* In case of shape data is present: */
    1121     if (shape.size() > 0)
    1122     {
    1123         /* We are ignoring visibility flag: */
    1124         m_fIsHidingHostPointer = false;
    1125 
    1126         /* And updating current cursor shape: */
    1127         setPointerShape(shape.data(), fAlpha,
    1128                         hotCorner.x(), hotCorner.y(),
    1129                         size.width(), size.height());
    1130     }
    1131     /* In case of shape data is NOT present: */
    1132     else
    1133     {
    1134         /* Remember if we should hide the cursor: */
    1135         m_fIsHidingHostPointer = !fVisible;
    1136     }
    1137 
    1138     /* Notify listeners about mouse capability changed: */
    1139     emit sigMousePointerShapeChange();
    1140 
    1141 }
    1142 
    1143 void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative, bool fSupportsMultiTouch, bool fNeedsHostCursor)
    1144 {
    1145     LogRelFlow(("UISession::sltMouseCapabilityChange: "
    1146                 "Supports absolute: %s, Supports relative: %s, "
    1147                 "Supports multi-touch: %s, Needs host cursor: %s\n",
    1148                 fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
    1149                 fSupportsMultiTouch ? "TRUE" : "FALSE", fNeedsHostCursor ? "TRUE" : "FALSE"));
    1150 
    1151     /* Check if something had changed: */
    1152     if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
    1153         || m_fIsMouseSupportsRelative != fSupportsRelative
    1154         || m_fIsMouseSupportsMultiTouch != fSupportsMultiTouch
    1155         || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
    1156     {
    1157         /* Store new data: */
    1158         m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
    1159         m_fIsMouseSupportsRelative = fSupportsRelative;
    1160         m_fIsMouseSupportsMultiTouch = fSupportsMultiTouch;
    1161         m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
    1162 
    1163         /* Notify listeners about mouse capability changed: */
    1164         emit sigMouseCapabilityChange();
    1165     }
    1166 }
    1167 
    1168 void UISession::sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
    1169 {
    1170     /* Check if something had changed: */
    1171     if (   m_fNumLock != fNumLock
    1172         || m_fCapsLock != fCapsLock
    1173         || m_fScrollLock != fScrollLock)
    1174     {
    1175         /* Store new num lock data: */
    1176         if (m_fNumLock != fNumLock)
    1177         {
    1178             m_fNumLock = fNumLock;
    1179             m_uNumLockAdaptionCnt = 2;
    1180         }
    1181 
    1182         /* Store new caps lock data: */
    1183         if (m_fCapsLock != fCapsLock)
    1184         {
    1185             m_fCapsLock = fCapsLock;
    1186             m_uCapsLockAdaptionCnt = 2;
    1187         }
    1188 
    1189         /* Store new scroll lock data: */
    1190         if (m_fScrollLock != fScrollLock)
    1191         {
    1192             m_fScrollLock = fScrollLock;
    1193         }
    1194 
    1195         /* Notify listeners about mouse capability changed: */
    1196         emit sigKeyboardLedsChange();
    1197     }
    1198 }
    1199 
    1200 void UISession::sltStateChange(KMachineState state)
    1201 {
    1202     /* Check if something had changed: */
    1203     if (m_machineState != state)
    1204     {
    1205         /* Store new data: */
    1206         m_machineStatePrevious = m_machineState;
    1207         m_machineState = state;
    1208 
    1209         /* Notify listeners about machine state changed: */
    1210         emit sigMachineStateChange();
    1211     }
    1212 }
    1213 
    1214 void UISession::sltVRDEChange()
    1215 {
    1216     /* Make sure VRDE server is present: */
    1217     const CVRDEServer server = machine().GetVRDEServer();
    1218     AssertMsgReturnVoid(machine().isOk() && !server.isNull(),
    1219                         ("VRDE server should NOT be null!\n"));
    1220 
    1221     /* Check/Uncheck VRDE Server action depending on feature status: */
    1222     actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->blockSignals(true);
    1223     actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->setChecked(server.GetEnabled());
    1224     actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->blockSignals(false);
    1225 
    1226     /* Notify listeners about VRDE change: */
    1227     emit sigVRDEChange();
    1228 }
    1229 
    1230 void UISession::sltVideoCaptureChange()
    1231 {
    1232     /* Check/Uncheck Video Capture action depending on feature status: */
    1233     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->blockSignals(true);
    1234     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->setChecked(machine().GetVideoCaptureEnabled());
    1235     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->blockSignals(false);
    1236 
    1237     /* Notify listeners about Video Capture change: */
    1238     emit sigVideoCaptureChange();
    1239 }
    1240 
    1241 void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
    1242 {
    1243     /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
    1244     if (changeType == KGuestMonitorChangedEventType_NewOrigin)
    1245         return;
    1246     /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
    1247     AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
    1248     if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
    1249         return;
    1250 
    1251     /* Process KGuestMonitorChangedEventType_Enabled change event: */
    1252     if (   !isScreenVisible(uScreenId)
    1253         && changeType == KGuestMonitorChangedEventType_Enabled)
    1254         setScreenVisible(uScreenId, true);
    1255     /* Process KGuestMonitorChangedEventType_Disabled change event: */
    1256     else if (   isScreenVisible(uScreenId)
    1257              && changeType == KGuestMonitorChangedEventType_Disabled)
    1258         setScreenVisible(uScreenId, false);
    1259 
    1260     /* Notify listeners about the change: */
    1261     emit sigGuestMonitorChange(changeType, uScreenId, screenGeo);
    1262 }
    1263 
    1264 #ifdef RT_OS_DARWIN
    1265 /**
    1266  * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
    1267  * @note Watchdog is trying to determine display reconfiguration in
    1268  *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
    1269  */
    1270 void UISession::sltHandleHostDisplayAboutToChange()
    1271 {
    1272     LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
    1273 
    1274     if (m_pWatchdogDisplayChange->isActive())
    1275         m_pWatchdogDisplayChange->stop();
    1276     m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
    1277     m_pWatchdogDisplayChange->start();
    1278 }
    1279 
    1280 /**
    1281  * MacOS X: Determines display reconfiguration.
    1282  * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
    1283  * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
    1284  */
    1285 void UISession::sltCheckIfHostDisplayChanged()
    1286 {
    1287     LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
    1288 
    1289     /* Acquire desktop wrapper: */
    1290     QDesktopWidget *pDesktop = QApplication::desktop();
    1291 
    1292     /* Check if display count changed: */
    1293     if (pDesktop->screenCount() != m_hostScreens.size())
    1294     {
    1295         /* Reset watchdog: */
    1296         m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    1297         /* Notify listeners about screen-count changed: */
    1298         return sltHandleHostScreenCountChange();
    1299     }
    1300     else
    1301     {
    1302         /* Check if at least one display geometry changed: */
    1303         for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
    1304         {
    1305             if (pDesktop->screenGeometry(iScreenIndex) != m_hostScreens.at(iScreenIndex))
    1306             {
    1307                 /* Reset watchdog: */
    1308                 m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    1309                 /* Notify listeners about screen-geometry changed: */
    1310                 return sltHandleHostScreenGeometryChange();
    1311             }
    1312         }
    1313     }
    1314 
    1315     /* Check if watchdog expired, restart if not: */
    1316     int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
    1317     if (cTryNumber > 0 && cTryNumber < 40)
    1318     {
    1319         /* Restart watchdog again: */
    1320         m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
    1321         m_pWatchdogDisplayChange->start();
    1322     }
    1323     else
    1324     {
    1325         /* Reset watchdog: */
    1326         m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    1327     }
    1328 }
    1329 #endif /* RT_OS_DARWIN */
    1330 
    1331 void UISession::sltHandleHostScreenCountChange()
    1332 {
    1333     LogRelFlow(("UISession: Host-screen count changed.\n"));
    1334 
    1335     /* Recache display data: */
    1336     updateHostScreenData();
    1337 
    1338     /* Notify current machine-logic: */
    1339     emit sigHostScreenCountChange();
    1340 }
    1341 
    1342 void UISession::sltHandleHostScreenGeometryChange()
    1343 {
    1344     LogRelFlow(("UISession: Host-screen geometry changed.\n"));
    1345 
    1346     /* Recache display data: */
    1347     updateHostScreenData();
    1348 
    1349     /* Notify current machine-logic: */
    1350     emit sigHostScreenGeometryChange();
    1351 }
    1352 
    1353 void UISession::sltHandleHostScreenAvailableAreaChange()
    1354 {
    1355     LogRelFlow(("UISession: Host-screen available-area changed.\n"));
    1356 
    1357     /* Notify current machine-logic: */
    1358     emit sigHostScreenAvailableAreaChange();
    1359 }
    1360 
    1361 void UISession::sltAdditionsChange()
    1362 {
    1363     /* Variable flags: */
    1364     ULONG ulGuestAdditionsRunLevel = guest().GetAdditionsRunLevel();
    1365     LONG64 lLastUpdatedIgnored;
    1366     bool fIsGuestSupportsGraphics = guest().GetFacilityStatus(KAdditionsFacilityType_Graphics, lLastUpdatedIgnored)
    1367                                     == KAdditionsFacilityStatus_Active;
    1368     bool fIsGuestSupportsSeamless = guest().GetFacilityStatus(KAdditionsFacilityType_Seamless, lLastUpdatedIgnored)
    1369                                     == KAdditionsFacilityStatus_Active;
    1370     /* Check if something had changed: */
    1371     if (m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel ||
    1372         m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
    1373         m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
    1374     {
    1375         /* Store new data: */
    1376         m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
    1377         m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
    1378         m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
    1379 
    1380         /* Notify listeners about guest additions state really changed: */
    1381         emit sigAdditionsStateActualChange();
    1382     }
    1383 
    1384     /* Notify listeners about guest additions state event came: */
    1385     emit sigAdditionsStateChange();
    1386 }
    1387 
    1388 UISession::UISession(UIMachine *pMachine)
    1389     : QObject(pMachine)
    1390     /* Base variables: */
    1391     , m_pMachine(pMachine)
    1392     , m_pActionPool(0)
    1393 #ifdef Q_WS_MAC
    1394     , m_pMenuBar(0)
    1395 #endif /* Q_WS_MAC */
    1396     /* Common variables: */
    1397     , m_machineStatePrevious(KMachineState_Null)
    1398     , m_machineState(KMachineState_Null)
    1399 #ifndef Q_WS_MAC
    1400     , m_pMachineWindowIcon(0)
    1401 #endif /* !Q_WS_MAC */
    1402     , m_mouseCapturePolicy(MouseCapturePolicy_Default)
    1403     , m_guruMeditationHandlerType(GuruMeditationHandlerType_Default)
    1404     , m_hiDPIOptimizationType(HiDPIOptimizationType_None)
    1405     , m_requestedVisualStateType(UIVisualStateType_Invalid)
    1406 #ifdef Q_WS_WIN
    1407     , m_alphaCursor(0)
    1408 #endif /* Q_WS_WIN */
    1409 #ifdef Q_WS_MAC
    1410     , m_pWatchdogDisplayChange(0)
    1411 #endif /* Q_WS_MAC */
    1412     , m_defaultCloseAction(MachineCloseAction_Invalid)
    1413     , m_restrictedCloseActions(MachineCloseAction_Invalid)
    1414     , m_fAllCloseActionsRestricted(false)
    1415     /* Common flags: */
    1416     , m_fInitialized(false)
    1417     , m_fIsFirstTimeStarted(false)
    1418     , m_fIsGuestResizeIgnored(false)
    1419     , m_fIsAutoCaptureDisabled(false)
    1420     /* Guest additions flags: */
    1421     , m_ulGuestAdditionsRunLevel(0)
    1422     , m_fIsGuestSupportsGraphics(false)
    1423     , m_fIsGuestSupportsSeamless(false)
    1424     /* Mouse flags: */
    1425     , m_fNumLock(false)
    1426     , m_fCapsLock(false)
    1427     , m_fScrollLock(false)
    1428     , m_uNumLockAdaptionCnt(2)
    1429     , m_uCapsLockAdaptionCnt(2)
    1430     /* Mouse flags: */
    1431     , m_fIsMouseSupportsAbsolute(false)
    1432     , m_fIsMouseSupportsRelative(false)
    1433     , m_fIsMouseSupportsMultiTouch(false)
    1434     , m_fIsMouseHostCursorNeeded(false)
    1435     , m_fIsMouseCaptured(false)
    1436     , m_fIsMouseIntegrated(true)
    1437     , m_fIsValidPointerShapePresent(false)
    1438     , m_fIsHidingHostPointer(true)
    1439 {
    1440 }
    1441 
    1442 UISession::~UISession()
    1443 {
    1444 }
    1445 
    1446 bool UISession::prepare()
    1447 {
    1448     /* Prepare session: */
    1449     if (!prepareSession())
    1450         return false;
    1451 
    1452     /* Prepare actions: */
    1453     prepareActions();
    1454 
    1455     /* Prepare connections: */
    1456     prepareConnections();
    1457 
    1458     /* Prepare console event-handlers: */
    1459     prepareConsoleEventHandlers();
    1460 
    1461     /* Prepare screens: */
    1462     prepareScreens();
    1463 
    1464     /* Prepare framebuffers: */
    1465     prepareFramebuffers();
    1466 
    1467     /* Load settings: */
    1468     loadSessionSettings();
    1469 
    1470 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    1471     struct sigaction sa;
    1472     sa.sa_sigaction = &signalHandlerSIGUSR1;
    1473     sigemptyset(&sa.sa_mask);
    1474     sa.sa_flags = SA_RESTART | SA_SIGINFO;
    1475     sigaction(SIGUSR1, &sa, NULL);
    1476 #endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    1477 
    1478     /* True by default: */
    1479     return true;
    1480 }
    1481 
    1482 bool UISession::prepareSession()
    1483 {
    1484     /* Open session: */
    1485     m_session = vboxGlobal().openSession(vboxGlobal().managedVMUuid(),
    1486                                          vboxGlobal().isSeparateProcess()
    1487                                          ? KLockType_Shared : KLockType_VM);
    1488     if (m_session.isNull())
    1489         return false;
    1490 
    1491     /* Get machine: */
    1492     m_machine = m_session.GetMachine();
    1493     if (m_machine.isNull())
    1494         return false;
    1495 
    1496     /* Get console: */
    1497     m_console = m_session.GetConsole();
    1498     if (m_console.isNull())
    1499         return false;
    1500 
    1501     /* Get display: */
    1502     m_display = m_console.GetDisplay();
    1503     if (m_display.isNull())
    1504         return false;
    1505 
    1506     /* Get guest: */
    1507     m_guest = m_console.GetGuest();
    1508     if (m_guest.isNull())
    1509         return false;
    1510 
    1511     /* Get mouse: */
    1512     m_mouse = m_console.GetMouse();
    1513     if (m_mouse.isNull())
    1514         return false;
    1515 
    1516     /* Get keyboard: */
    1517     m_keyboard = m_console.GetKeyboard();
    1518     if (m_keyboard.isNull())
    1519         return false;
    1520 
    1521     /* Get debugger: */
    1522     m_debugger = m_console.GetDebugger();
    1523     if (m_debugger.isNull())
    1524         return false;
    1525 
    1526     /* Update machine-name: */
    1527     m_strMachineName = machine().GetName();
    1528 
    1529     /* Update machine-state: */
    1530     m_machineState = machine().GetState();
    1531 
    1532     /* True by default: */
    1533     return true;
    1534 }
    1535 
    1536 void UISession::prepareActions()
    1537 {
    1538     /* Create action-pool: */
    1539     m_pActionPool = UIActionPool::create(UIActionPoolType_Runtime);
    1540     AssertPtrReturnVoid(actionPool());
    1541     {
    1542         /* Configure action-pool: */
    1543         actionPool()->toRuntime()->setSession(this);
    1544 
    1545         /* Get host: */
    1546         const CHost host = vboxGlobal().host();
    1547         UIExtraDataMetaDefs::RuntimeMenuViewActionType restrictionForView = UIExtraDataMetaDefs::RuntimeMenuViewActionType_Invalid;
    1548         UIExtraDataMetaDefs::RuntimeMenuDevicesActionType restrictionForDevices = UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Invalid;
    1549 
    1550         /* VRDE server stuff: */
    1551         {
    1552             /* Initialize 'View' menu: */
    1553             const CVRDEServer server = machine().GetVRDEServer();
    1554             if (server.isNull())
    1555                 restrictionForView = (UIExtraDataMetaDefs::RuntimeMenuViewActionType)(restrictionForView | UIExtraDataMetaDefs::RuntimeMenuViewActionType_VRDEServer);
    1556         }
    1557 
    1558         /* Storage stuff: */
    1559         {
    1560             /* Initialize CD/FD menus: */
    1561             int iDevicesCountCD = 0;
    1562             int iDevicesCountFD = 0;
    1563             foreach (const CMediumAttachment &attachment, machine().GetMediumAttachments())
    1564             {
    1565                 if (attachment.GetType() == KDeviceType_DVD)
    1566                     ++iDevicesCountCD;
    1567                 if (attachment.GetType() == KDeviceType_Floppy)
    1568                     ++iDevicesCountFD;
    1569             }
    1570             QAction *pOpticalDevicesMenu = actionPool()->action(UIActionIndexRT_M_Devices_M_OpticalDevices);
    1571             QAction *pFloppyDevicesMenu = actionPool()->action(UIActionIndexRT_M_Devices_M_FloppyDevices);
    1572             pOpticalDevicesMenu->setData(iDevicesCountCD);
    1573             pFloppyDevicesMenu->setData(iDevicesCountFD);
    1574             if (!iDevicesCountCD)
    1575                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_OpticalDevices);
    1576             if (!iDevicesCountFD)
    1577                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_FloppyDevices);
    1578         }
    1579 
    1580         /* Network stuff: */
    1581         {
    1582             /* Initialize Network menu: */
    1583             bool fAtLeastOneAdapterActive = false;
    1584             const KChipsetType chipsetType = machine().GetChipsetType();
    1585             ULONG uSlots = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(chipsetType);
    1586             for (ULONG uSlot = 0; uSlot < uSlots; ++uSlot)
    1587             {
    1588                 const CNetworkAdapter &adapter = machine().GetNetworkAdapter(uSlot);
    1589                 if (adapter.GetEnabled())
    1590                 {
    1591                     fAtLeastOneAdapterActive = true;
    1592                     break;
    1593                 }
    1594             }
    1595             if (!fAtLeastOneAdapterActive)
    1596                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Network);
    1597         }
    1598 
    1599         /* USB stuff: */
    1600         {
    1601             /* Check whether there is at least one USB controller with an available proxy. */
    1602             const bool fUSBEnabled =    !machine().GetUSBDeviceFilters().isNull()
    1603                                      && !machine().GetUSBControllers().isEmpty()
    1604                                      && machine().GetUSBProxyAvailable();
    1605             if (!fUSBEnabled)
    1606                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_USBDevices);
    1607         }
    1608 
    1609         /* WebCams stuff: */
    1610         {
    1611             /* Check whether there is an accessible video input devices pool: */
    1612             host.GetVideoInputDevices();
    1613             const bool fWebCamsEnabled = host.isOk() && !machine().GetUSBControllers().isEmpty();
    1614             if (!fWebCamsEnabled)
    1615                 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_WebCams);
    1616         }
    1617 
    1618         /* Apply cumulative restriction for 'View' menu: */
    1619         actionPool()->toRuntime()->setRestrictionForMenuView(UIActionRestrictionLevel_Session, restrictionForView);
    1620         /* Apply cumulative restriction for 'Devices' menu: */
    1621         actionPool()->toRuntime()->setRestrictionForMenuDevices(UIActionRestrictionLevel_Session, restrictionForDevices);
    1622 
    1623 #ifdef Q_WS_MAC
    1624         /* Create Mac OS X menu-bar: */
    1625         m_pMenuBar = new UIMenuBar;
    1626         AssertPtrReturnVoid(m_pMenuBar);
    1627         {
    1628             /* Configure Mac OS X menu-bar: */
    1629             connect(gEDataManager, SIGNAL(sigMenuBarConfigurationChange(const QString&)),
    1630                     this, SLOT(sltHandleMenuBarConfigurationChange(const QString&)));
    1631             /* Update Mac OS X menu-bar: */
    1632             updateMenu();
    1633         }
    1634 #endif /* Q_WS_MAC */
    1635     }
    1636 }
    1637 
    1638 void UISession::prepareConnections()
    1639 {
    1640     connect(this, SIGNAL(sigInitialized()), this, SLOT(sltMarkInitialized()));
    1641     connect(this, SIGNAL(sigCloseRuntimeUI()), this, SLOT(sltCloseRuntimeUI()));
    1642 
    1643 #ifdef Q_WS_MAC
    1644     /* Install native display reconfiguration callback: */
    1645     CGDisplayRegisterReconfigurationCallback(cgDisplayReconfigurationCallback, this);
    1646 #else /* !Q_WS_MAC */
    1647     /* Install Qt display reconfiguration callbacks: */
    1648     connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)),
    1649             this, SLOT(sltHandleHostScreenCountChange()));
    1650     connect(QApplication::desktop(), SIGNAL(resized(int)),
    1651             this, SLOT(sltHandleHostScreenGeometryChange()));
    1652     connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
    1653             this, SLOT(sltHandleHostScreenAvailableAreaChange()));
    1654 #endif /* !Q_WS_MAC */
    1655 }
    1656 
    1657 void UISession::prepareConsoleEventHandlers()
    1658 {
    1659     /* Create console event-handler: */
    1660     UIConsoleEventHandler::create(this);
    1661 
    1662     /* Add console event connections: */
    1663     connect(gConsoleEvents, SIGNAL(sigMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)),
    1664             this, SLOT(sltMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)));
    1665 
    1666     connect(gConsoleEvents, SIGNAL(sigMouseCapabilityChange(bool, bool, bool, bool)),
    1667             this, SLOT(sltMouseCapabilityChange(bool, bool, bool, bool)));
    1668 
    1669     connect(gConsoleEvents, SIGNAL(sigKeyboardLedsChangeEvent(bool, bool, bool)),
    1670             this, SLOT(sltKeyboardLedsChangeEvent(bool, bool, bool)));
    1671 
    1672     connect(gConsoleEvents, SIGNAL(sigStateChange(KMachineState)),
    1673             this, SLOT(sltStateChange(KMachineState)));
    1674 
    1675     connect(gConsoleEvents, SIGNAL(sigAdditionsChange()),
    1676             this, SLOT(sltAdditionsChange()));
    1677 
    1678     connect(gConsoleEvents, SIGNAL(sigVRDEChange()),
    1679             this, SLOT(sltVRDEChange()));
    1680 
    1681     connect(gConsoleEvents, SIGNAL(sigVideoCaptureChange()),
    1682             this, SLOT(sltVideoCaptureChange()));
    1683 
    1684     connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
    1685             this, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)));
    1686 
    1687     connect(gConsoleEvents, SIGNAL(sigMediumChange(CMediumAttachment)),
    1688             this, SIGNAL(sigMediumChange(CMediumAttachment)));
    1689 
    1690     connect(gConsoleEvents, SIGNAL(sigUSBControllerChange()),
    1691             this, SIGNAL(sigUSBControllerChange()));
    1692 
    1693     connect(gConsoleEvents, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)),
    1694             this, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)));
    1695 
    1696     connect(gConsoleEvents, SIGNAL(sigSharedFolderChange()),
    1697             this, SIGNAL(sigSharedFolderChange()));
    1698 
    1699     connect(gConsoleEvents, SIGNAL(sigRuntimeError(bool, QString, QString)),
    1700             this, SIGNAL(sigRuntimeError(bool, QString, QString)));
    1701 
    1702 #ifdef Q_WS_MAC
    1703     connect(gConsoleEvents, SIGNAL(sigShowWindow()),
    1704             this, SIGNAL(sigShowWindows()), Qt::QueuedConnection);
    1705 #endif /* Q_WS_MAC */
    1706 
    1707     connect(gConsoleEvents, SIGNAL(sigCPUExecutionCapChange()),
    1708             this, SIGNAL(sigCPUExecutionCapChange()));
    1709 
    1710     connect(gConsoleEvents, SIGNAL(sigGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)),
    1711             this, SLOT(sltGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)));
    1712 }
    1713 
    1714 void UISession::prepareScreens()
    1715 {
    1716     /* Recache display data: */
    1717     updateHostScreenData();
    1718 
    1719 #ifdef Q_WS_MAC
    1720     /* Prepare display-change watchdog: */
    1721     m_pWatchdogDisplayChange = new QTimer(this);
    1722     {
    1723         m_pWatchdogDisplayChange->setInterval(500);
    1724         m_pWatchdogDisplayChange->setSingleShot(true);
    1725         connect(m_pWatchdogDisplayChange, SIGNAL(timeout()),
    1726                 this, SLOT(sltCheckIfHostDisplayChanged()));
    1727     }
    1728 #endif /* Q_WS_MAC */
    1729 
    1730     /* Prepare initial screen visibility status: */
    1731     m_monitorVisibilityVector.resize(machine().GetMonitorCount());
    1732     m_monitorVisibilityVector.fill(false);
    1733     m_monitorVisibilityVector[0] = true;
    1734 
    1735     /* If machine is in 'saved' state: */
    1736     if (isSaved())
    1737     {
    1738         /* Update screen visibility status from saved-state: */
    1739         for (int iScreenIndex = 0; iScreenIndex < m_monitorVisibilityVector.size(); ++iScreenIndex)
    1740         {
    1741             BOOL fEnabled = true;
    1742             ULONG uGuestOriginX = 0, uGuestOriginY = 0, uGuestWidth = 0, uGuestHeight = 0;
    1743             machine().QuerySavedGuestScreenInfo(iScreenIndex,
    1744                                                 uGuestOriginX, uGuestOriginY,
    1745                                                 uGuestWidth, uGuestHeight, fEnabled);
    1746             m_monitorVisibilityVector[iScreenIndex] = fEnabled;
    1747         }
    1748         /* And make sure at least one of them is visible (primary if others are hidden): */
    1749         if (countOfVisibleWindows() < 1)
    1750             m_monitorVisibilityVector[0] = true;
    1751     }
    1752     else if (vboxGlobal().isSeparateProcess())
    1753     {
    1754         /* Update screen visibility status from display directly: */
    1755         for (int iScreenIndex = 0; iScreenIndex < m_monitorVisibilityVector.size(); ++iScreenIndex)
    1756         {
    1757             KGuestMonitorStatus enmStatus = KGuestMonitorStatus_Disabled;
    1758             ULONG uGuestWidth = 0, uGuestHeight = 0, uBpp = 0;
    1759             LONG iGuestOriginX = 0, iGuestOriginY = 0;
    1760             display().GetScreenResolution(iScreenIndex,
    1761                                           uGuestWidth, uGuestHeight, uBpp,
    1762                                           iGuestOriginX, iGuestOriginY, enmStatus);
    1763             m_monitorVisibilityVector[iScreenIndex] = (enmStatus == KGuestMonitorStatus_Enabled);
    1764         }
    1765         /* And make sure at least one of them is visible (primary if others are hidden): */
    1766         if (countOfVisibleWindows() < 1)
    1767             m_monitorVisibilityVector[0] = true;
    1768     }
    1769 }
    1770 
    1771 void UISession::prepareFramebuffers()
    1772 {
    1773     /* Each framebuffer will be really prepared on first UIMachineView creation: */
    1774     m_frameBufferVector.resize(machine().GetMonitorCount());
    1775 }
    1776 
    1777 void UISession::loadSessionSettings()
    1778 {
    1779     /* Load extra-data settings: */
    1780     {
    1781         /* Get machine ID: */
    1782         const QString strMachineID = vboxGlobal().managedVMUuid();
    1783 
    1784 #ifndef Q_WS_MAC
    1785         /* Load/prepare user's machine-window icon: */
    1786         QIcon icon;
    1787         foreach (const QString &strIconName, gEDataManager->machineWindowIconNames(strMachineID))
    1788             if (!strIconName.isEmpty())
    1789                 icon.addFile(strIconName);
    1790         if (!icon.isNull())
    1791             m_pMachineWindowIcon = new QIcon(icon);
    1792 
    1793         /* Load user's machine-window name postfix: */
    1794         m_strMachineWindowNamePostfix = gEDataManager->machineWindowNamePostfix(strMachineID);
    1795 #endif /* !Q_WS_MAC */
    1796 
    1797         /* Determine mouse-capture policy: */
    1798         m_mouseCapturePolicy = gEDataManager->mouseCapturePolicy(strMachineID);
    1799 
    1800         /* Determine Guru Meditation handler type: */
    1801         m_guruMeditationHandlerType = gEDataManager->guruMeditationHandlerType(strMachineID);
    1802 
    1803         /* Determine HiDPI optimization type: */
    1804         m_hiDPIOptimizationType = gEDataManager->hiDPIOptimizationType(strMachineID);
    1805 
    1806         /* Is there should be First RUN Wizard? */
    1807         m_fIsFirstTimeStarted = gEDataManager->machineFirstTimeStarted(strMachineID);
    1808 
    1809         /* Should guest autoresize? */
    1810         QAction *pGuestAutoresizeSwitch = actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize);
    1811         pGuestAutoresizeSwitch->setChecked(gEDataManager->guestScreenAutoResizeEnabled(strMachineID));
    1812 
    1813 #ifndef Q_WS_MAC
    1814         /* Menu-bar options: */
    1815         {
    1816             const bool fEnabledGlobally = !vboxGlobal().settings().isFeatureActive("noMenuBar");
    1817             const bool fEnabledForMachine = gEDataManager->menuBarEnabled(strMachineID);
    1818             const bool fEnabled = fEnabledGlobally && fEnabledForMachine;
    1819             QAction *pActionMenuBarSettings = actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_S_Settings);
    1820             pActionMenuBarSettings->setEnabled(fEnabled);
    1821             QAction *pActionMenuBarSwitch = actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_T_Visibility);
    1822             pActionMenuBarSwitch->blockSignals(true);
    1823             pActionMenuBarSwitch->setChecked(fEnabled);
    1824             pActionMenuBarSwitch->blockSignals(false);
    1825         }
    1826 #endif /* !Q_WS_MAC */
    1827 
    1828         /* Status-bar options: */
    1829         {
    1830             const bool fEnabledGlobally = !vboxGlobal().settings().isFeatureActive("noStatusBar");
    1831             const bool fEnabledForMachine = gEDataManager->statusBarEnabled(strMachineID);
    1832             const bool fEnabled = fEnabledGlobally && fEnabledForMachine;
    1833             QAction *pActionStatusBarSettings = actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_S_Settings);
    1834             pActionStatusBarSettings->setEnabled(fEnabled);
    1835             QAction *pActionStatusBarSwitch = actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_T_Visibility);
    1836             pActionStatusBarSwitch->blockSignals(true);
    1837             pActionStatusBarSwitch->setChecked(fEnabled);
    1838             pActionStatusBarSwitch->blockSignals(false);
    1839         }
    1840 
    1841         /* Input options: */
    1842         actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration)->setChecked(isMouseIntegrated());
    1843 
    1844         /* What is the default close action and the restricted are? */
    1845         m_defaultCloseAction = gEDataManager->defaultMachineCloseAction(strMachineID);
    1846         m_restrictedCloseActions = gEDataManager->restrictedMachineCloseActions(strMachineID);
    1847         m_fAllCloseActionsRestricted =  (!vboxGlobal().isSeparateProcess() || (m_restrictedCloseActions & MachineCloseAction_Detach))
    1848                                      && (m_restrictedCloseActions & MachineCloseAction_SaveState)
    1849                                      && (m_restrictedCloseActions & MachineCloseAction_Shutdown)
    1850                                      && (m_restrictedCloseActions & MachineCloseAction_PowerOff);
    1851                                      // Close VM Dialog hides PowerOff_RestoringSnapshot implicitly if PowerOff is hidden..
    1852                                      // && (m_restrictedCloseActions & MachineCloseAction_PowerOff_RestoringSnapshot);
    1853     }
    1854 }
    1855 
    1856 void UISession::saveSessionSettings()
    1857 {
    1858     /* Save extra-data settings: */
    1859     {
    1860         /* Disable First RUN Wizard: */
    1861         gEDataManager->setMachineFirstTimeStarted(false, vboxGlobal().managedVMUuid());
    1862 
    1863         /* Remember if guest should autoresize: */
    1864         if (actionPool())
    1865         {
    1866             const QAction *pGuestAutoresizeSwitch = actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize);
    1867             gEDataManager->setGuestScreenAutoResizeEnabled(pGuestAutoresizeSwitch->isChecked(), vboxGlobal().managedVMUuid());
    1868         }
    1869 
    1870 #ifndef Q_WS_MAC
    1871         /* Cleanup user's machine-window icon: */
    1872         delete m_pMachineWindowIcon;
    1873         m_pMachineWindowIcon = 0;
    1874 #endif /* !Q_WS_MAC */
    1875     }
    1876 }
    1877 
    1878 void UISession::cleanupFramebuffers()
    1879 {
    1880     /* Cleanup framebuffers finally: */
    1881     for (int i = m_frameBufferVector.size() - 1; i >= 0; --i)
    1882     {
    1883         UIFrameBuffer *pFrameBuffer = m_frameBufferVector[i];
    1884         if (pFrameBuffer)
    1885         {
    1886             /* Mark framebuffer as unused: */
    1887             pFrameBuffer->setMarkAsUnused(true);
    1888             /* Detach framebuffer from Display: */
    1889             pFrameBuffer->detach();
    1890             /* Delete framebuffer reference: */
    1891             delete pFrameBuffer;
    1892         }
    1893     }
    1894     m_frameBufferVector.clear();
    1895 }
    1896 
    1897 void UISession::cleanupConsoleEventHandlers()
    1898 {
    1899     /* Destroy console event-handler if necessary: */
    1900     if (gConsoleEvents)
    1901         UIConsoleEventHandler::destroy();
    1902 }
    1903 
    1904 void UISession::cleanupConnections()
    1905 {
    1906 #ifdef Q_WS_MAC
    1907     /* Remove display reconfiguration callback: */
    1908     CGDisplayRemoveReconfigurationCallback(cgDisplayReconfigurationCallback, this);
    1909 #endif /* Q_WS_MAC */
    1910 }
    1911 
    1912 void UISession::cleanupActions()
    1913 {
    1914 #ifdef Q_WS_MAC
    1915     /* Destroy Mac OS X menu-bar: */
    1916     delete m_pMenuBar;
    1917     m_pMenuBar = 0;
    1918 #endif /* Q_WS_MAC */
    1919 
    1920     /* Destroy action-pool if necessary: */
    1921     if (actionPool())
    1922         UIActionPool::destroy(actionPool());
    1923 }
    1924 
    1925 void UISession::cleanupSession()
    1926 {
    1927     /* Detach debugger: */
    1928     if (!m_debugger.isNull())
    1929         m_debugger.detach();
    1930 
    1931     /* Detach keyboard: */
    1932     if (!m_keyboard.isNull())
    1933         m_keyboard.detach();
    1934 
    1935     /* Detach mouse: */
    1936     if (!m_mouse.isNull())
    1937         m_mouse.detach();
    1938 
    1939     /* Detach guest: */
    1940     if (!m_guest.isNull())
    1941         m_guest.detach();
    1942 
    1943     /* Detach display: */
    1944     if (!m_display.isNull())
    1945         m_display.detach();
    1946 
    1947     /* Detach console: */
    1948     if (!m_console.isNull())
    1949         m_console.detach();
    1950 
    1951     /* Detach machine: */
    1952     if (!m_machine.isNull())
    1953         m_machine.detach();
    1954 
    1955     /* Close session: */
    1956     if (!m_session.isNull() && vboxGlobal().isVBoxSVCAvailable())
    1957     {
    1958         m_session.UnlockMachine();
    1959         m_session.detach();
    1960     }
    1961 }
    1962 
    1963 void UISession::cleanup()
    1964 {
    1965 #ifdef Q_WS_WIN
    1966     /* Destroy alpha cursor: */
    1967     if (m_alphaCursor)
    1968         DestroyIcon(m_alphaCursor);
    1969 #endif /* Q_WS_WIN */
    1970 
    1971     /* Save settings: */
    1972     saveSessionSettings();
    1973 
    1974     /* Cleanup framebuffers: */
    1975     cleanupFramebuffers();
    1976 
    1977     /* Cleanup console event-handlers: */
    1978     cleanupConsoleEventHandlers();
    1979 
    1980     /* Cleanup connections: */
    1981     cleanupConnections();
    1982 
    1983     /* Cleanup actions: */
    1984     cleanupActions();
    1985 
    1986     /* Cleanup session: */
    1987     cleanupSession();
    1988 }
    1989 
    1990 #ifdef Q_WS_MAC
    1991 void UISession::updateMenu()
    1992 {
    1993     /* Rebuild Mac OS X menu-bar: */
    1994     m_pMenuBar->clear();
    1995     foreach (QMenu *pMenu, actionPool()->menus())
    1996     {
    1997         UIMenu *pMenuUI = qobject_cast<UIMenu*>(pMenu);
    1998         if (!pMenuUI->isConsumable() || !pMenuUI->isConsumed())
    1999             m_pMenuBar->addMenu(pMenuUI);
    2000         if (pMenuUI->isConsumable() && !pMenuUI->isConsumed())
    2001             pMenuUI->setConsumed(true);
    2002     }
    2003 }
    2004 #endif /* Q_WS_MAC */
    2005 
    2006 WId UISession::winId() const
    2007 {
    2008     return mainMachineWindow()->winId();
    2009 }
    2010 
    2011 void UISession::setPointerShape(const uchar *pShapeData, bool fHasAlpha,
    2012                                 uint uXHot, uint uYHot, uint uWidth, uint uHeight)
    2013 {
    2014     AssertMsg(pShapeData, ("Shape data must not be NULL!\n"));
    2015 
    2016     m_fIsValidPointerShapePresent = false;
    2017     const uchar *srcAndMaskPtr = pShapeData;
    2018     uint andMaskSize = (uWidth + 7) / 8 * uHeight;
    2019     const uchar *srcShapePtr = pShapeData + ((andMaskSize + 3) & ~3);
    2020     uint srcShapePtrScan = uWidth * 4;
    2021 
    2022 #if defined (Q_WS_WIN)
    2023 
    2024     BITMAPV5HEADER bi;
    2025     HBITMAP hBitmap;
    2026     void *lpBits;
    2027 
    2028     ::ZeroMemory(&bi, sizeof (BITMAPV5HEADER));
    2029     bi.bV5Size = sizeof(BITMAPV5HEADER);
    2030     bi.bV5Width = uWidth;
    2031     bi.bV5Height = - (LONG)uHeight;
    2032     bi.bV5Planes = 1;
    2033     bi.bV5BitCount = 32;
    2034     bi.bV5Compression = BI_BITFIELDS;
    2035     bi.bV5RedMask   = 0x00FF0000;
    2036     bi.bV5GreenMask = 0x0000FF00;
    2037     bi.bV5BlueMask  = 0x000000FF;
    2038     if (fHasAlpha)
    2039         bi.bV5AlphaMask = 0xFF000000;
    2040     else
    2041         bi.bV5AlphaMask = 0;
    2042 
    2043     HDC hdc = GetDC(NULL);
    2044 
    2045     /* Create the DIB section with an alpha channel: */
    2046     hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, (DWORD) 0);
    2047 
    2048     ReleaseDC(NULL, hdc);
    2049 
    2050     HBITMAP hMonoBitmap = NULL;
    2051     if (fHasAlpha)
    2052     {
    2053         /* Create an empty mask bitmap: */
    2054         hMonoBitmap = CreateBitmap(uWidth, uHeight, 1, 1, NULL);
    2055     }
    2056     else
    2057     {
    2058         /* Word aligned AND mask. Will be allocated and created if necessary. */
    2059         uint8_t *pu8AndMaskWordAligned = NULL;
    2060 
    2061         /* Width in bytes of the original AND mask scan line. */
    2062         uint32_t cbAndMaskScan = (uWidth + 7) / 8;
    2063 
    2064         if (cbAndMaskScan & 1)
    2065         {
    2066             /* Original AND mask is not word aligned. */
    2067 
    2068             /* Allocate memory for aligned AND mask. */
    2069             pu8AndMaskWordAligned = (uint8_t *)RTMemTmpAllocZ((cbAndMaskScan + 1) * uHeight);
    2070 
    2071             Assert(pu8AndMaskWordAligned);
    2072 
    2073             if (pu8AndMaskWordAligned)
    2074             {
    2075                 /* According to MSDN the padding bits must be 0.
    2076                  * Compute the bit mask to set padding bits to 0 in the last byte of original AND mask. */
    2077                 uint32_t u32PaddingBits = cbAndMaskScan * 8  - uWidth;
    2078                 Assert(u32PaddingBits < 8);
    2079                 uint8_t u8LastBytesPaddingMask = (uint8_t)(0xFF << u32PaddingBits);
    2080 
    2081                 Log(("u8LastBytesPaddingMask = %02X, aligned w = %d, width = %d, cbAndMaskScan = %d\n",
    2082                       u8LastBytesPaddingMask, (cbAndMaskScan + 1) * 8, uWidth, cbAndMaskScan));
    2083 
    2084                 uint8_t *src = (uint8_t *)srcAndMaskPtr;
    2085                 uint8_t *dst = pu8AndMaskWordAligned;
    2086 
    2087                 unsigned i;
    2088                 for (i = 0; i < uHeight; i++)
    2089                 {
    2090                     memcpy(dst, src, cbAndMaskScan);
    2091 
    2092                     dst[cbAndMaskScan - 1] &= u8LastBytesPaddingMask;
    2093 
    2094                     src += cbAndMaskScan;
    2095                     dst += cbAndMaskScan + 1;
    2096                 }
    2097             }
    2098         }
    2099 
    2100         /* Create the AND mask bitmap: */
    2101         hMonoBitmap = ::CreateBitmap(uWidth, uHeight, 1, 1,
    2102                                      pu8AndMaskWordAligned? pu8AndMaskWordAligned: srcAndMaskPtr);
    2103 
    2104         if (pu8AndMaskWordAligned)
    2105         {
    2106             RTMemTmpFree(pu8AndMaskWordAligned);
    2107         }
    2108     }
    2109 
    2110     Assert(hBitmap);
    2111     Assert(hMonoBitmap);
    2112     if (hBitmap && hMonoBitmap)
    2113     {
    2114         DWORD *dstShapePtr = (DWORD *) lpBits;
    2115 
    2116         for (uint y = 0; y < uHeight; y ++)
    2117         {
    2118             memcpy(dstShapePtr, srcShapePtr, srcShapePtrScan);
    2119             srcShapePtr += srcShapePtrScan;
    2120             dstShapePtr += uWidth;
    2121         }
    2122 
    2123         ICONINFO ii;
    2124         ii.fIcon = FALSE;
    2125         ii.xHotspot = uXHot;
    2126         ii.yHotspot = uYHot;
    2127         ii.hbmMask = hMonoBitmap;
    2128         ii.hbmColor = hBitmap;
    2129 
    2130         HCURSOR hAlphaCursor = CreateIconIndirect(&ii);
    2131         Assert(hAlphaCursor);
    2132         if (hAlphaCursor)
    2133         {
    2134             /* Set the new cursor: */
    2135             m_cursor = QCursor(hAlphaCursor);
    2136             if (m_alphaCursor)
    2137                 DestroyIcon(m_alphaCursor);
    2138             m_alphaCursor = hAlphaCursor;
    2139             m_fIsValidPointerShapePresent = true;
    2140         }
    2141     }
    2142 
    2143     if (hMonoBitmap)
    2144         DeleteObject(hMonoBitmap);
    2145     if (hBitmap)
    2146         DeleteObject(hBitmap);
    2147 
    2148 #elif defined (Q_WS_X11) && !defined (VBOX_WITHOUT_XCURSOR)
    2149 
    2150     XcursorImage *img = XcursorImageCreate(uWidth, uHeight);
    2151     Assert(img);
    2152     if (img)
    2153     {
    2154         img->xhot = uXHot;
    2155         img->yhot = uYHot;
    2156 
    2157         XcursorPixel *dstShapePtr = img->pixels;
    2158 
    2159         for (uint y = 0; y < uHeight; y ++)
    2160         {
    2161             memcpy (dstShapePtr, srcShapePtr, srcShapePtrScan);
    2162 
    2163             if (!fHasAlpha)
    2164             {
    2165                 /* Convert AND mask to the alpha channel: */
    2166                 uchar byte = 0;
    2167                 for (uint x = 0; x < uWidth; x ++)
    2168                 {
    2169                     if (!(x % 8))
    2170                         byte = *(srcAndMaskPtr ++);
    2171                     else
    2172                         byte <<= 1;
    2173 
    2174                     if (byte & 0x80)
    2175                     {
    2176                         /* Linux doesn't support inverted pixels (XOR ops,
    2177                          * to be exact) in cursor shapes, so we detect such
    2178                          * pixels and always replace them with black ones to
    2179                          * make them visible at least over light colors */
    2180                         if (dstShapePtr [x] & 0x00FFFFFF)
    2181                             dstShapePtr [x] = 0xFF000000;
    2182                         else
    2183                             dstShapePtr [x] = 0x00000000;
    2184                     }
    2185                     else
    2186                         dstShapePtr [x] |= 0xFF000000;
    2187                 }
    2188             }
    2189 
    2190             srcShapePtr += srcShapePtrScan;
    2191             dstShapePtr += uWidth;
    2192         }
    2193 
    2194         /* Set the new cursor: */
    2195         m_cursor = QCursor(XcursorImageLoadCursor(QX11Info::display(), img));
    2196         m_fIsValidPointerShapePresent = true;
    2197 
    2198         XcursorImageDestroy(img);
    2199     }
    2200 
    2201 #elif defined(Q_WS_MAC)
    2202 
    2203     /* Create a ARGB image out of the shape data. */
    2204     QImage image  (uWidth, uHeight, QImage::Format_ARGB32);
    2205     const uint8_t* pbSrcMask = static_cast<const uint8_t*> (srcAndMaskPtr);
    2206     unsigned cbSrcMaskLine = RT_ALIGN (uWidth, 8) / 8;
    2207     for (unsigned int y = 0; y < uHeight; ++y)
    2208     {
    2209         for (unsigned int x = 0; x < uWidth; ++x)
    2210         {
    2211            unsigned int color = ((unsigned int*)srcShapePtr)[y*uWidth+x];
    2212            /* If the alpha channel isn't in the shape data, we have to
    2213             * create them from the and-mask. This is a bit field where 1
    2214             * represent transparency & 0 opaque respectively. */
    2215            if (!fHasAlpha)
    2216            {
    2217                if (!(pbSrcMask[x / 8] & (1 << (7 - (x % 8)))))
    2218                    color  |= 0xff000000;
    2219                else
    2220                {
    2221                    /* This isn't quite right, but it's the best we can do I think... */
    2222                    if (color & 0x00ffffff)
    2223                        color = 0xff000000;
    2224                    else
    2225                        color = 0x00000000;
    2226                }
    2227            }
    2228            image.setPixel (x, y, color);
    2229         }
    2230         /* Move one scanline forward. */
    2231         pbSrcMask += cbSrcMaskLine;
    2232     }
    2233 
    2234     /* Set the new cursor: */
    2235     m_cursor = QCursor(QPixmap::fromImage(image), uXHot, uYHot);
    2236     m_fIsValidPointerShapePresent = true;
    2237     NOREF(srcShapePtrScan);
    2238 
    2239 #else
    2240 
    2241 # warning "port me"
    2242 
    2243 #endif
    2244 }
    2245 
    2246 bool UISession::preprocessInitialization()
    2247 {
    2248 #ifdef VBOX_WITH_NETFLT
    2249     /* Skip further checks if VM in saved state */
    2250     if (isSaved())
    2251         return true;
    2252 
    2253     /* Make sure all the attached and enabled network
    2254      * adapters are present on the host. This check makes sense
    2255      * in two cases only - when attachement type is Bridged Network
    2256      * or Host-only Interface. NOTE: Only currently enabled
    2257      * attachement type is checked (incorrect parameters check for
    2258      * currently disabled attachement types is skipped). */
    2259     QStringList failedInterfaceNames;
    2260     QStringList availableInterfaceNames;
    2261 
    2262     /* Create host network interface names list */
    2263     foreach (const CHostNetworkInterface &iface, vboxGlobal().host().GetNetworkInterfaces())
    2264     {
    2265         availableInterfaceNames << iface.GetName();
    2266         availableInterfaceNames << iface.GetShortName();
    2267     }
    2268 
    2269     ulong cCount = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(machine().GetChipsetType());
    2270     for (ulong uAdapterIndex = 0; uAdapterIndex < cCount; ++uAdapterIndex)
    2271     {
    2272         CNetworkAdapter na = machine().GetNetworkAdapter(uAdapterIndex);
    2273 
    2274         if (na.GetEnabled())
    2275         {
    2276             QString strIfName = QString();
    2277 
    2278             /* Get physical network interface name for currently
    2279              * enabled network attachement type */
    2280             switch (na.GetAttachmentType())
    2281             {
    2282                 case KNetworkAttachmentType_Bridged:
    2283                     strIfName = na.GetBridgedInterface();
    2284                     break;
    2285                 case KNetworkAttachmentType_HostOnly:
    2286                     strIfName = na.GetHostOnlyInterface();
    2287                     break;
    2288             }
    2289 
    2290             if (!strIfName.isEmpty() &&
    2291                 !availableInterfaceNames.contains(strIfName))
    2292             {
    2293                 LogFlow(("Found invalid network interface: %s\n", strIfName.toStdString().c_str()));
    2294                 failedInterfaceNames << QString("%1 (adapter %2)").arg(strIfName).arg(uAdapterIndex + 1);
    2295             }
    2296         }
    2297     }
    2298 
    2299     /* Check if non-existent interfaces found */
    2300     if (!failedInterfaceNames.isEmpty())
    2301     {
    2302         if (msgCenter().cannotStartWithoutNetworkIf(machineName(), failedInterfaceNames.join(", ")))
    2303             machineLogic()->openNetworkSettingsDialog();
    2304         else
    2305             return false;
    2306     }
    2307 #endif /* VBOX_WITH_NETFLT */
    2308 
    2309     /* True by default: */
    2310     return true;
    2311 }
    2312 
    2313 bool UISession::postprocessInitialization()
    2314 {
    2315     /* Check if the required virtualization features are active. We get this info only when the session is active. */
    2316     const bool fIs64BitsGuest = vboxGlobal().virtualBox().GetGuestOSType(guest().GetOSTypeId()).GetIs64Bit();
    2317     const bool fRecommendVirtEx = vboxGlobal().virtualBox().GetGuestOSType(guest().GetOSTypeId()).GetRecommendedVirtEx();
    2318     AssertMsg(!fIs64BitsGuest || fRecommendVirtEx, ("Virtualization support missed for 64bit guest!\n"));
    2319     const bool fIsVirtActive = debugger().GetHWVirtExEnabled();
    2320     if (fRecommendVirtEx && !fIsVirtActive)
    2321     {
    2322         /* Check whether vt-x / amd-v supported: */
    2323         bool fVTxAMDVSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
    2324 
    2325         /* Pause VM: */
    2326         setPause(true);
    2327 
    2328         /* Ask the user about further actions: */
    2329         bool fShouldWeClose;
    2330         if (fIs64BitsGuest)
    2331             fShouldWeClose = msgCenter().warnAboutVirtExInactiveFor64BitsGuest(fVTxAMDVSupported);
    2332         else
    2333             fShouldWeClose = msgCenter().warnAboutVirtExInactiveForRecommendedGuest(fVTxAMDVSupported);
    2334 
    2335         /* If user asked to close VM: */
    2336         if (fShouldWeClose)
    2337         {
    2338             /* Prevent auto-closure during power off sequence: */
    2339             machineLogic()->setPreventAutoClose(true);
    2340             /* Power off VM: */
    2341             bool fServerCrashed = false;
    2342             powerOff(false, fServerCrashed);
    2343             return false;
    2344         }
    2345 
    2346         /* Resume VM: */
    2347         setPause(false);
    2348     }
    2349 
    2350     /* True by default: */
    2351     return true;
    2352 }
    2353 
    2354 bool UISession::isScreenVisible(ulong uScreenId) const
    2355 {
    2356     Assert(uScreenId < (ulong)m_monitorVisibilityVector.size());
    2357     return m_monitorVisibilityVector.value((int)uScreenId, false);
    2358 }
    2359 
    2360 void UISession::setScreenVisible(ulong uScreenId, bool fIsMonitorVisible)
    2361 {
    2362     Assert(uScreenId < (ulong)m_monitorVisibilityVector.size());
    2363     if (uScreenId < (ulong)m_monitorVisibilityVector.size())
    2364         m_monitorVisibilityVector[(int)uScreenId] = fIsMonitorVisible;
    2365 }
    2366 
    2367 int UISession::countOfVisibleWindows()
    2368 {
    2369     int cCountOfVisibleWindows = 0;
    2370     for (int i = 0; i < m_monitorVisibilityVector.size(); ++i)
    2371         if (m_monitorVisibilityVector[i])
    2372             ++cCountOfVisibleWindows;
    2373     return cCountOfVisibleWindows;
    2374 }
    2375 
    2376 UIFrameBuffer* UISession::frameBuffer(ulong uScreenId) const
    2377 {
    2378     Assert(uScreenId < (ulong)m_frameBufferVector.size());
    2379     return m_frameBufferVector.value((int)uScreenId, 0);
    2380 }
    2381 
    2382 void UISession::setFrameBuffer(ulong uScreenId, UIFrameBuffer* pFrameBuffer)
    2383 {
    2384     Assert(uScreenId < (ulong)m_frameBufferVector.size());
    2385     if (uScreenId < (ulong)m_frameBufferVector.size())
    2386         m_frameBufferVector[(int)uScreenId] = pFrameBuffer;
    2387 }
    2388 
    2389 void UISession::updateHostScreenData()
    2390 {
    2391     m_hostScreens.clear();
    2392     QDesktopWidget *pDesktop = QApplication::desktop();
    2393     for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
    2394         m_hostScreens << pDesktop->screenGeometry(iScreenIndex);
    2395 }
    2396 
    2397 #ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
    2398 /**
    2399  * Custom signal handler. When switching VTs, we might not get release events
    2400  * for Ctrl-Alt and in case a savestate is performed on the new VT, the VM will
    2401  * be saved with modifier keys stuck. This is annoying enough for introducing
    2402  * this hack.
    2403  */
    2404 /* static */
    2405 static void signalHandlerSIGUSR1(int sig, siginfo_t * /* pInfo */, void * /*pSecret */)
    2406 {
    2407     /* only SIGUSR1 is interesting */
    2408     if (sig == SIGUSR1)
    2409         if (UIMachine *pMachine = vboxGlobal().virtualMachine())
    2410             pMachine->uisession()->machineLogic()->keyboardHandler()->releaseAllPressedKeys();
    2411 }
    2412 #endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    2413 
    2414 #include "UISession.moc"
    2415 
     70#endif /* !___UIAddDiskEncryptionPasswordDialog_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r54732 r54733  
    4444# include "UIFrameBuffer.h"
    4545# include "UISettingsDialogSpecific.h"
     46# include "UIAddDiskEncryptionPasswordDialog.h"
    4647# ifdef VBOX_WITH_VIDEOHWACCEL
    4748#  include "VBoxFBOverlay.h"
     
    8081# endif /* VBOX_WITHOUT_XCURSOR */
    8182#endif /* Q_WS_X11 */
    82 
    83 
    84 /* Qt includes: */
    85 #include <QDialog>
    86 #include <QVBoxLayout>
    87 #include <QLineEdit>
    88 #include <QTableView>
    89 #include <QHeaderView>
    90 #include <QItemEditorFactory>
    91 #include <QAbstractTableModel>
    92 #include <QStandardItemEditorCreator>
    93 /* GUI includes: */
    94 #include "QILabel.h"
    95 #include "QIDialogButtonBox.h"
    96 #include "QIWithRetranslateUI.h"
    97 #include "QIStyledItemDelegate.h"
    98 
    99 /* Type definitions: */
    100 typedef QMap<QString, QString> EncryptionPasswordsMap;
    101 typedef QMultiMap<QString, QString> EncryptedMediumsMap;
    102 
    103 /** Encryption-data table field indexes.
    104   * @todo To be moved into separate file.. */
    105 enum UIEncryptionTableSection
    106 {
    107     UIEncryptionTableSection_Id,
    108     UIEncryptionTableSection_Password,
    109     UIEncryptionTableSection_Max
    110 };
    111 
    112 /** QLineEdit implementation allowing to enter
    113   * disk encryption password for particular password id.
    114   * @todo To be moved into separate file.. */
    115 class UILineEdit : public QLineEdit
    116 {
    117     Q_OBJECT;
    118     Q_PROPERTY(QString password READ password WRITE setPassword USER true);
    119 
    120 signals:
    121 
    122     /** Notifies listener about data should be committed. */
    123     void sigCommitData(QWidget *pThis);
    124 
    125 public:
    126 
    127     /** Constructor.
    128       * @param pParent being passed to the base-class. */
    129     UILineEdit(QWidget *pParent)
    130         : QLineEdit(pParent)
    131     {
    132         /* Prepare: */
    133         prepare();
    134     }
    135 
    136 public slots:
    137 
    138     /** Handles @s strText changes. */
    139     void sltTextChanged(const QString &strText)
    140     {
    141         Q_UNUSED(strText);
    142         /* Commit data to the listener: */
    143         emit sigCommitData(this);
    144     }
    145 
    146 private:
    147 
    148     /** Prepare routine. */
    149     void prepare()
    150     {
    151         /* Set alignment: */
    152         setAlignment(Qt::AlignCenter);
    153         /* Set echo mode: */
    154         setEchoMode(QLineEdit::Password);
    155         /* Listen for the text changes: */
    156         connect(this, SIGNAL(textChanged(const QString&)),
    157                 this, SLOT(sltTextChanged(const QString&)));
    158     }
    159 
    160     /** Returns the password from the editor. */
    161     QString password() const { return QLineEdit::text(); }
    162     /** Defines the @a strPassword to the editor. */
    163     void setPassword(const QString &strPassword) { QLineEdit::setText(strPassword); }
    164 };
    165 
    166 /** QAbstractTableModel implementation reflecting
    167   * disk encryption passwords for particular password ids.
    168   * @todo To be moved into separate file.. */
    169 class UIEncryptionDataModel : public QAbstractTableModel
    170 {
    171     Q_OBJECT;
    172 
    173 public:
    174 
    175     /** Constructor.
    176       * @param pParent          being passed to the base-class,
    177       * @param encryptedMediums contains the lists of medium ids (values) encrypted with passwords with ids (keys). */
    178     UIEncryptionDataModel(QObject *pParent, const EncryptedMediumsMap &encryptedMediums)
    179         : QAbstractTableModel(pParent)
    180         , m_encryptedMediums(encryptedMediums)
    181     {
    182         /* Prepare: */
    183         prepare();
    184     }
    185 
    186     /** Returns encryption passwords. */
    187     EncryptionPasswordsMap encryptionPasswords() const { return m_encryptionPasswords; }
    188 
    189     /** Returns the @a index flags. */
    190     virtual Qt::ItemFlags flags(const QModelIndex &index) const
    191     {
    192         /* Check index validness: */
    193         if (!index.isValid())
    194             return Qt::NoItemFlags;
    195         /* Depending on column index: */
    196         switch (index.column())
    197         {
    198             case UIEncryptionTableSection_Id:       return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    199             case UIEncryptionTableSection_Password: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    200             default: break;
    201         }
    202         /* No flags by default: */
    203         return Qt::NoItemFlags;
    204     }
    205 
    206     /** Returns the row count. Provide optional @a parent instead of root if necessary. */
    207     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
    208     {
    209         Q_UNUSED(parent);
    210         return m_encryptionPasswords.size();
    211     }
    212 
    213     /** Returns the column count. Provide optional @a parent instead of root if necessary. */
    214     virtual int columnCount(const QModelIndex &parent = QModelIndex()) const
    215     {
    216         Q_UNUSED(parent);
    217         return UIEncryptionTableSection_Max;
    218     }
    219 
    220     /** Returns header data for @a iSection, @a orientation and @a iRole. */
    221     virtual QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const
    222     {
    223         /* Check argument validness: */
    224         if (iRole != Qt::DisplayRole || orientation != Qt::Horizontal)
    225             return QVariant();
    226         /* Depending on column index: */
    227         switch (iSection)
    228         {
    229             case UIEncryptionTableSection_Id:       return tr("Password ID");
    230             case UIEncryptionTableSection_Password: return tr("Password");
    231             default: break;
    232         }
    233         /* Null value by default: */
    234         return QVariant();
    235     }
    236 
    237     /** Returns @a index data for @a iRole. */
    238     virtual QVariant data(const QModelIndex &index, int iRole /* = Qt::DisplayRole */) const
    239     {
    240         /* Check index validness: */
    241         if (!index.isValid())
    242             return QVariant();
    243         /* Depending on role: */
    244         switch (iRole)
    245         {
    246             case Qt::DisplayRole:
    247             {
    248                 /* Depending on column index: */
    249                 switch (index.column())
    250                 {
    251                     case UIEncryptionTableSection_Id:
    252                         return m_encryptionPasswords.keys().at(index.row());
    253                     case UIEncryptionTableSection_Password:
    254                         return QString().fill('*', m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row())).size());
    255                     default:
    256                         return QVariant();
    257                 }
    258                 break;
    259             }
    260             case Qt::EditRole:
    261             {
    262                 /* Depending on column index: */
    263                 switch (index.column())
    264                 {
    265                     case UIEncryptionTableSection_Password:
    266                         return m_encryptionPasswords.value(m_encryptionPasswords.keys().at(index.row()));
    267                     default:
    268                         return QVariant();
    269                 }
    270                 break;
    271             }
    272             case Qt::TextAlignmentRole:
    273             {
    274                 /* Depending on column index: */
    275                 switch (index.column())
    276                 {
    277                     case UIEncryptionTableSection_Password:
    278                         return Qt::AlignCenter;
    279                     default: return QVariant();
    280                 }
    281                 break;
    282             }
    283             default:
    284                 break;
    285         }
    286         /* Null value by default: */
    287         return QVariant();
    288     }
    289 
    290     /** Defines @a index data for @a iRole as @a value. */
    291     virtual bool setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole */)
    292     {
    293         /* Check index validness: */
    294         if (!index.isValid())
    295             return false;
    296         /* Check argument validness: */
    297         if (iRole != Qt::EditRole)
    298             return false;
    299         /* Depending on column index: */
    300         switch (index.column())
    301         {
    302             case UIEncryptionTableSection_Password: m_encryptionPasswords[m_encryptionPasswords.keys().at(index.row())] = value.toString(); break;
    303             default: break;
    304         }
    305         /* Nothing to set by default: */
    306         return false;
    307     }
    308 
    309 private:
    310 
    311     /** Prepare routine. */
    312     void prepare()
    313     {
    314         /* Populate the map of passwords. */
    315         foreach (const QString &strPasswordId, m_encryptedMediums.keys())
    316             m_encryptionPasswords.insert(strPasswordId, QString());
    317     }
    318 
    319     /** Holds the encrypted medium map reference. */
    320     const EncryptedMediumsMap &m_encryptedMediums;
    321 
    322     /** Holds the encrypted password id map. */
    323     EncryptionPasswordsMap m_encryptionPasswords;
    324 };
    325 
    326 /** QTableView implementation allowing to enter
    327   * disk encryption passwords for particular password ids.
    328   * @todo To be moved into separate file.. */
    329 class UIEncryptionDataTable : public QTableView
    330 {
    331     Q_OBJECT;
    332 
    333 public:
    334 
    335     /** Constructor.
    336       * @param pParent being passed to the base-class. */
    337     UIEncryptionDataTable(const EncryptedMediumsMap &encryptedMediums)
    338         : m_encryptedMediums(encryptedMediums)
    339         , m_pModelEncryptionData(0)
    340     {
    341         /* Prepare: */
    342         prepare();
    343     }
    344 
    345     /** Returns encryption passwords. */
    346     EncryptionPasswordsMap encryptionPasswords() const
    347     {
    348         AssertPtrReturn(m_pModelEncryptionData, EncryptionPasswordsMap());
    349         return m_pModelEncryptionData->encryptionPasswords();
    350     }
    351 
    352 private:
    353 
    354     /** Prepare routine. */
    355     void prepare()
    356     {
    357         /* Create encryption-data model: */
    358         m_pModelEncryptionData = new UIEncryptionDataModel(this, m_encryptedMediums);
    359         AssertPtrReturnVoid(m_pModelEncryptionData);
    360         {
    361             /* Assign configured model to table: */
    362             setModel(m_pModelEncryptionData);
    363         }
    364 
    365         /* Create item delegate: */
    366         QIStyledItemDelegate *pStyledItemDelegate = new QIStyledItemDelegate(this);
    367         AssertPtrReturnVoid(pStyledItemDelegate);
    368         {
    369             /* Create item editor factory: */
    370             QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    371             AssertPtrReturnVoid(pNewItemEditorFactory);
    372             {
    373                 /* Create item editor creator: */
    374                 QStandardItemEditorCreator<UILineEdit> *pQStringItemEditorCreator = new QStandardItemEditorCreator<UILineEdit>();
    375                 AssertPtrReturnVoid(pQStringItemEditorCreator);
    376                 {
    377                     /* Register UILineEdit as the QString editor: */
    378                     pNewItemEditorFactory->registerEditor(QVariant::String, pQStringItemEditorCreator);
    379                 }
    380                 /* Assign configured item editor factory to table delegate: */
    381                 pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
    382             }
    383             /* Assign configured item delegate to table: */
    384             delete itemDelegate();
    385             setItemDelegate(pStyledItemDelegate);
    386         }
    387 
    388         /* Configure table: */
    389         setTabKeyNavigation(false);
    390         setContextMenuPolicy(Qt::CustomContextMenu);
    391         setSelectionBehavior(QAbstractItemView::SelectRows);
    392         setSelectionMode(QAbstractItemView::SingleSelection);
    393         setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
    394 
    395         /* Configure headers: */
    396         verticalHeader()->hide();
    397         verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));
    398         horizontalHeader()->setStretchLastSection(false);
    399         horizontalHeader()->setResizeMode(UIEncryptionTableSection_Id, QHeaderView::Interactive);
    400         horizontalHeader()->setResizeMode(UIEncryptionTableSection_Password, QHeaderView::Stretch);
    401     }
    402 
    403     /** Holds the encrypted medium map reference. */
    404     const EncryptedMediumsMap &m_encryptedMediums;
    405 
    406     /** Holds the encryption-data model. */
    407     UIEncryptionDataModel *m_pModelEncryptionData;
    408 };
    409 
    410 /** QDialog implementation allowing to enter
    411   * disk encryption passwords for particular password ids.
    412   * @todo To be moved into separate files.. */
    413 class UIAddDiskEncryptionPasswordDialog : public QIWithRetranslateUI<QDialog>
    414 {
    415     Q_OBJECT;
    416 
    417 public:
    418 
    419     /** Constructor.
    420       * @param pParent          being passed to the base-class,
    421       * @param encryptedMediums contains the lists of medium ids (values) encrypted with passwords with ids (keys). */
    422     UIAddDiskEncryptionPasswordDialog(QWidget *pParent, const EncryptedMediumsMap &encryptedMediums)
    423         : QIWithRetranslateUI<QDialog>(pParent)
    424         , m_encryptedMediums(encryptedMediums)
    425         , m_pLabelDescription(0)
    426         , m_pTableEncryptionData(0)
    427     {
    428         /* Prepare: */
    429         prepare();
    430         /* Retranslate: */
    431         retranslateUi();
    432     }
    433 
    434     /** Returns encryption passwords. */
    435     EncryptionPasswordsMap encryptionPasswords() const
    436     {
    437         AssertPtrReturn(m_pTableEncryptionData, EncryptionPasswordsMap());
    438         return m_pTableEncryptionData->encryptionPasswords();
    439     }
    440 
    441 private:
    442 
    443     /** Prepare routine. */
    444     void prepare()
    445     {
    446         /* Create main-layout: */
    447         QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    448         AssertPtrReturnVoid(pMainLayout);
    449         {
    450             /* Create input-layout: */
    451             QVBoxLayout *pInputLayout = new QVBoxLayout;
    452             AssertPtrReturnVoid(pInputLayout);
    453             {
    454                 /* Create description label: */
    455                 m_pLabelDescription = new QILabel;
    456                 m_pLabelDescription->useSizeHintForWidth(450);
    457                 m_pLabelDescription->updateGeometry();
    458                 AssertPtrReturnVoid(m_pLabelDescription);
    459                 {
    460                     /* Configure description label: */
    461                     m_pLabelDescription->setWordWrap(true);
    462                     /* Add label into layout: */
    463                     pInputLayout->addWidget(m_pLabelDescription);
    464                 }
    465                 /* Create encryption-data table: */
    466                 m_pTableEncryptionData = new UIEncryptionDataTable(m_encryptedMediums);
    467                 AssertPtrReturnVoid(m_pTableEncryptionData);
    468                 {
    469                     /* Add label into layout: */
    470                     pInputLayout->addWidget(m_pTableEncryptionData);
    471                 }
    472                 /* Add layout into parent: */
    473                 pMainLayout->addLayout(pInputLayout);
    474             }
    475             /* Create button-box: */
    476             QIDialogButtonBox *pButtonBox = new QIDialogButtonBox;
    477             AssertPtrReturnVoid(pButtonBox);
    478             {
    479                 /* Configure button-box: */
    480                 pButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    481                 connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
    482                 connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
    483                 /* Add button-box into layout: */
    484                 pMainLayout->addWidget(pButtonBox);
    485             }
    486         }
    487     }
    488 
    489     /** Translation routine. */
    490     void retranslateUi()
    491     {
    492         AssertPtrReturnVoid(m_pLabelDescription);
    493         m_pLabelDescription->setText(tr("This virtual machine is password protected. "
    494                                         "Please enter the %n encryption password(s) below.",
    495                                         "This text is never used with n == 0. "
    496                                         "Feel free to drop the %n where possible, "
    497                                         "we only included it because of problems with Qt Linguist "
    498                                         "(but the user can see how many passwords are in the list "
    499                                         "and doesn't need to be told).",
    500                                         m_encryptedMediums.size()));
    501     }
    502 
    503     /** Holds the encrypted medium map reference. */
    504     const EncryptedMediumsMap &m_encryptedMediums;
    505 
    506     /** Holds the description label. */
    507     QILabel *m_pLabelDescription;
    508     /** Holds the encryption-data table. */
    509     UIEncryptionDataTable *m_pTableEncryptionData;
    510 };
    511 
    51283
    51384#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
     
    24121983#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
    24131984
    2414 #include "UISession.moc"
    2415 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette