VirtualBox

Ignore:
Timestamp:
Feb 9, 2023 1:21:53 PM (2 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:10322: Runtime UI: Heavy cleanup for UIMultiScreenLayout class; Quite dangerous in theory.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp

    r98452 r98518  
    2626 */
    2727
    28 /* Qt includes: */
    29 #include <QApplication>
    30 #include <QMenu>
    31 
    3228/* GUI includes: */
    33 #include "UIDefs.h"
     29#include "UIActionPoolRuntime.h"
     30#include "UICommon.h"
     31#include "UIDesktopWidgetWatchdog.h"
     32#include "UIExtraDataManager.h"
     33#include "UIMachine.h"
     34#include "UIMachineLogic.h"
     35#include "UIMessageCenter.h"
    3436#include "UIMultiScreenLayout.h"
    35 #include "UIActionPoolRuntime.h"
    36 #include "UIMachineLogic.h"
    37 #include "UIMachine.h"
    38 #include "UIMessageCenter.h"
    39 #include "UIExtraDataManager.h"
    40 #include "UIDesktopWidgetWatchdog.h"
    41 #include "UICommon.h"
    4237
    4338/* COM includes: */
    4439#include "COMEnums.h"
    45 #include "CSession.h"
    46 #include "CConsole.h"
     40#include "CDisplay.h"
    4741#include "CMachine.h"
    48 #include "CDisplay.h"
    4942#include "CGraphicsAdapter.h"
    5043
     
    5346    : m_pMachineLogic(pMachineLogic)
    5447    , m_cGuestScreens(m_pMachineLogic->machine().GetGraphicsAdapter().GetMonitorCount())
    55     , m_cHostScreens(0)
    56 {
    57     /* Calculate host/guest screen count: */
    58     calculateHostMonitorCount();
    59     calculateGuestScreenCount();
    60 
    61     /* Prpeare connections: */
    62     prepareConnections();
     48    , m_cHostMonitors(0)
     49{
     50    prepare();
     51}
     52
     53bool UIMultiScreenLayout::hasHostScreenForGuestScreen(int iScreenId) const
     54{
     55    return m_screenMap.contains(iScreenId);
     56}
     57
     58int UIMultiScreenLayout::hostScreenForGuestScreen(int iScreenId) const
     59{
     60    return m_screenMap.value(iScreenId, 0);
     61}
     62
     63quint64 UIMultiScreenLayout::memoryRequirements() const
     64{
     65    return memoryRequirements(m_screenMap);
    6366}
    6467
     
    7275    /* Make a pool of available host screens: */
    7376    QList<int> availableScreens;
    74     for (int i = 0; i < m_cHostScreens; ++i)
     77    for (int i = 0; i < m_cHostMonitors; ++i)
    7578        availableScreens << i;
    7679
    7780    /* Load all combinations stored in the settings file.
    7881     * We have to make sure they are valid, which means there have to be unique combinations
    79      * and all guests screens need there own host screen. */
    80     bool fShouldWeAutoMountGuestScreens = gEDataManager->autoMountGuestScreensEnabled(uiCommon().managedVMUuid());
     82     * and all guests screens need there own host-monitor. */
     83    const bool fShouldWeAutoMountGuestScreens = gEDataManager->autoMountGuestScreensEnabled(uiCommon().managedVMUuid());
    8184    LogRel(("GUI: UIMultiScreenLayout::update: GUI/AutomountGuestScreens is %s\n", fShouldWeAutoMountGuestScreens ? "enabled" : "disabled"));
    8285    foreach (int iGuestScreen, m_guestScreens)
     
    9194            iHostScreen = gEDataManager->hostScreenForPassedGuestScreen(iGuestScreen, uiCommon().managedVMUuid());
    9295            /* Revalidate: */
    93             fValid =    iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
     96            fValid =    iHostScreen >= 0 && iHostScreen < m_cHostMonitors /* In the host-monitor bounds? */
    9497                     && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
    9598        }
     
    110113                iHostScreen = UIDesktopWidgetWatchdog::screenNumber(topLeftPosition);
    111114                /* Revalidate: */
    112                 fValid =    iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
     115                fValid =    iHostScreen >= 0 && iHostScreen < m_cHostMonitors /* In the host-monitor bounds? */
    113116                         && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
    114117            }
     
    118121        {
    119122            /* If still not valid, pick the next one
    120              * if there is still available host screen: */
     123             * if there is still available host-monitor: */
    121124            if (!availableScreens.isEmpty())
    122125            {
     
    128131        if (fValid)
    129132        {
    130             /* Register host screen for the guest screen: */
     133            /* Register host-monitor for the guest-screen: */
    131134            m_screenMap.insert(iGuestScreen, iHostScreen);
    132135            /* Remove it from the list of available host screens: */
     
    138141            /* Then we have to disable excessive guest-screen: */
    139142            LogRel(("GUI: UIMultiScreenLayout::update: Disabling excessive guest-screen %d\n", iGuestScreen));
    140             m_pMachineLogic->uimachine()->setScreenVisibleHostDesires(iGuestScreen, false);
    141             m_pMachineLogic->display().SetVideoModeHint(iGuestScreen, false, false, 0, 0, 0, 0, 0, true);
     143            uimachine()->setScreenVisibleHostDesires(iGuestScreen, false);
     144            machineLogic()->display().SetVideoModeHint(iGuestScreen, false, false, 0, 0, 0, 0, 0, true);
    142145        }
    143146    }
     
    160163            /* Try to get previous guest-screen arguments: */
    161164            const int iGuestScreen = m_disabledGuestScreens.at(iGuestScreenIndex);
    162             const QSize guestScreenSize = m_pMachineLogic->uimachine()->guestScreenSize(iGuestScreen);
     165            const QSize guestScreenSize = uimachine()->guestScreenSize(iGuestScreen);
    163166            {
    164167                if (guestScreenSize.width() > 0)
     
    170173            LogRel(("GUI: UIMultiScreenLayout::update: Enabling guest-screen %d with following resolution: %dx%d\n",
    171174                    iGuestScreen, uWidth, uHeight));
    172             m_pMachineLogic->uimachine()->setScreenVisibleHostDesires(iGuestScreen, true);
    173             m_pMachineLogic->display().SetVideoModeHint(iGuestScreen, true, false, 0, 0, uWidth, uHeight, 32, true);
     175            uimachine()->setScreenVisibleHostDesires(iGuestScreen, true);
     176            machineLogic()->display().SetVideoModeHint(iGuestScreen, true, false, 0, 0, uWidth, uHeight, 32, true);
    174177        }
    175178    }
    176179
    177180    /* Make sure action-pool knows whether multi-screen layout has host-screen for guest-screen: */
    178     m_pMachineLogic->actionPool()->toRuntime()->setHostScreenForGuestScreenMap(m_screenMap);
     181    actionPool()->toRuntime()->setHostScreenForGuestScreenMap(m_screenMap);
    179182
    180183    LogRelFlow(("UIMultiScreenLayout::update: Finished!\n"));
     
    188191    calculateHostMonitorCount();
    189192    calculateGuestScreenCount();
     193
    190194    /* Update layout: */
    191195    update();
     
    194198}
    195199
    196 int UIMultiScreenLayout::hostScreenCount() const
    197 {
    198     return m_cHostScreens;
    199 }
    200 
    201 int UIMultiScreenLayout::guestScreenCount() const
    202 {
    203     return m_guestScreens.size();
    204 }
    205 
    206 int UIMultiScreenLayout::hostScreenForGuestScreen(int iScreenId) const
    207 {
    208     return m_screenMap.value(iScreenId, 0);
    209 }
    210 
    211 bool UIMultiScreenLayout::hasHostScreenForGuestScreen(int iScreenId) const
    212 {
    213     return m_screenMap.contains(iScreenId);
    214 }
    215 
    216 quint64 UIMultiScreenLayout::memoryRequirements() const
    217 {
    218     return memoryRequirements(m_screenMap);
    219 }
    220 
    221 void UIMultiScreenLayout::sltHandleScreenLayoutChange(int iRequestedGuestScreen, int iRequestedHostScreen)
     200void UIMultiScreenLayout::sltHandleScreenLayoutChange(int iRequestedGuestScreen, int iRequestedHostMonitor)
    222201{
    223202    /* Search for the virtual screen which is currently displayed on the
    224      * requested host screen. When there is one found, we swap both. */
     203     * requested host-monitor. When there is one found, we swap both. */
    225204    QMap<int,int> tmpMap(m_screenMap);
    226     int iCurrentGuestScreen = tmpMap.key(iRequestedHostScreen, -1);
     205    const int iCurrentGuestScreen = tmpMap.key(iRequestedHostMonitor, -1);
    227206    if (iCurrentGuestScreen != -1 && tmpMap.contains(iRequestedGuestScreen))
    228207        tmpMap.insert(iCurrentGuestScreen, tmpMap.value(iRequestedGuestScreen));
    229208    else
    230209        tmpMap.remove(iCurrentGuestScreen);
    231     tmpMap.insert(iRequestedGuestScreen, iRequestedHostScreen);
     210    tmpMap.insert(iRequestedGuestScreen, iRequestedHostMonitor);
    232211
    233212    /* Check the memory requirements first: */
    234213    bool fSuccess = true;
    235     if (m_pMachineLogic->uimachine()->isGuestSupportsGraphics())
    236     {
    237         quint64 availBits = m_pMachineLogic->machine().GetGraphicsAdapter().GetVRAMSize() * _1M * 8;
    238         quint64 usedBits = memoryRequirements(tmpMap);
    239         fSuccess = availBits >= usedBits;
     214    if (uimachine()->isGuestSupportsGraphics())
     215    {
     216        quint64 uAvailBits = machineLogic()->machine().GetGraphicsAdapter().GetVRAMSize() * _1M * 8;
     217        quint64 uUsedBits = memoryRequirements(tmpMap);
     218        fSuccess = uAvailBits >= uUsedBits;
    240219        if (!fSuccess)
    241220        {
    242221            /* We have too little video memory for the new layout, so say it to the user and revert all the changes: */
    243             if (m_pMachineLogic->visualStateType() == UIVisualStateType_Seamless)
    244                 msgCenter().cannotSwitchScreenInSeamless((((usedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
     222            if (machineLogic()->visualStateType() == UIVisualStateType_Seamless)
     223                msgCenter().cannotSwitchScreenInSeamless((((uUsedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
    245224            else
    246                 fSuccess = msgCenter().cannotSwitchScreenInFullscreen((((usedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
     225                fSuccess = msgCenter().cannotSwitchScreenInFullscreen((((uUsedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
    247226        }
    248227    }
     
    255234
    256235    /* Make sure action-pool knows whether multi-screen layout has host-screen for guest-screen: */
    257     m_pMachineLogic->actionPool()->toRuntime()->setHostScreenForGuestScreenMap(m_screenMap);
     236    actionPool()->toRuntime()->setHostScreenForGuestScreenMap(m_screenMap);
    258237
    259238    /* Save guest-to-host mapping: */
    260     saveScreenMapping();
     239    foreach (const int &iGuestScreen, m_guestScreens)
     240    {
     241        const int iHostScreen = m_screenMap.value(iGuestScreen, -1);
     242        gEDataManager->setHostScreenForPassedGuestScreen(iGuestScreen, iHostScreen, uiCommon().managedVMUuid());
     243    }
    261244
    262245    /* Notifies about layout change: */
     
    264247}
    265248
     249void UIMultiScreenLayout::prepare()
     250{
     251    /* Make sure logic is always set: */
     252    AssertPtrReturnVoid(machineLogic());
     253
     254    /* Recalculate host/guest screen count: */
     255    calculateHostMonitorCount();
     256    calculateGuestScreenCount();
     257
     258    /* Prepare connections: */
     259    prepareConnections();
     260}
     261
     262void UIMultiScreenLayout::prepareConnections()
     263{
     264    /* Connect action-pool: */
     265    connect(actionPool()->toRuntime(), &UIActionPoolRuntime::sigNotifyAboutTriggeringViewScreenRemap,
     266            this, &UIMultiScreenLayout::sltHandleScreenLayoutChange);
     267}
     268
     269UIMachine *UIMultiScreenLayout::uimachine() const
     270{
     271    return machineLogic() ? machineLogic()->uimachine() : 0;
     272}
     273
     274UIActionPool *UIMultiScreenLayout::actionPool() const
     275{
     276    return machineLogic() ? machineLogic()->actionPool() : 0;
     277}
     278
    266279void UIMultiScreenLayout::calculateHostMonitorCount()
    267280{
    268     m_cHostScreens = UIDesktopWidgetWatchdog::screenCount();
     281    m_cHostMonitors = UIDesktopWidgetWatchdog::screenCount();
    269282}
    270283
    271284void UIMultiScreenLayout::calculateGuestScreenCount()
    272285{
    273     /* Enumerate all the guest screens: */
    274286    m_guestScreens.clear();
    275287    m_disabledGuestScreens.clear();
    276288    for (uint iGuestScreen = 0; iGuestScreen < m_cGuestScreens; ++iGuestScreen)
    277         if (m_pMachineLogic->uimachine()->isScreenVisible(iGuestScreen))
     289        if (uimachine()->isScreenVisible(iGuestScreen))
    278290            m_guestScreens << iGuestScreen;
    279291        else
     
    281293}
    282294
    283 void UIMultiScreenLayout::prepareConnections()
    284 {
    285     /* Connect action-pool: */
    286     connect(m_pMachineLogic->actionPool()->toRuntime(), &UIActionPoolRuntime::sigNotifyAboutTriggeringViewScreenRemap,
    287             this, &UIMultiScreenLayout::sltHandleScreenLayoutChange);
    288 }
    289 
    290 void UIMultiScreenLayout::saveScreenMapping()
    291 {
    292     foreach (const int &iGuestScreen, m_guestScreens)
    293     {
    294         const int iHostScreen = m_screenMap.value(iGuestScreen, -1);
    295         gEDataManager->setHostScreenForPassedGuestScreen(iGuestScreen, iHostScreen, uiCommon().managedVMUuid());
    296     }
    297 }
    298 
    299295quint64 UIMultiScreenLayout::memoryRequirements(const QMap<int, int> &screenLayout) const
    300296{
    301     ULONG width = 0;
    302     ULONG height = 0;
    303     ULONG guestBpp = 0;
     297    ULONG uWidth = 0;
     298    ULONG uHeight = 0;
     299    ULONG uGuestBpp = 0;
    304300    LONG xOrigin = 0;
    305301    LONG yOrigin = 0;
    306     quint64 usedBits = 0;
     302    quint64 uUsedBits = 0;
     303    KGuestMonitorStatus enmMonitorStatus = KGuestMonitorStatus_Enabled;
     304    const UIVisualStateType enmVisualStateType = machineLogic()->visualStateType();
    307305    foreach (int iGuestScreen, m_guestScreens)
    308306    {
    309         QRect screen;
    310         if (m_pMachineLogic->visualStateType() == UIVisualStateType_Seamless)
    311             screen = gpDesktop->availableGeometry(screenLayout.value(iGuestScreen, 0));
    312         else
    313             screen = gpDesktop->screenGeometry(screenLayout.value(iGuestScreen, 0));
    314         KGuestMonitorStatus monitorStatus = KGuestMonitorStatus_Enabled;
    315         m_pMachineLogic->display().GetScreenResolution(iGuestScreen, width, height, guestBpp, xOrigin, yOrigin, monitorStatus);
    316         usedBits += screen.width() * /* display width */
    317                     screen.height() * /* display height */
    318                     guestBpp + /* guest bits per pixel */
    319                     _1M * 8; /* current cache per screen - may be changed in future */
    320     }
    321     usedBits += 4096 * 8; /* adapter info */
    322     return usedBits;
    323 }
    324 
     307        /* Make sure corresponding screen is valid: */
     308        const QRect screen = enmVisualStateType == UIVisualStateType_Fullscreen
     309                           ? gpDesktop->screenGeometry(screenLayout.value(iGuestScreen, 0))
     310                           : enmVisualStateType == UIVisualStateType_Seamless
     311                           ? gpDesktop->availableGeometry(screenLayout.value(iGuestScreen, 0))
     312                           : QRect();
     313        AssertReturn(screen.isValid(), 0);
     314
     315        /* Get some useful screen info: */
     316        machineLogic()->display().GetScreenResolution(iGuestScreen, uWidth, uHeight, uGuestBpp,
     317                                                      xOrigin, yOrigin, enmMonitorStatus);
     318        uUsedBits += screen.width() * /* display width */
     319                     screen.height() * /* display height */
     320                     uGuestBpp + /* guest bits per pixel */
     321                     _1M * 8; /* current cache per screen - may be changed in future */
     322    }
     323    uUsedBits += 4096 * 8; /* adapter info */
     324    return uUsedBits;
     325}
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.h

    r98103 r98518  
    3333
    3434/* Qt includes: */
     35#include <QMap>
    3536#include <QObject>
    36 #include <QMap>
    3737
    3838/* Forward declarations: */
     39class UIActionPool;
     40class UIMachine;
    3941class UIMachineLogic;
    40 class QMenu;
    41 class QAction;
    4242
    43 /* Multi-screen layout manager: */
     43/** QObject subclass containing a part of
     44  * machine-logic related to multi-screen layout handling.
     45  * Used in such modes as Full-screen and Seamless. */
    4446class UIMultiScreenLayout : public QObject
    4547{
     
    5355public:
    5456
    55     /* Constructor/destructor: */
     57    /** Constructs multi-screen layout passing @a pMachineLogic to the base-class.
     58      * @param  pMachineLogic  Brings the parent machine-logic reference. */
    5659    UIMultiScreenLayout(UIMachineLogic *pMachineLogic);
    5760
    58     /* API: Update stuff: */
     61    /** Returns whether there is host-monitor suitable for guest-screen with @a iScreenId specified. */
     62    bool hasHostScreenForGuestScreen(int iScreenId) const;
     63    /** Returns a host-monitor suitable for guest-screen with @a iScreenId specified. */
     64    int hostScreenForGuestScreen(int iScreenId) const;
     65
     66    /** Returns video memory requirements for currently cached multi-screen layout. */
     67    quint64 memoryRequirements() const;
     68
     69    /** Updates multi-screen layout on the basis
     70      * of known host/guest screen count. */
    5971    void update();
     72    /** Updates everything.
     73      * Recalculates host/guest screen count
     74      * and calls for update wrapper above. */
    6075    void rebuild();
    61 
    62     /* API: Getters: */
    63     int hostScreenCount() const;
    64     int guestScreenCount() const;
    65     int hostScreenForGuestScreen(int iScreenId) const;
    66     bool hasHostScreenForGuestScreen(int iScreenId) const;
    67     quint64 memoryRequirements() const;
    6876
    6977private slots:
    7078
    71     /* Handler: Screen change stuff: */
    72     void sltHandleScreenLayoutChange(int iRequestedGuestScreen, int iRequestedHostScreen);
     79    /** Handles screen layout change request.
     80      * @param  iRequestedGuestScreen  Brings the index of guest-screen which needs to be mapped to certain host-monitor.
     81      * @param  iRequestedHostMonitor  Brings the index of host-monitor which needs to be mapped to certain guest-screen.*/
     82    void sltHandleScreenLayoutChange(int iRequestedGuestScreen, int iRequestedHostMonitor);
    7383
    7484private:
    7585
    76     /* Helpers: Prepare stuff: */
    77     void calculateHostMonitorCount();
    78     void calculateGuestScreenCount();
     86    /** Prepares everything. */
     87    void prepare();
     88    /** Prepares connections. */
    7989    void prepareConnections();
    8090
    81     /* Other helpers: */
    82     void saveScreenMapping();
     91    /** Returns parent machine-logic reference. */
     92    UIMachineLogic *machineLogic() const { return m_pMachineLogic; }
     93    /** Returns machine UI reference. */
     94    UIMachine *uimachine() const;
     95    /** Returns action-pool reference. */
     96    UIActionPool *actionPool() const;
     97
     98    /** Recalculates host-monitor count. */
     99    void calculateHostMonitorCount();
     100    /** Recalculates guest-screen count. */
     101    void calculateGuestScreenCount();
     102
     103    /** Calculates memory requirements for passed @a screenLayout. */
    83104    quint64 memoryRequirements(const QMap<int, int> &screenLayout) const;
    84105
    85     /* Variables: */
     106    /** Holds the machine-logic reference. */
    86107    UIMachineLogic *m_pMachineLogic;
    87     QList<int> m_guestScreens;
    88     QList<int> m_disabledGuestScreens;
    89     const uint m_cGuestScreens;
    90     int m_cHostScreens;
     108
     109    /** Holds the number of guest-screens. */
     110    const uint  m_cGuestScreens;
     111    /** Holds the number of host-monitors. */
     112    int         m_cHostMonitors;
     113
     114    /** Holds currently cached enabled guest-screens. */
     115    QList<int>  m_guestScreens;
     116    /** Holds currently cached disabled guest-screens. */
     117    QList<int>  m_disabledGuestScreens;
     118
     119    /** Holds the cached screens map.
     120      * The keys used for guest-screens.
     121      * The values used for host-monitors. */
    91122    QMap<int, int> m_screenMap;
    92     QList<QMenu*> m_screenMenuList;
    93123};
    94124
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