Changeset 98518 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Feb 9, 2023 1:21:53 PM (2 years ago)
- 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 26 26 */ 27 27 28 /* Qt includes: */29 #include <QApplication>30 #include <QMenu>31 32 28 /* 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" 34 36 #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"42 37 43 38 /* COM includes: */ 44 39 #include "COMEnums.h" 45 #include "CSession.h" 46 #include "CConsole.h" 40 #include "CDisplay.h" 47 41 #include "CMachine.h" 48 #include "CDisplay.h"49 42 #include "CGraphicsAdapter.h" 50 43 … … 53 46 : m_pMachineLogic(pMachineLogic) 54 47 , 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 53 bool UIMultiScreenLayout::hasHostScreenForGuestScreen(int iScreenId) const 54 { 55 return m_screenMap.contains(iScreenId); 56 } 57 58 int UIMultiScreenLayout::hostScreenForGuestScreen(int iScreenId) const 59 { 60 return m_screenMap.value(iScreenId, 0); 61 } 62 63 quint64 UIMultiScreenLayout::memoryRequirements() const 64 { 65 return memoryRequirements(m_screenMap); 63 66 } 64 67 … … 72 75 /* Make a pool of available host screens: */ 73 76 QList<int> availableScreens; 74 for (int i = 0; i < m_cHost Screens; ++i)77 for (int i = 0; i < m_cHostMonitors; ++i) 75 78 availableScreens << i; 76 79 77 80 /* Load all combinations stored in the settings file. 78 81 * 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()); 81 84 LogRel(("GUI: UIMultiScreenLayout::update: GUI/AutomountGuestScreens is %s\n", fShouldWeAutoMountGuestScreens ? "enabled" : "disabled")); 82 85 foreach (int iGuestScreen, m_guestScreens) … … 91 94 iHostScreen = gEDataManager->hostScreenForPassedGuestScreen(iGuestScreen, uiCommon().managedVMUuid()); 92 95 /* Revalidate: */ 93 fValid = iHostScreen >= 0 && iHostScreen < m_cHost Screens /* In the host screenbounds? */96 fValid = iHostScreen >= 0 && iHostScreen < m_cHostMonitors /* In the host-monitor bounds? */ 94 97 && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */ 95 98 } … … 110 113 iHostScreen = UIDesktopWidgetWatchdog::screenNumber(topLeftPosition); 111 114 /* Revalidate: */ 112 fValid = iHostScreen >= 0 && iHostScreen < m_cHost Screens /* In the host screenbounds? */115 fValid = iHostScreen >= 0 && iHostScreen < m_cHostMonitors /* In the host-monitor bounds? */ 113 116 && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */ 114 117 } … … 118 121 { 119 122 /* If still not valid, pick the next one 120 * if there is still available host screen: */123 * if there is still available host-monitor: */ 121 124 if (!availableScreens.isEmpty()) 122 125 { … … 128 131 if (fValid) 129 132 { 130 /* Register host screen for the guestscreen: */133 /* Register host-monitor for the guest-screen: */ 131 134 m_screenMap.insert(iGuestScreen, iHostScreen); 132 135 /* Remove it from the list of available host screens: */ … … 138 141 /* Then we have to disable excessive guest-screen: */ 139 142 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); 142 145 } 143 146 } … … 160 163 /* Try to get previous guest-screen arguments: */ 161 164 const int iGuestScreen = m_disabledGuestScreens.at(iGuestScreenIndex); 162 const QSize guestScreenSize = m_pMachineLogic->uimachine()->guestScreenSize(iGuestScreen);165 const QSize guestScreenSize = uimachine()->guestScreenSize(iGuestScreen); 163 166 { 164 167 if (guestScreenSize.width() > 0) … … 170 173 LogRel(("GUI: UIMultiScreenLayout::update: Enabling guest-screen %d with following resolution: %dx%d\n", 171 174 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); 174 177 } 175 178 } 176 179 177 180 /* 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); 179 182 180 183 LogRelFlow(("UIMultiScreenLayout::update: Finished!\n")); … … 188 191 calculateHostMonitorCount(); 189 192 calculateGuestScreenCount(); 193 190 194 /* Update layout: */ 191 195 update(); … … 194 198 } 195 199 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) 200 void UIMultiScreenLayout::sltHandleScreenLayoutChange(int iRequestedGuestScreen, int iRequestedHostMonitor) 222 201 { 223 202 /* 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. */ 225 204 QMap<int,int> tmpMap(m_screenMap); 226 int iCurrentGuestScreen = tmpMap.key(iRequestedHostScreen, -1);205 const int iCurrentGuestScreen = tmpMap.key(iRequestedHostMonitor, -1); 227 206 if (iCurrentGuestScreen != -1 && tmpMap.contains(iRequestedGuestScreen)) 228 207 tmpMap.insert(iCurrentGuestScreen, tmpMap.value(iRequestedGuestScreen)); 229 208 else 230 209 tmpMap.remove(iCurrentGuestScreen); 231 tmpMap.insert(iRequestedGuestScreen, iRequestedHost Screen);210 tmpMap.insert(iRequestedGuestScreen, iRequestedHostMonitor); 232 211 233 212 /* Check the memory requirements first: */ 234 213 bool fSuccess = true; 235 if ( m_pMachineLogic->uimachine()->isGuestSupportsGraphics())236 { 237 quint64 availBits = m_pMachineLogic->machine().GetGraphicsAdapter().GetVRAMSize() * _1M * 8;238 quint64 u sedBits = 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; 240 219 if (!fSuccess) 241 220 { 242 221 /* 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((((u sedBits + 7) / 8 + _1M - 1) / _1M) * _1M);222 if (machineLogic()->visualStateType() == UIVisualStateType_Seamless) 223 msgCenter().cannotSwitchScreenInSeamless((((uUsedBits + 7) / 8 + _1M - 1) / _1M) * _1M); 245 224 else 246 fSuccess = msgCenter().cannotSwitchScreenInFullscreen((((u sedBits + 7) / 8 + _1M - 1) / _1M) * _1M);225 fSuccess = msgCenter().cannotSwitchScreenInFullscreen((((uUsedBits + 7) / 8 + _1M - 1) / _1M) * _1M); 247 226 } 248 227 } … … 255 234 256 235 /* 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); 258 237 259 238 /* 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 } 261 244 262 245 /* Notifies about layout change: */ … … 264 247 } 265 248 249 void 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 262 void UIMultiScreenLayout::prepareConnections() 263 { 264 /* Connect action-pool: */ 265 connect(actionPool()->toRuntime(), &UIActionPoolRuntime::sigNotifyAboutTriggeringViewScreenRemap, 266 this, &UIMultiScreenLayout::sltHandleScreenLayoutChange); 267 } 268 269 UIMachine *UIMultiScreenLayout::uimachine() const 270 { 271 return machineLogic() ? machineLogic()->uimachine() : 0; 272 } 273 274 UIActionPool *UIMultiScreenLayout::actionPool() const 275 { 276 return machineLogic() ? machineLogic()->actionPool() : 0; 277 } 278 266 279 void UIMultiScreenLayout::calculateHostMonitorCount() 267 280 { 268 m_cHost Screens = UIDesktopWidgetWatchdog::screenCount();281 m_cHostMonitors = UIDesktopWidgetWatchdog::screenCount(); 269 282 } 270 283 271 284 void UIMultiScreenLayout::calculateGuestScreenCount() 272 285 { 273 /* Enumerate all the guest screens: */274 286 m_guestScreens.clear(); 275 287 m_disabledGuestScreens.clear(); 276 288 for (uint iGuestScreen = 0; iGuestScreen < m_cGuestScreens; ++iGuestScreen) 277 if ( m_pMachineLogic->uimachine()->isScreenVisible(iGuestScreen))289 if (uimachine()->isScreenVisible(iGuestScreen)) 278 290 m_guestScreens << iGuestScreen; 279 291 else … … 281 293 } 282 294 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 299 295 quint64 UIMultiScreenLayout::memoryRequirements(const QMap<int, int> &screenLayout) const 300 296 { 301 ULONG width = 0;302 ULONG height = 0;303 ULONG guestBpp = 0;297 ULONG uWidth = 0; 298 ULONG uHeight = 0; 299 ULONG uGuestBpp = 0; 304 300 LONG xOrigin = 0; 305 301 LONG yOrigin = 0; 306 quint64 usedBits = 0; 302 quint64 uUsedBits = 0; 303 KGuestMonitorStatus enmMonitorStatus = KGuestMonitorStatus_Enabled; 304 const UIVisualStateType enmVisualStateType = machineLogic()->visualStateType(); 307 305 foreach (int iGuestScreen, m_guestScreens) 308 306 { 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 33 33 34 34 /* Qt includes: */ 35 #include <QMap> 35 36 #include <QObject> 36 #include <QMap>37 37 38 38 /* Forward declarations: */ 39 class UIActionPool; 40 class UIMachine; 39 41 class UIMachineLogic; 40 class QMenu;41 class QAction;42 42 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. */ 44 46 class UIMultiScreenLayout : public QObject 45 47 { … … 53 55 public: 54 56 55 /* Constructor/destructor: */ 57 /** Constructs multi-screen layout passing @a pMachineLogic to the base-class. 58 * @param pMachineLogic Brings the parent machine-logic reference. */ 56 59 UIMultiScreenLayout(UIMachineLogic *pMachineLogic); 57 60 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. */ 59 71 void update(); 72 /** Updates everything. 73 * Recalculates host/guest screen count 74 * and calls for update wrapper above. */ 60 75 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;68 76 69 77 private slots: 70 78 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); 73 83 74 84 private: 75 85 76 /* Helpers: Prepare stuff:*/77 void calculateHostMonitorCount();78 void calculateGuestScreenCount();86 /** Prepares everything. */ 87 void prepare(); 88 /** Prepares connections. */ 79 89 void prepareConnections(); 80 90 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. */ 83 104 quint64 memoryRequirements(const QMap<int, int> &screenLayout) const; 84 105 85 /* Variables:*/106 /** Holds the machine-logic reference. */ 86 107 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. */ 91 122 QMap<int, int> m_screenMap; 92 QList<QMenu*> m_screenMenuList;93 123 }; 94 124
Note:
See TracChangeset
for help on using the changeset viewer.