af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync/* $Id$ */
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync/** @file
d34409ad02ea0d28e08a6c4b089a412fdb3b4c9cvboxsync * VBox Qt GUI - UIMultiScreenLayout class implementation.
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync */
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync/*
967ea84c07a4d8a8d89fb846efc0dd5a523d5a85vboxsync * Copyright (C) 2010-2013 Oracle Corporation
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync *
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * available from http://www.virtualbox.org. This file is free software;
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * you can redistribute it and/or modify it under the terms of the GNU
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * General Public License (GPL) as published by the Free Software
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync */
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync#ifdef VBOX_WITH_PRECOMPILED_HEADERS
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include <precomp.h>
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync
8bf8c6b1914c9e7e60b1547888400668f1774497vboxsync/* Qt includes: */
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include <QApplication>
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include <QDesktopWidget>
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include <QMenu>
8bf8c6b1914c9e7e60b1547888400668f1774497vboxsync
8bf8c6b1914c9e7e60b1547888400668f1774497vboxsync/* GUI includes: */
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UIDefs.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UIMultiScreenLayout.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UIActionPoolRuntime.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UIMachineLogic.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UIFrameBuffer.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UISession.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UIMessageCenter.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "UIExtraDataManager.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "VBoxGlobal.h"
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
8bf8c6b1914c9e7e60b1547888400668f1774497vboxsync/* COM includes: */
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "COMEnums.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "CSession.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "CConsole.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "CMachine.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync# include "CDisplay.h"
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
a9b62afc62b28da7a1a77f34259f8013892d9664vboxsync
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsyncUIMultiScreenLayout::UIMultiScreenLayout(UIMachineLogic *pMachineLogic)
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync : m_pMachineLogic(pMachineLogic)
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync{
967ea84c07a4d8a8d89fb846efc0dd5a523d5a85vboxsync /* Calculate host/guest screen count: */
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync calculateHostMonitorCount();
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync calculateGuestScreenCount();
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync}
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsyncvoid UIMultiScreenLayout::update()
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync{
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync LogRelFlow(("UIMultiScreenLayout::update: Started...\n"));
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync /* Clear screen-map initially: */
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync m_screenMap.clear();
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync /* Make a pool of available host screens: */
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync QList<int> availableScreens;
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync for (int i = 0; i < m_cHostScreens; ++i)
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync availableScreens << i;
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync /* Load all combinations stored in the settings file.
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync * We have to make sure they are valid, which means there have to be unique combinations
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync * and all guests screens need there own host screen. */
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync CDisplay display = m_pMachineLogic->session().GetConsole().GetDisplay();
dfb707ebae9a5fbe40ddb781ae54fb396a79dd76vboxsync bool fShouldWeAutoMountGuestScreens = gEDataManager->autoMountGuestScreensEnabled(vboxGlobal().managedVMUuid());
8bca6efc969da4550edd800bdec665b810388fa4vboxsync LogRel(("UIMultiScreenLayout::update: GUI/AutomountGuestScreens is %s.\n", fShouldWeAutoMountGuestScreens ? "enabled" : "disabled"));
de138efba2ebd195de75cc07a0b52a9dbdab9fa5vboxsync QDesktopWidget *pDW = QApplication::desktop();
0555766825ef1f1699618d57768bfe7bdea0ae0fvboxsync foreach (int iGuestScreen, m_guestScreens)
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync {
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Initialize variables: */
249378295da4756ab32709a50a419f902f8e4835vboxsync bool fValid = false;
249378295da4756ab32709a50a419f902f8e4835vboxsync int iHostScreen = -1;
249378295da4756ab32709a50a419f902f8e4835vboxsync
249378295da4756ab32709a50a419f902f8e4835vboxsync if (!fValid)
249378295da4756ab32709a50a419f902f8e4835vboxsync {
249378295da4756ab32709a50a419f902f8e4835vboxsync /* If the user ever selected a combination in the view menu, we have the following entry: */
01c48663538d44988d48d462bfd77f00400c4d4cvboxsync iHostScreen = gEDataManager->hostScreenForPassedGuestScreen(iGuestScreen, vboxGlobal().managedVMUuid());
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Revalidate: */
01c48663538d44988d48d462bfd77f00400c4d4cvboxsync fValid = iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
249378295da4756ab32709a50a419f902f8e4835vboxsync && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
249378295da4756ab32709a50a419f902f8e4835vboxsync }
249378295da4756ab32709a50a419f902f8e4835vboxsync
249378295da4756ab32709a50a419f902f8e4835vboxsync if (!fValid)
de138efba2ebd195de75cc07a0b52a9dbdab9fa5vboxsync {
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Check the position of the guest window in normal mode.
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync * This makes sure that on first use fullscreen/seamless window opens on the same host-screen as the normal window was before.
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync * This even works with multi-screen. The user just have to move all the normal windows to the target host-screens
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync * and they will magically open there in fullscreen/seamless also. */
66cf9089c03fb7cc497bc724c022c4d34985c6e3vboxsync QRect geo = gEDataManager->machineWindowGeometry(UIVisualStateType_Normal, iGuestScreen, vboxGlobal().managedVMUuid());
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync /* If geometry is valid: */
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync if (!geo.isNull())
de138efba2ebd195de75cc07a0b52a9dbdab9fa5vboxsync {
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync /* Get top-left corner position: */
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync QPoint topLeftPosition(geo.topLeft());
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync /* Check which host-screen the position belongs to: */
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync iHostScreen = pDW->screenNumber(topLeftPosition);
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Revalidate: */
f7aceb294f917c0af317644a35e3cf8f78880b65vboxsync fValid = iHostScreen >= 0 && iHostScreen < m_cHostScreens /* In the host screen bounds? */
249378295da4756ab32709a50a419f902f8e4835vboxsync && m_screenMap.key(iHostScreen, -1) == -1; /* Not taken already? */
de138efba2ebd195de75cc07a0b52a9dbdab9fa5vboxsync }
249378295da4756ab32709a50a419f902f8e4835vboxsync }
249378295da4756ab32709a50a419f902f8e4835vboxsync
249378295da4756ab32709a50a419f902f8e4835vboxsync if (!fValid)
249378295da4756ab32709a50a419f902f8e4835vboxsync {
249378295da4756ab32709a50a419f902f8e4835vboxsync /* If still not valid, pick the next one
249378295da4756ab32709a50a419f902f8e4835vboxsync * if there is still available host screen: */
249378295da4756ab32709a50a419f902f8e4835vboxsync if (!availableScreens.isEmpty())
249378295da4756ab32709a50a419f902f8e4835vboxsync {
b7cd916020f507a173c9cdd6c56c4a9a4574640dvboxsync iHostScreen = availableScreens.first();
249378295da4756ab32709a50a419f902f8e4835vboxsync fValid = true;
249378295da4756ab32709a50a419f902f8e4835vboxsync }
249378295da4756ab32709a50a419f902f8e4835vboxsync }
249378295da4756ab32709a50a419f902f8e4835vboxsync
249378295da4756ab32709a50a419f902f8e4835vboxsync if (fValid)
249378295da4756ab32709a50a419f902f8e4835vboxsync {
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Register host screen for the guest screen: */
249378295da4756ab32709a50a419f902f8e4835vboxsync m_screenMap.insert(iGuestScreen, iHostScreen);
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Remove it from the list of available host screens: */
249378295da4756ab32709a50a419f902f8e4835vboxsync availableScreens.removeOne(iHostScreen);
de138efba2ebd195de75cc07a0b52a9dbdab9fa5vboxsync }
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync /* Do we have opinion about what to do with excessive guest-screen? */
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync else if (fShouldWeAutoMountGuestScreens)
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync {
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync /* Then we have to disable excessive guest-screen: */
8bca6efc969da4550edd800bdec665b810388fa4vboxsync LogRel(("UIMultiScreenLayout::update: Disabling excessive guest-screen %d.\n", iGuestScreen));
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync display.SetVideoModeHint(iGuestScreen, false, false, 0, 0, 0, 0, 0);
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync }
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync }
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync /* Are we still have available host-screens
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync * and have opinion about what to do with disabled guest-screens? */
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync if (!availableScreens.isEmpty() && fShouldWeAutoMountGuestScreens)
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync {
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync /* How many excessive host-screens do we have? */
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync int cExcessiveHostScreens = availableScreens.size();
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync /* How many disabled guest-screens do we have? */
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync int cDisabledGuestScreens = m_disabledGuestScreens.size();
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync /* We have to try to enable disabled guest-screens if any: */
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync int cGuestScreensToEnable = qMin(cExcessiveHostScreens, cDisabledGuestScreens);
90b029a822a47e186a5662b05b3813674d3fee5evboxsync UISession *pSession = m_pMachineLogic->uisession();
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync for (int iGuestScreenIndex = 0; iGuestScreenIndex < cGuestScreensToEnable; ++iGuestScreenIndex)
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync {
90b029a822a47e186a5662b05b3813674d3fee5evboxsync /* Defaults: */
90b029a822a47e186a5662b05b3813674d3fee5evboxsync ULONG uWidth = 800;
90b029a822a47e186a5662b05b3813674d3fee5evboxsync ULONG uHeight = 600;
90b029a822a47e186a5662b05b3813674d3fee5evboxsync /* Try to get previous guest-screen arguments: */
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync int iGuestScreen = m_disabledGuestScreens[iGuestScreenIndex];
90b029a822a47e186a5662b05b3813674d3fee5evboxsync if (UIFrameBuffer *pFrameBuffer = pSession->frameBuffer(iGuestScreen))
90b029a822a47e186a5662b05b3813674d3fee5evboxsync {
90b029a822a47e186a5662b05b3813674d3fee5evboxsync if (pFrameBuffer->width() > 0)
90b029a822a47e186a5662b05b3813674d3fee5evboxsync uWidth = pFrameBuffer->width();
90b029a822a47e186a5662b05b3813674d3fee5evboxsync if (pFrameBuffer->height() > 0)
90b029a822a47e186a5662b05b3813674d3fee5evboxsync uHeight = pFrameBuffer->height();
09be45879d8ec763f5d6f19ba000da5a19455b7avboxsync pFrameBuffer->setAutoEnabled(true);
90b029a822a47e186a5662b05b3813674d3fee5evboxsync }
90b029a822a47e186a5662b05b3813674d3fee5evboxsync /* Re-enable guest-screen with proper resolution: */
8bca6efc969da4550edd800bdec665b810388fa4vboxsync LogRel(("UIMultiScreenLayout::update: Enabling guest-screen %d with following resolution: %dx%d.\n",
8bca6efc969da4550edd800bdec665b810388fa4vboxsync iGuestScreen, uWidth, uHeight));
90b029a822a47e186a5662b05b3813674d3fee5evboxsync display.SetVideoModeHint(iGuestScreen, true, false, 0, 0, uWidth, uHeight, 32);
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync }
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync }
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync /* Notifies about layout update: */
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync emit sigScreenLayoutUpdate();
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync LogRelFlow(("UIMultiScreenLayout::update: Finished!\n"));
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync}
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsyncvoid UIMultiScreenLayout::rebuild()
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync{
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync LogRelFlow(("UIMultiScreenLayout::rebuild: Started...\n"));
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync /* Recalculate host/guest screen count: */
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync calculateHostMonitorCount();
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync calculateGuestScreenCount();
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync /* Update layout: */
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync update();
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync
582fa31289b0d5e01ad0020b8cd1e640596a48e0vboxsync LogRelFlow(("UIMultiScreenLayout::rebuild: Finished!\n"));
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync}
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsyncint UIMultiScreenLayout::hostScreenCount() const
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync{
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync return m_cHostScreens;
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync}
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsyncint UIMultiScreenLayout::guestScreenCount() const
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync{
0555766825ef1f1699618d57768bfe7bdea0ae0fvboxsync return m_guestScreens.size();
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync}
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
967ea84c07a4d8a8d89fb846efc0dd5a523d5a85vboxsyncint UIMultiScreenLayout::hostScreenForGuestScreen(int iScreenId) const
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync{
6a7e2ecbbcc452e120a12c6996aee7397c57a9d7vboxsync return m_screenMap.value(iScreenId, 0);
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync}
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsyncbool UIMultiScreenLayout::hasHostScreenForGuestScreen(int iScreenId) const
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync{
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync return m_screenMap.contains(iScreenId);
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync}
e5b078efb3ece1a8718cbab43f4744fd0a6d1ca8vboxsync
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsyncquint64 UIMultiScreenLayout::memoryRequirements() const
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync{
6a7e2ecbbcc452e120a12c6996aee7397c57a9d7vboxsync return memoryRequirements(m_screenMap);
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync}
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsyncvoid UIMultiScreenLayout::sltHandleScreenLayoutChange(int iRequestedGuestScreen, int iRequestedHostScreen)
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync{
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync /* Search for the virtual screen which is currently displayed on the
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync * requested host screen. When there is one found, we swap both. */
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync QMap<int,int> tmpMap(m_screenMap);
b7cd916020f507a173c9cdd6c56c4a9a4574640dvboxsync int iCurrentGuestScreen = tmpMap.key(iRequestedHostScreen, -1);
249378295da4756ab32709a50a419f902f8e4835vboxsync if (iCurrentGuestScreen != -1 && tmpMap.contains(iRequestedGuestScreen))
b7cd916020f507a173c9cdd6c56c4a9a4574640dvboxsync tmpMap.insert(iCurrentGuestScreen, tmpMap.value(iRequestedGuestScreen));
249378295da4756ab32709a50a419f902f8e4835vboxsync else
249378295da4756ab32709a50a419f902f8e4835vboxsync tmpMap.remove(iCurrentGuestScreen);
b7cd916020f507a173c9cdd6c56c4a9a4574640dvboxsync tmpMap.insert(iRequestedGuestScreen, iRequestedHostScreen);
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync /* Check the memory requirements first: */
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync bool fSuccess = true;
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync CMachine machine = m_pMachineLogic->session().GetMachine();
0a2cd044b0d76309f5ff2c89b30c9e2d3a724838vboxsync if (m_pMachineLogic->uisession()->isGuestSupportsGraphics())
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync {
b7cd916020f507a173c9cdd6c56c4a9a4574640dvboxsync quint64 availBits = machine.GetVRAMSize() * _1M * 8;
6a7e2ecbbcc452e120a12c6996aee7397c57a9d7vboxsync quint64 usedBits = memoryRequirements(tmpMap);
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync fSuccess = availBits >= usedBits;
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync if (!fSuccess)
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync {
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync /* We have too little video memory for the new layout, so say it to the user and revert all the changes: */
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync if (m_pMachineLogic->visualStateType() == UIVisualStateType_Seamless)
cb48b678483eed76053da41c3f0f2600eeeed5f4vboxsync msgCenter().cannotSwitchScreenInSeamless((((usedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync else
78100a023b3725c3611e76d104f41f2c2ccfa440vboxsync fSuccess = msgCenter().cannotSwitchScreenInFullscreen((((usedBits + 7) / 8 + _1M - 1) / _1M) * _1M);
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync }
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync }
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Make sure memory requirements matched: */
249378295da4756ab32709a50a419f902f8e4835vboxsync if (!fSuccess)
249378295da4756ab32709a50a419f902f8e4835vboxsync return;
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync
249378295da4756ab32709a50a419f902f8e4835vboxsync /* Swap the maps: */
249378295da4756ab32709a50a419f902f8e4835vboxsync m_screenMap = tmpMap;
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync /* Save guest-to-host mapping: */
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync saveScreenMapping();
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync /* Notifies about layout change: */
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync emit sigScreenLayoutChange();
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync}
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsyncvoid UIMultiScreenLayout::calculateHostMonitorCount()
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync{
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync m_cHostScreens = QApplication::desktop()->screenCount();
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync}
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsyncvoid UIMultiScreenLayout::calculateGuestScreenCount()
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync{
24b149e148cc3fa554adb3225a34b96292d18e9evboxsync /* Get machine: */
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync CMachine machine = m_pMachineLogic->session().GetMachine();
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync /* Enumerate all the guest screens: */
0555766825ef1f1699618d57768bfe7bdea0ae0fvboxsync m_guestScreens.clear();
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync m_disabledGuestScreens.clear();
0555766825ef1f1699618d57768bfe7bdea0ae0fvboxsync for (uint iGuestScreen = 0; iGuestScreen < machine.GetMonitorCount(); ++iGuestScreen)
0555766825ef1f1699618d57768bfe7bdea0ae0fvboxsync if (m_pMachineLogic->uisession()->isScreenVisible(iGuestScreen))
0555766825ef1f1699618d57768bfe7bdea0ae0fvboxsync m_guestScreens << iGuestScreen;
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync else
42c3a43fe0633a05ce009eb9a1e3653ddee65f00vboxsync m_disabledGuestScreens << iGuestScreen;
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync}
ed6ec60d8984cdb1068af0cc3c8b54ef7701b269vboxsync
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsyncvoid UIMultiScreenLayout::saveScreenMapping()
05a789df00b1b166fe2a6ede4562331679ca0c4cvboxsync{
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync foreach (const int &iGuestScreen, m_guestScreens)
05a789df00b1b166fe2a6ede4562331679ca0c4cvboxsync {
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync const int iHostScreen = m_screenMap.value(iGuestScreen, -1);
123cf63fa2d7b42aeea7da2605e3a4971a722dadvboxsync gEDataManager->setHostScreenForPassedGuestScreen(iGuestScreen, iHostScreen, vboxGlobal().managedVMUuid());
05a789df00b1b166fe2a6ede4562331679ca0c4cvboxsync }
05a789df00b1b166fe2a6ede4562331679ca0c4cvboxsync}
05a789df00b1b166fe2a6ede4562331679ca0c4cvboxsync
6a7e2ecbbcc452e120a12c6996aee7397c57a9d7vboxsyncquint64 UIMultiScreenLayout::memoryRequirements(const QMap<int, int> &screenLayout) const
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync{
2fd23abb6f9e4d687f636f3e62e707e822aaadd6vboxsync ULONG width = 0;
2fd23abb6f9e4d687f636f3e62e707e822aaadd6vboxsync ULONG height = 0;
2fd23abb6f9e4d687f636f3e62e707e822aaadd6vboxsync ULONG guestBpp = 0;
77b95150000f2ef9778e43783401ed80eaed6949vboxsync LONG xOrigin = 0;
77b95150000f2ef9778e43783401ed80eaed6949vboxsync LONG yOrigin = 0;
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync quint64 usedBits = 0;
7ac6803839f30a88cff7d938c64c5c75c220b4favboxsync CDisplay display = m_pMachineLogic->uisession()->session().GetConsole().GetDisplay();
0555766825ef1f1699618d57768bfe7bdea0ae0fvboxsync foreach (int iGuestScreen, m_guestScreens)
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync {
7abe5cfaba8f21303dcefca4fcd1c6c0a192eaf3vboxsync QRect screen;
7abe5cfaba8f21303dcefca4fcd1c6c0a192eaf3vboxsync if (m_pMachineLogic->visualStateType() == UIVisualStateType_Seamless)
b7cd916020f507a173c9cdd6c56c4a9a4574640dvboxsync screen = QApplication::desktop()->availableGeometry(screenLayout.value(iGuestScreen, 0));
7abe5cfaba8f21303dcefca4fcd1c6c0a192eaf3vboxsync else
b7cd916020f507a173c9cdd6c56c4a9a4574640dvboxsync screen = QApplication::desktop()->screenGeometry(screenLayout.value(iGuestScreen, 0));
b7307c9c040a1a8aed0dbabed6574466d0bff2e4vboxsync KGuestMonitorStatus monitorStatus = KGuestMonitorStatus_Enabled;
b7307c9c040a1a8aed0dbabed6574466d0bff2e4vboxsync display.GetScreenResolution(iGuestScreen, width, height, guestBpp, xOrigin, yOrigin, monitorStatus);
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync usedBits += screen.width() * /* display width */
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync screen.height() * /* display height */
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync guestBpp + /* guest bits per pixel */
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync _1M * 8; /* current cache per screen - may be changed in future */
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync }
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync usedBits += 4096 * 8; /* adapter info */
452fe6c0ad673fa5006fe2c24b76a1a54e4ff499vboxsync return usedBits;
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync}
af62929dce3cc5e14c75438cd2b893f82ae6dbc8vboxsync