VirtualBox

Ignore:
Timestamp:
Oct 8, 2014 4:59:48 PM (10 years ago)
Author:
vboxsync
Message:

FE/Qt: Runtime UI rework/cleanup for 7115 (part #10): Just moving code to corresponding places for r96460.

File:
1 edited

Legend:

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

    r53000 r53001  
    159159    delete pSession;
    160160    pSession = 0;
     161}
     162
     163void UISession::powerUp()
     164{
     165    /* Prepare powerup: */
     166    bool fPrepared = preparePowerUp();
     167    if (!fPrepared)
     168        return;
     169
     170    /* Get current machine/console: */
     171    CMachine machine = session().GetMachine();
     172    CConsole console = session().GetConsole();
     173
     174    /* Apply debug settings from the command line. */
     175    CMachineDebugger debugger = console.GetDebugger();
     176    if (debugger.isOk())
     177    {
     178        if (vboxGlobal().isPatmDisabled())
     179            debugger.SetPATMEnabled(false);
     180        if (vboxGlobal().isCsamDisabled())
     181            debugger.SetCSAMEnabled(false);
     182        if (vboxGlobal().isSupervisorCodeExecedRecompiled())
     183            debugger.SetRecompileSupervisor(true);
     184        if (vboxGlobal().isUserCodeExecedRecompiled())
     185            debugger.SetRecompileUser(true);
     186        if (vboxGlobal().areWeToExecuteAllInIem())
     187            debugger.SetExecuteAllInIEM(true);
     188        if (!vboxGlobal().isDefaultWarpPct())
     189            debugger.SetVirtualTimeRate(vboxGlobal().getWarpPct());
     190    }
     191
     192    if (!vboxGlobal().isSeparateProcess())
     193    {
     194        /* Power UP machine: */
     195#ifdef VBOX_WITH_DEBUGGER_GUI
     196        CProgress progress = vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled() ?
     197                             console.PowerUpPaused() : console.PowerUp();
     198#else /* !VBOX_WITH_DEBUGGER_GUI */
     199        CProgress progress = console.PowerUp();
     200#endif /* !VBOX_WITH_DEBUGGER_GUI */
     201
     202        /* Check for immediate failure: */
     203        if (!console.isOk())
     204        {
     205            if (vboxGlobal().showStartVMErrors())
     206                msgCenter().cannotStartMachine(console, machine.GetName());
     207            closeRuntimeUI();
     208            return;
     209        }
     210
     211        /* Guard progressbar warnings from auto-closing: */
     212        if (uimachine()->machineLogic())
     213            uimachine()->machineLogic()->setPreventAutoClose(true);
     214
     215        /* Show "Starting/Restoring" progress dialog: */
     216        if (isSaved())
     217        {
     218            msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_restore_90px.png", 0, 0);
     219            /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
     220            machineLogic()->adjustMachineWindowsGeometry();
     221        }
     222        else
     223            msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_start_90px.png");
     224
     225        /* Check for a progress failure: */
     226        if (!progress.isOk() || progress.GetResultCode() != 0)
     227        {
     228            if (vboxGlobal().showStartVMErrors())
     229                msgCenter().cannotStartMachine(progress, machine.GetName());
     230            closeRuntimeUI();
     231            return;
     232        }
     233
     234        /* Allow further auto-closing: */
     235        if (uimachine()->machineLogic())
     236            uimachine()->machineLogic()->setPreventAutoClose(false);
     237    }
     238    else
     239    {
     240        /* Fetch the current state: */
     241        CMouse mouse = console.GetMouse();
     242        m_fIsMouseSupportsAbsolute = mouse.GetAbsoluteSupported();
     243        m_fIsMouseSupportsRelative = mouse.GetRelativeSupported();
     244        m_fIsMouseSupportsMultiTouch = mouse.GetMultiTouchSupported();
     245        m_fIsMouseHostCursorNeeded = mouse.GetNeedsHostCursor();
     246
     247        sltAdditionsChange();
     248    }
     249
     250    /* Check if we missed a really quick termination after successful startup, and process it if we did: */
     251    if (isTurnedOff())
     252    {
     253        closeRuntimeUI();
     254        return;
     255    }
     256
     257    /* Check if the required virtualization features are active. We get this
     258     * info only when the session is active. */
     259    bool fIs64BitsGuest = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetIs64Bit();
     260    bool fRecommendVirtEx = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetRecommendedVirtEx();
     261    AssertMsg(!fIs64BitsGuest || fRecommendVirtEx, ("Virtualization support missed for 64bit guest!\n"));
     262    bool fIsVirtEnabled = console.GetDebugger().GetHWVirtExEnabled();
     263    if (fRecommendVirtEx && !fIsVirtEnabled)
     264    {
     265        bool fShouldWeClose;
     266
     267        bool fVTxAMDVSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
     268
     269        QApplication::processEvents();
     270        setPause(true);
     271
     272        if (fIs64BitsGuest)
     273            fShouldWeClose = msgCenter().warnAboutVirtNotEnabled64BitsGuest(fVTxAMDVSupported);
     274        else
     275            fShouldWeClose = msgCenter().warnAboutVirtNotEnabledGuestRequired(fVTxAMDVSupported);
     276
     277        if (fShouldWeClose)
     278        {
     279            /* At this point the console is powered up. So we have to close
     280             * this session again. */
     281            CProgress progress = console.PowerDown();
     282            if (console.isOk())
     283            {
     284                /* Guard progressbar warnings from auto-closing: */
     285                if (uimachine()->machineLogic())
     286                    uimachine()->machineLogic()->setPreventAutoClose(true);
     287                /* Show the power down progress dialog */
     288                msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
     289                if (!progress.isOk() || progress.GetResultCode() != 0)
     290                    msgCenter().cannotPowerDownMachine(progress, machine.GetName());
     291                /* Allow further auto-closing: */
     292                if (uimachine()->machineLogic())
     293                    uimachine()->machineLogic()->setPreventAutoClose(false);
     294            }
     295            else
     296                msgCenter().cannotPowerDownMachine(console);
     297            closeRuntimeUI();
     298            return;
     299        }
     300
     301        setPause(false);
     302    }
     303
     304#ifdef VBOX_WITH_VIDEOHWACCEL
     305    LogRel(("2D video acceleration is %s.\n",
     306           machine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()
     307                 ? "enabled"
     308                 : "disabled"));
     309#endif
     310
     311/* Check if HID LEDs sync is enabled and add a log message about it. */
     312#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
     313    if(uimachine()->machineLogic()->isHidLedsSyncEnabled())
     314        LogRel(("HID LEDs sync is enabled.\n"));
     315    else
     316        LogRel(("HID LEDs sync is disabled.\n"));
     317#else
     318    LogRel(("HID LEDs sync is not supported on this platform.\n"));
     319#endif
     320
     321#ifdef VBOX_GUI_WITH_PIDFILE
     322    vboxGlobal().createPidfile();
     323#endif
     324
     325    /* Warn listeners about machine was started: */
     326    emit sigStarted();
     327}
     328
     329bool UISession::saveState()
     330{
     331    /* Prepare the saving progress: */
     332    CMachine machine = m_session.GetMachine();
     333    CConsole console = m_session.GetConsole();
     334    CProgress progress = console.SaveState();
     335    if (console.isOk())
     336    {
     337        /* Show the saving progress: */
     338        msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_save_90px.png");
     339        if (!progress.isOk() || progress.GetResultCode() != 0)
     340        {
     341            /* Failed in progress: */
     342            msgCenter().cannotSaveMachineState(progress, machine.GetName());
     343            return false;
     344        }
     345    }
     346    else
     347    {
     348        /* Failed in console: */
     349        msgCenter().cannotSaveMachineState(console);
     350        return false;
     351    }
     352    /* Passed: */
     353    return true;
     354}
     355
     356bool UISession::shutdown()
     357{
     358    /* Send ACPI shutdown signal if possible: */
     359    CConsole console = m_session.GetConsole();
     360    console.PowerButton();
     361    if (!console.isOk())
     362    {
     363        /* Failed in console: */
     364        msgCenter().cannotACPIShutdownMachine(console);
     365        return false;
     366    }
     367    /* Passed: */
     368    return true;
     369}
     370
     371bool UISession::powerOff(bool fIncludingDiscard, bool &fServerCrashed)
     372{
     373    /* Prepare the power-off progress: */
     374    CMachine machine = m_session.GetMachine();
     375    CConsole console = m_session.GetConsole();
     376    CProgress progress = console.PowerDown();
     377    if (console.isOk())
     378    {
     379        /* Show the power-off progress: */
     380        msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
     381        if (progress.isOk() && progress.GetResultCode() == 0)
     382        {
     383            /* Discard the current state if requested: */
     384            if (fIncludingDiscard)
     385            {
     386                /* Prepare the snapshot-discard progress: */
     387                CSnapshot snapshot = machine.GetCurrentSnapshot();
     388                CProgress progress = console.RestoreSnapshot(snapshot);
     389                if (!console.isOk())
     390                    return msgCenter().cannotRestoreSnapshot(console, snapshot.GetName(), machine.GetName());
     391
     392                /* Show the snapshot-discard progress: */
     393                msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_discard_90px.png");
     394                if (progress.GetResultCode() != 0)
     395                    return msgCenter().cannotRestoreSnapshot(progress, snapshot.GetName(), machine.GetName());
     396            }
     397        }
     398        else
     399        {
     400            /* Failed in progress: */
     401            msgCenter().cannotPowerDownMachine(progress, machine.GetName());
     402            return false;
     403        }
     404    }
     405    else
     406    {
     407        /* Check the machine state, it might be already gone: */
     408        if (!console.isNull())
     409        {
     410           /* Failed in console: */
     411           COMResult res(console);
     412           /* This can happen if VBoxSVC is not running: */
     413           if (FAILED_DEAD_INTERFACE(res.rc()))
     414               fServerCrashed = true;
     415           else
     416               msgCenter().cannotPowerDownMachine(console);
     417           return false;
     418        }
     419    }
     420    /* Passed: */
     421    return true;
     422}
     423
     424void UISession::closeRuntimeUI()
     425{
     426    /* Start corresponding slot asynchronously: */
     427    emit sigCloseRuntimeUI();
     428}
     429
     430UIMachineLogic* UISession::machineLogic() const
     431{
     432    return uimachine()->machineLogic();
     433}
     434
     435QWidget* UISession::mainMachineWindow() const
     436{
     437    return machineLogic()->mainMachineWindow();
     438}
     439
     440bool UISession::isVisualStateAllowed(UIVisualStateType state) const
     441{
     442    return m_pMachine->isVisualStateAllowed(state);
     443}
     444
     445void UISession::changeVisualState(UIVisualStateType visualStateType)
     446{
     447    m_pMachine->asyncChangeVisualState(visualStateType);
     448}
     449
     450bool UISession::setPause(bool fOn)
     451{
     452    CConsole console = session().GetConsole();
     453    if (console.isNull())
     454        return true;
     455
     456    if (fOn)
     457        console.Pause();
     458    else
     459        console.Resume();
     460
     461    bool ok = console.isOk();
     462    if (!ok)
     463    {
     464        if (fOn)
     465            msgCenter().cannotPauseMachine(console);
     466        else
     467            msgCenter().cannotResumeMachine(console);
     468    }
     469
     470    return ok;
     471}
     472
     473void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
     474{
     475    /* This flag indicates whether we want to do the usual .ISO mounting or not.
     476     * First try updating the Guest Additions directly without mounting the .ISO. */
     477    bool fDoMount = false;
     478
     479    /* Auto-update in GUI currently is disabled. */
     480#ifndef VBOX_WITH_ADDITIONS_AUTOUPDATE_UI
     481    fDoMount = true;
     482#else /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
     483    CGuest guest = session().GetConsole().GetGuest();
     484    QVector<KAdditionsUpdateFlag> aFlagsUpdate;
     485    QVector<QString> aArgs;
     486    CProgress progressInstall = guest.UpdateGuestAdditions(strSource,
     487                                                           aArgs, aFlagsUpdate);
     488    bool fResult = guest.isOk();
     489    if (fResult)
     490    {
     491        msgCenter().showModalProgressDialog(progressInstall, tr("Updating Guest Additions"),
     492                                            ":/progress_install_guest_additions_90px.png",
     493                                            0, 500 /* 500ms delay. */);
     494        if (progressInstall.GetCanceled())
     495            return;
     496
     497        HRESULT rc = progressInstall.GetResultCode();
     498        if (!progressInstall.isOk() || rc != S_OK)
     499        {
     500            /* If we got back a VBOX_E_NOT_SUPPORTED we don't complain (guest OS
     501             * simply isn't supported yet), so silently fall back to "old" .ISO
     502             * mounting method. */
     503            if (   !SUCCEEDED_WARNING(rc)
     504                && rc != VBOX_E_NOT_SUPPORTED)
     505            {
     506                msgCenter().cannotUpdateGuestAdditions(progressInstall);
     507
     508                /* Log the error message in the release log. */
     509                QString strErr = progressInstall.GetErrorInfo().GetText();
     510                if (!strErr.isEmpty())
     511                    LogRel(("%s\n", strErr.toLatin1().constData()));
     512            }
     513            fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
     514        }
     515    }
     516#endif /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
     517
     518    /* Do we still want mounting? */
     519    if (!fDoMount)
     520        return;
     521
     522    /* Open corresponding medium: */
     523    QString strMediumID;
     524    CVirtualBox vbox = vboxGlobal().virtualBox();
     525    CMedium image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
     526    if (vbox.isOk() && !image.isNull())
     527        strMediumID = image.GetId();
     528    else
     529    {
     530        msgCenter().cannotOpenMedium(vbox, UIMediumType_DVD, strSource, mainMachineWindow());
     531        return;
     532    }
     533
     534    /* Make sure GA medium ID is valid: */
     535    AssertReturnVoid(!strMediumID.isNull());
     536
     537    /* Get machine: */
     538    CMachine machine = session().GetMachine();
     539
     540    /* Searching for the first suitable controller/slot: */
     541    QString strControllerName;
     542    LONG iCntPort = -1, iCntDevice = -1;
     543    foreach (const CStorageController &controller, machine.GetStorageControllers())
     544    {
     545        foreach (const CMediumAttachment &attachment, machine.GetMediumAttachmentsOfController(controller.GetName()))
     546        {
     547            if (attachment.GetType() == KDeviceType_DVD)
     548            {
     549                strControllerName = controller.GetName();
     550                iCntPort = attachment.GetPort();
     551                iCntDevice = attachment.GetDevice();
     552                break;
     553            }
     554        }
     555        if (!strControllerName.isNull())
     556            break;
     557    }
     558
     559    /* Make sure suitable controller/slot were found: */
     560    if (strControllerName.isNull())
     561    {
     562        msgCenter().cannotMountGuestAdditions(machine.GetName());
     563        return;
     564    }
     565
     566    /* Try to find UIMedium among cached: */
     567    UIMedium medium = vboxGlobal().medium(strMediumID);
     568    if (medium.isNull())
     569    {
     570        /* Create new one if necessary: */
     571        medium = UIMedium(image, UIMediumType_DVD, KMediumState_Created);
     572        vboxGlobal().createMedium(medium);
     573    }
     574
     575    /* Mount medium to corresponding controller/slot: */
     576    machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), false /* force */);
     577    if (!machine.isOk())
     578    {
     579        /* Ask for force mounting: */
     580        if (msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
     581                                            true /* retry? */, mainMachineWindow()))
     582        {
     583            /* Force mount medium to the predefined port/device: */
     584            machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), true /* force */);
     585            if (!machine.isOk())
     586                msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
     587                                                false /* retry? */, mainMachineWindow());
     588        }
     589    }
     590}
     591
     592void UISession::sltCloseRuntimeUI()
     593{
     594    /* First, we have to hide any opened modal/popup widgets.
     595     * They then should unlock their event-loops synchronously.
     596     * If all such loops are unlocked, we can close Runtime UI: */
     597    if (QWidget *pWidget = QApplication::activeModalWidget() ?
     598                           QApplication::activeModalWidget() :
     599                           QApplication::activePopupWidget() ?
     600                           QApplication::activePopupWidget() : 0)
     601    {
     602        /* First we should try to close this widget: */
     603        pWidget->close();
     604        /* If widget rejected the 'close-event' we can
     605         * still hide it and hope it will behave correctly
     606         * and unlock his event-loop if any: */
     607        if (!pWidget->isHidden())
     608            pWidget->hide();
     609        /* Restart this slot: */
     610        emit sigCloseRuntimeUI();
     611        return;
     612    }
     613
     614    /* Finally close the Runtime UI: */
     615    UIMachine::destroy();
     616}
     617
     618#ifdef RT_OS_DARWIN
     619void UISession::sltHandleMenuBarConfigurationChange()
     620{
     621    /* Update Mac OS X menu-bar: */
     622    updateMenu();
     623}
     624#endif /* RT_OS_DARWIN */
     625
     626void UISession::sltMousePointerShapeChange(bool fVisible, bool fAlpha, QPoint hotCorner, QSize size, QVector<uint8_t> shape)
     627{
     628    /* In case of shape data is present: */
     629    if (shape.size() > 0)
     630    {
     631        /* We are ignoring visibility flag: */
     632        m_fIsHidingHostPointer = false;
     633
     634        /* And updating current cursor shape: */
     635        setPointerShape(shape.data(), fAlpha,
     636                        hotCorner.x(), hotCorner.y(),
     637                        size.width(), size.height());
     638    }
     639    /* In case of shape data is NOT present: */
     640    else
     641    {
     642        /* Remember if we should hide the cursor: */
     643        m_fIsHidingHostPointer = !fVisible;
     644    }
     645
     646    /* Notify listeners about mouse capability changed: */
     647    emit sigMousePointerShapeChange();
     648
     649}
     650
     651void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative, bool fSupportsMultiTouch, bool fNeedsHostCursor)
     652{
     653    LogRelFlow(("UISession::sltMouseCapabilityChange: "
     654                "Supports absolute: %s, Supports relative: %s, "
     655                "Supports multi-touch: %s, Needs host cursor: %s\n",
     656                fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
     657                fSupportsMultiTouch ? "TRUE" : "FALSE", fNeedsHostCursor ? "TRUE" : "FALSE"));
     658
     659    /* Check if something had changed: */
     660    if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
     661        || m_fIsMouseSupportsRelative != fSupportsRelative
     662        || m_fIsMouseSupportsMultiTouch != fSupportsMultiTouch
     663        || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
     664    {
     665        /* Store new data: */
     666        m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
     667        m_fIsMouseSupportsRelative = fSupportsRelative;
     668        m_fIsMouseSupportsMultiTouch = fSupportsMultiTouch;
     669        m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
     670
     671        /* Notify listeners about mouse capability changed: */
     672        emit sigMouseCapabilityChange();
     673    }
     674}
     675
     676void UISession::sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
     677{
     678    /* Check if something had changed: */
     679    if (   m_fNumLock != fNumLock
     680        || m_fCapsLock != fCapsLock
     681        || m_fScrollLock != fScrollLock)
     682    {
     683        /* Store new num lock data: */
     684        if (m_fNumLock != fNumLock)
     685        {
     686            m_fNumLock = fNumLock;
     687            m_uNumLockAdaptionCnt = 2;
     688        }
     689
     690        /* Store new caps lock data: */
     691        if (m_fCapsLock != fCapsLock)
     692        {
     693            m_fCapsLock = fCapsLock;
     694            m_uCapsLockAdaptionCnt = 2;
     695        }
     696
     697        /* Store new scroll lock data: */
     698        if (m_fScrollLock != fScrollLock)
     699        {
     700            m_fScrollLock = fScrollLock;
     701        }
     702
     703        /* Notify listeners about mouse capability changed: */
     704        emit sigKeyboardLedsChange();
     705    }
     706}
     707
     708void UISession::sltStateChange(KMachineState state)
     709{
     710    /* Check if something had changed: */
     711    if (m_machineState != state)
     712    {
     713        /* Store new data: */
     714        m_machineStatePrevious = m_machineState;
     715        m_machineState = state;
     716
     717        /* Notify listeners about machine state changed: */
     718        emit sigMachineStateChange();
     719    }
     720}
     721
     722void UISession::sltVRDEChange()
     723{
     724    /* Get machine: */
     725    const CMachine machine = session().GetMachine();
     726    /* Get VRDE server: */
     727    const CVRDEServer &server = machine.GetVRDEServer();
     728    bool fIsVRDEServerAvailable = !server.isNull();
     729    /* Show/Hide VRDE action depending on VRDE server availability status: */
     730    // TODO: Is this status can be changed at runtime?
     731    //       Because if no => the place for that stuff is in prepareActions().
     732    actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setVisible(fIsVRDEServerAvailable);
     733    /* Check/Uncheck VRDE action depending on VRDE server activity status: */
     734    if (fIsVRDEServerAvailable)
     735        actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setChecked(server.GetEnabled());
     736    /* Notify listeners about VRDE change: */
     737    emit sigVRDEChange();
     738}
     739
     740void UISession::sltVideoCaptureChange()
     741{
     742    /* Get machine: */
     743    const CMachine machine = session().GetMachine();
     744    /* Check/Uncheck Video Capture action depending on feature status: */
     745    actionPool()->action(UIActionIndexRT_M_Devices_M_VideoCapture_T_Start)->setChecked(machine.GetVideoCaptureEnabled());
     746    /* Notify listeners about Video Capture change: */
     747    emit sigVideoCaptureChange();
     748}
     749
     750void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
     751{
     752    /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
     753    if (changeType == KGuestMonitorChangedEventType_NewOrigin)
     754        return;
     755    /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
     756    AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
     757    if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
     758        return;
     759
     760    /* Process KGuestMonitorChangedEventType_Enabled change event: */
     761    if (   !isScreenVisible(uScreenId)
     762        && changeType == KGuestMonitorChangedEventType_Enabled)
     763        setScreenVisible(uScreenId, true);
     764    /* Process KGuestMonitorChangedEventType_Disabled change event: */
     765    else if (   isScreenVisible(uScreenId)
     766             && changeType == KGuestMonitorChangedEventType_Disabled)
     767        setScreenVisible(uScreenId, false);
     768
     769    /* Notify listeners about the change: */
     770    emit sigGuestMonitorChange(changeType, uScreenId, screenGeo);
     771}
     772
     773#ifdef RT_OS_DARWIN
     774/**
     775 * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
     776 * @note Watchdog is trying to determine display reconfiguration in
     777 *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
     778 */
     779void UISession::sltHandleHostDisplayAboutToChange()
     780{
     781    LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
     782
     783    if (m_pWatchdogDisplayChange->isActive())
     784        m_pWatchdogDisplayChange->stop();
     785    m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
     786    m_pWatchdogDisplayChange->start();
     787}
     788
     789/**
     790 * MacOS X: Determines display reconfiguration.
     791 * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
     792 * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
     793 */
     794void UISession::sltCheckIfHostDisplayChanged()
     795{
     796    LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
     797
     798    /* Acquire desktop wrapper: */
     799    QDesktopWidget *pDesktop = QApplication::desktop();
     800
     801    /* Check if display count changed: */
     802    if (pDesktop->screenCount() != m_hostScreens.size())
     803    {
     804        /* Reset watchdog: */
     805        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
     806        /* Notify listeners about screen-count changed: */
     807        return sltHandleHostScreenCountChange();
     808    }
     809    else
     810    {
     811        /* Check if at least one display geometry changed: */
     812        for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
     813        {
     814            if (pDesktop->screenGeometry(iScreenIndex) != m_hostScreens.at(iScreenIndex))
     815            {
     816                /* Reset watchdog: */
     817                m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
     818                /* Notify listeners about screen-geometry changed: */
     819                return sltHandleHostScreenGeometryChange();
     820            }
     821        }
     822    }
     823
     824    /* Check if watchdog expired, restart if not: */
     825    int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
     826    if (cTryNumber > 0 && cTryNumber < 40)
     827    {
     828        /* Restart watchdog again: */
     829        m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
     830        m_pWatchdogDisplayChange->start();
     831    }
     832    else
     833    {
     834        /* Reset watchdog: */
     835        m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
     836    }
     837}
     838#endif /* RT_OS_DARWIN */
     839
     840void UISession::sltHandleHostScreenCountChange()
     841{
     842    LogRelFlow(("UISession: Host-screen count changed.\n"));
     843
     844    /* Recache display data: */
     845    updateHostScreenData();
     846
     847    /* Notify current machine-logic: */
     848    emit sigHostScreenCountChange();
     849}
     850
     851void UISession::sltHandleHostScreenGeometryChange()
     852{
     853    LogRelFlow(("UISession: Host-screen geometry changed.\n"));
     854
     855    /* Recache display data: */
     856    updateHostScreenData();
     857
     858    /* Notify current machine-logic: */
     859    emit sigHostScreenGeometryChange();
     860}
     861
     862void UISession::sltHandleHostScreenAvailableAreaChange()
     863{
     864    LogRelFlow(("UISession: Host-screen available-area changed.\n"));
     865
     866    /* Notify current machine-logic: */
     867    emit sigHostScreenAvailableAreaChange();
     868}
     869
     870void UISession::sltAdditionsChange()
     871{
     872    /* Get our guest: */
     873    CGuest guest = session().GetConsole().GetGuest();
     874
     875    /* Variable flags: */
     876    ULONG ulGuestAdditionsRunLevel = guest.GetAdditionsRunLevel();
     877    LONG64 lLastUpdatedIgnored;
     878    bool fIsGuestSupportsGraphics = guest.GetFacilityStatus(KAdditionsFacilityType_Graphics, lLastUpdatedIgnored)
     879                                    == KAdditionsFacilityStatus_Active;
     880    bool fIsGuestSupportsSeamless = guest.GetFacilityStatus(KAdditionsFacilityType_Seamless, lLastUpdatedIgnored)
     881                                    == KAdditionsFacilityStatus_Active;
     882    /* Check if something had changed: */
     883    if (m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel ||
     884        m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
     885        m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
     886    {
     887        /* Store new data: */
     888        m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
     889        m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
     890        m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
     891
     892        /* Notify listeners about guest additions state changed: */
     893        emit sigAdditionsStateChange();
     894    }
    161895}
    162896
     
    215949}
    216950
     951UISession::~UISession()
     952{
     953}
     954
    217955bool UISession::prepare()
    218956{
     
    251989}
    252990
    253 UISession::~UISession()
    254 {
    255 }
    256 
    257 void UISession::cleanup()
    258 {
    259 #ifdef Q_WS_WIN
    260     /* Destroy alpha cursor: */
    261     if (m_alphaCursor)
    262         DestroyIcon(m_alphaCursor);
    263 #endif /* Q_WS_WIN */
    264 
    265     /* Save settings: */
    266     saveSessionSettings();
    267 
    268     /* Cleanup framebuffers: */
    269     cleanupFramebuffers();
    270 
    271     /* Cleanup console event-handlers: */
    272     cleanupConsoleEventHandlers();
    273 
    274     /* Cleanup connections: */
    275     cleanupConnections();
    276 
    277     /* Cleanup actions: */
    278     cleanupActions();
    279 
    280     /* Cleanup session: */
    281     cleanupSession();
    282 }
    283 
    284 void UISession::powerUp()
    285 {
    286     /* Prepare powerup: */
    287     bool fPrepared = preparePowerUp();
    288     if (!fPrepared)
    289         return;
    290 
    291     /* Get current machine/console: */
    292     CMachine machine = session().GetMachine();
    293     CConsole console = session().GetConsole();
    294 
    295     /* Apply debug settings from the command line. */
    296     CMachineDebugger debugger = console.GetDebugger();
    297     if (debugger.isOk())
    298     {
    299         if (vboxGlobal().isPatmDisabled())
    300             debugger.SetPATMEnabled(false);
    301         if (vboxGlobal().isCsamDisabled())
    302             debugger.SetCSAMEnabled(false);
    303         if (vboxGlobal().isSupervisorCodeExecedRecompiled())
    304             debugger.SetRecompileSupervisor(true);
    305         if (vboxGlobal().isUserCodeExecedRecompiled())
    306             debugger.SetRecompileUser(true);
    307         if (vboxGlobal().areWeToExecuteAllInIem())
    308             debugger.SetExecuteAllInIEM(true);
    309         if (!vboxGlobal().isDefaultWarpPct())
    310             debugger.SetVirtualTimeRate(vboxGlobal().getWarpPct());
    311     }
    312 
    313     if (!vboxGlobal().isSeparateProcess())
    314     {
    315         /* Power UP machine: */
    316 #ifdef VBOX_WITH_DEBUGGER_GUI
    317         CProgress progress = vboxGlobal().isStartPausedEnabled() || vboxGlobal().isDebuggerAutoShowEnabled() ?
    318                              console.PowerUpPaused() : console.PowerUp();
    319 #else /* !VBOX_WITH_DEBUGGER_GUI */
    320         CProgress progress = console.PowerUp();
    321 #endif /* !VBOX_WITH_DEBUGGER_GUI */
    322 
    323         /* Check for immediate failure: */
    324         if (!console.isOk())
    325         {
    326             if (vboxGlobal().showStartVMErrors())
    327                 msgCenter().cannotStartMachine(console, machine.GetName());
    328             closeRuntimeUI();
    329             return;
    330         }
    331 
    332         /* Guard progressbar warnings from auto-closing: */
    333         if (uimachine()->machineLogic())
    334             uimachine()->machineLogic()->setPreventAutoClose(true);
    335 
    336         /* Show "Starting/Restoring" progress dialog: */
    337         if (isSaved())
    338         {
    339             msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_restore_90px.png", 0, 0);
    340             /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
    341             machineLogic()->adjustMachineWindowsGeometry();
    342         }
    343         else
    344             msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_start_90px.png");
    345 
    346         /* Check for a progress failure: */
    347         if (!progress.isOk() || progress.GetResultCode() != 0)
    348         {
    349             if (vboxGlobal().showStartVMErrors())
    350                 msgCenter().cannotStartMachine(progress, machine.GetName());
    351             closeRuntimeUI();
    352             return;
    353         }
    354 
    355         /* Allow further auto-closing: */
    356         if (uimachine()->machineLogic())
    357             uimachine()->machineLogic()->setPreventAutoClose(false);
    358     }
    359     else
    360     {
    361         /* Fetch the current state: */
    362         CMouse mouse = console.GetMouse();
    363         m_fIsMouseSupportsAbsolute = mouse.GetAbsoluteSupported();
    364         m_fIsMouseSupportsRelative = mouse.GetRelativeSupported();
    365         m_fIsMouseSupportsMultiTouch = mouse.GetMultiTouchSupported();
    366         m_fIsMouseHostCursorNeeded = mouse.GetNeedsHostCursor();
    367 
    368         sltAdditionsChange();
    369     }
    370 
    371     /* Check if we missed a really quick termination after successful startup, and process it if we did: */
    372     if (isTurnedOff())
    373     {
    374         closeRuntimeUI();
    375         return;
    376     }
    377 
    378     /* Check if the required virtualization features are active. We get this
    379      * info only when the session is active. */
    380     bool fIs64BitsGuest = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetIs64Bit();
    381     bool fRecommendVirtEx = vboxGlobal().virtualBox().GetGuestOSType(console.GetGuest().GetOSTypeId()).GetRecommendedVirtEx();
    382     AssertMsg(!fIs64BitsGuest || fRecommendVirtEx, ("Virtualization support missed for 64bit guest!\n"));
    383     bool fIsVirtEnabled = console.GetDebugger().GetHWVirtExEnabled();
    384     if (fRecommendVirtEx && !fIsVirtEnabled)
    385     {
    386         bool fShouldWeClose;
    387 
    388         bool fVTxAMDVSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
    389 
    390         QApplication::processEvents();
    391         setPause(true);
    392 
    393         if (fIs64BitsGuest)
    394             fShouldWeClose = msgCenter().warnAboutVirtNotEnabled64BitsGuest(fVTxAMDVSupported);
    395         else
    396             fShouldWeClose = msgCenter().warnAboutVirtNotEnabledGuestRequired(fVTxAMDVSupported);
    397 
    398         if (fShouldWeClose)
    399         {
    400             /* At this point the console is powered up. So we have to close
    401              * this session again. */
    402             CProgress progress = console.PowerDown();
    403             if (console.isOk())
    404             {
    405                 /* Guard progressbar warnings from auto-closing: */
    406                 if (uimachine()->machineLogic())
    407                     uimachine()->machineLogic()->setPreventAutoClose(true);
    408                 /* Show the power down progress dialog */
    409                 msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
    410                 if (!progress.isOk() || progress.GetResultCode() != 0)
    411                     msgCenter().cannotPowerDownMachine(progress, machine.GetName());
    412                 /* Allow further auto-closing: */
    413                 if (uimachine()->machineLogic())
    414                     uimachine()->machineLogic()->setPreventAutoClose(false);
    415             }
    416             else
    417                 msgCenter().cannotPowerDownMachine(console);
    418             closeRuntimeUI();
    419             return;
    420         }
    421 
    422         setPause(false);
    423     }
    424 
    425 #ifdef VBOX_WITH_VIDEOHWACCEL
    426     LogRel(("2D video acceleration is %s.\n",
    427            machine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()
    428                  ? "enabled"
    429                  : "disabled"));
    430 #endif
    431 
    432 /* Check if HID LEDs sync is enabled and add a log message about it. */
    433 #if defined(Q_WS_MAC) || defined(Q_WS_WIN)
    434     if(uimachine()->machineLogic()->isHidLedsSyncEnabled())
    435         LogRel(("HID LEDs sync is enabled.\n"));
    436     else
    437         LogRel(("HID LEDs sync is disabled.\n"));
    438 #else
    439     LogRel(("HID LEDs sync is not supported on this platform.\n"));
    440 #endif
    441 
    442 #ifdef VBOX_GUI_WITH_PIDFILE
    443     vboxGlobal().createPidfile();
    444 #endif
    445 
    446     /* Warn listeners about machine was started: */
    447     emit sigStarted();
    448 }
    449 
    450 bool UISession::saveState()
    451 {
    452     /* Prepare the saving progress: */
    453     CMachine machine = m_session.GetMachine();
    454     CConsole console = m_session.GetConsole();
    455     CProgress progress = console.SaveState();
    456     if (console.isOk())
    457     {
    458         /* Show the saving progress: */
    459         msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_save_90px.png");
    460         if (!progress.isOk() || progress.GetResultCode() != 0)
    461         {
    462             /* Failed in progress: */
    463             msgCenter().cannotSaveMachineState(progress, machine.GetName());
    464             return false;
    465         }
    466     }
    467     else
    468     {
    469         /* Failed in console: */
    470         msgCenter().cannotSaveMachineState(console);
    471         return false;
    472     }
    473     /* Passed: */
    474     return true;
    475 }
    476 
    477 bool UISession::shutdown()
    478 {
    479     /* Send ACPI shutdown signal if possible: */
    480     CConsole console = m_session.GetConsole();
    481     console.PowerButton();
    482     if (!console.isOk())
    483     {
    484         /* Failed in console: */
    485         msgCenter().cannotACPIShutdownMachine(console);
    486         return false;
    487     }
    488     /* Passed: */
    489     return true;
    490 }
    491 
    492 bool UISession::powerOff(bool fIncludingDiscard, bool &fServerCrashed)
    493 {
    494     /* Prepare the power-off progress: */
    495     CMachine machine = m_session.GetMachine();
    496     CConsole console = m_session.GetConsole();
    497     CProgress progress = console.PowerDown();
    498     if (console.isOk())
    499     {
    500         /* Show the power-off progress: */
    501         msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_poweroff_90px.png");
    502         if (progress.isOk() && progress.GetResultCode() == 0)
    503         {
    504             /* Discard the current state if requested: */
    505             if (fIncludingDiscard)
    506             {
    507                 /* Prepare the snapshot-discard progress: */
    508                 CSnapshot snapshot = machine.GetCurrentSnapshot();
    509                 CProgress progress = console.RestoreSnapshot(snapshot);
    510                 if (!console.isOk())
    511                     return msgCenter().cannotRestoreSnapshot(console, snapshot.GetName(), machine.GetName());
    512 
    513                 /* Show the snapshot-discard progress: */
    514                 msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_discard_90px.png");
    515                 if (progress.GetResultCode() != 0)
    516                     return msgCenter().cannotRestoreSnapshot(progress, snapshot.GetName(), machine.GetName());
    517             }
    518         }
    519         else
    520         {
    521             /* Failed in progress: */
    522             msgCenter().cannotPowerDownMachine(progress, machine.GetName());
    523             return false;
    524         }
    525     }
    526     else
    527     {
    528         /* Check the machine state, it might be already gone: */
    529         if (!console.isNull())
    530         {
    531            /* Failed in console: */
    532            COMResult res(console);
    533            /* This can happen if VBoxSVC is not running: */
    534            if (FAILED_DEAD_INTERFACE(res.rc()))
    535                fServerCrashed = true;
    536            else
    537                msgCenter().cannotPowerDownMachine(console);
    538            return false;
    539         }
    540     }
    541     /* Passed: */
    542     return true;
    543 }
    544 
    545 void UISession::closeRuntimeUI()
    546 {
    547     /* Start corresponding slot asynchronously: */
    548     emit sigCloseRuntimeUI();
    549 }
    550 
    551 UIMachineLogic* UISession::machineLogic() const
    552 {
    553     return uimachine()->machineLogic();
    554 }
    555 
    556 QWidget* UISession::mainMachineWindow() const
    557 {
    558     return machineLogic()->mainMachineWindow();
    559 }
    560 
    561 bool UISession::isVisualStateAllowed(UIVisualStateType state) const
    562 {
    563     return m_pMachine->isVisualStateAllowed(state);
    564 }
    565 
    566 void UISession::changeVisualState(UIVisualStateType visualStateType)
    567 {
    568     m_pMachine->asyncChangeVisualState(visualStateType);
    569 }
    570 
    571 bool UISession::setPause(bool fOn)
    572 {
    573     CConsole console = session().GetConsole();
    574     if (console.isNull())
    575         return true;
    576 
    577     if (fOn)
    578         console.Pause();
    579     else
    580         console.Resume();
    581 
    582     bool ok = console.isOk();
    583     if (!ok)
    584     {
    585         if (fOn)
    586             msgCenter().cannotPauseMachine(console);
    587         else
    588             msgCenter().cannotResumeMachine(console);
    589     }
    590 
    591     return ok;
    592 }
    593 
    594 void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
    595 {
    596     /* This flag indicates whether we want to do the usual .ISO mounting or not.
    597      * First try updating the Guest Additions directly without mounting the .ISO. */
    598     bool fDoMount = false;
    599 
    600     /* Auto-update in GUI currently is disabled. */
    601 #ifndef VBOX_WITH_ADDITIONS_AUTOUPDATE_UI
    602     fDoMount = true;
    603 #else /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
    604     CGuest guest = session().GetConsole().GetGuest();
    605     QVector<KAdditionsUpdateFlag> aFlagsUpdate;
    606     QVector<QString> aArgs;
    607     CProgress progressInstall = guest.UpdateGuestAdditions(strSource,
    608                                                            aArgs, aFlagsUpdate);
    609     bool fResult = guest.isOk();
    610     if (fResult)
    611     {
    612         msgCenter().showModalProgressDialog(progressInstall, tr("Updating Guest Additions"),
    613                                             ":/progress_install_guest_additions_90px.png",
    614                                             0, 500 /* 500ms delay. */);
    615         if (progressInstall.GetCanceled())
    616             return;
    617 
    618         HRESULT rc = progressInstall.GetResultCode();
    619         if (!progressInstall.isOk() || rc != S_OK)
    620         {
    621             /* If we got back a VBOX_E_NOT_SUPPORTED we don't complain (guest OS
    622              * simply isn't supported yet), so silently fall back to "old" .ISO
    623              * mounting method. */
    624             if (   !SUCCEEDED_WARNING(rc)
    625                 && rc != VBOX_E_NOT_SUPPORTED)
    626             {
    627                 msgCenter().cannotUpdateGuestAdditions(progressInstall);
    628 
    629                 /* Log the error message in the release log. */
    630                 QString strErr = progressInstall.GetErrorInfo().GetText();
    631                 if (!strErr.isEmpty())
    632                     LogRel(("%s\n", strErr.toLatin1().constData()));
    633             }
    634             fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
    635         }
    636     }
    637 #endif /* VBOX_WITH_ADDITIONS_AUTOUPDATE_UI */
    638 
    639     /* Do we still want mounting? */
    640     if (!fDoMount)
    641         return;
    642 
    643     /* Open corresponding medium: */
    644     QString strMediumID;
    645     CVirtualBox vbox = vboxGlobal().virtualBox();
    646     CMedium image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
    647     if (vbox.isOk() && !image.isNull())
    648         strMediumID = image.GetId();
    649     else
    650     {
    651         msgCenter().cannotOpenMedium(vbox, UIMediumType_DVD, strSource, mainMachineWindow());
    652         return;
    653     }
    654 
    655     /* Make sure GA medium ID is valid: */
    656     AssertReturnVoid(!strMediumID.isNull());
    657 
    658     /* Get machine: */
    659     CMachine machine = session().GetMachine();
    660 
    661     /* Searching for the first suitable controller/slot: */
    662     QString strControllerName;
    663     LONG iCntPort = -1, iCntDevice = -1;
    664     foreach (const CStorageController &controller, machine.GetStorageControllers())
    665     {
    666         foreach (const CMediumAttachment &attachment, machine.GetMediumAttachmentsOfController(controller.GetName()))
    667         {
    668             if (attachment.GetType() == KDeviceType_DVD)
    669             {
    670                 strControllerName = controller.GetName();
    671                 iCntPort = attachment.GetPort();
    672                 iCntDevice = attachment.GetDevice();
    673                 break;
    674             }
    675         }
    676         if (!strControllerName.isNull())
    677             break;
    678     }
    679 
    680     /* Make sure suitable controller/slot were found: */
    681     if (strControllerName.isNull())
    682     {
    683         msgCenter().cannotMountGuestAdditions(machine.GetName());
    684         return;
    685     }
    686 
    687     /* Try to find UIMedium among cached: */
    688     UIMedium medium = vboxGlobal().medium(strMediumID);
    689     if (medium.isNull())
    690     {
    691         /* Create new one if necessary: */
    692         medium = UIMedium(image, UIMediumType_DVD, KMediumState_Created);
    693         vboxGlobal().createMedium(medium);
    694     }
    695 
    696     /* Mount medium to corresponding controller/slot: */
    697     machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), false /* force */);
    698     if (!machine.isOk())
    699     {
    700         /* Ask for force mounting: */
    701         if (msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
    702                                             true /* retry? */, mainMachineWindow()))
    703         {
    704             /* Force mount medium to the predefined port/device: */
    705             machine.MountMedium(strControllerName, iCntPort, iCntDevice, medium.medium(), true /* force */);
    706             if (!machine.isOk())
    707                 msgCenter().cannotRemountMedium(machine, medium, true /* mount? */,
    708                                                 false /* retry? */, mainMachineWindow());
    709         }
    710     }
    711 }
    712 
    713 void UISession::sltCloseRuntimeUI()
    714 {
    715     /* First, we have to hide any opened modal/popup widgets.
    716      * They then should unlock their event-loops synchronously.
    717      * If all such loops are unlocked, we can close Runtime UI: */
    718     if (QWidget *pWidget = QApplication::activeModalWidget() ?
    719                            QApplication::activeModalWidget() :
    720                            QApplication::activePopupWidget() ?
    721                            QApplication::activePopupWidget() : 0)
    722     {
    723         /* First we should try to close this widget: */
    724         pWidget->close();
    725         /* If widget rejected the 'close-event' we can
    726          * still hide it and hope it will behave correctly
    727          * and unlock his event-loop if any: */
    728         if (!pWidget->isHidden())
    729             pWidget->hide();
    730         /* Restart this slot: */
    731         emit sigCloseRuntimeUI();
    732         return;
    733     }
    734 
    735     /* Finally close the Runtime UI: */
    736     UIMachine::destroy();
    737 }
    738 
    739 #ifdef RT_OS_DARWIN
    740 void UISession::sltHandleMenuBarConfigurationChange()
    741 {
    742     /* Update Mac OS X menu-bar: */
    743     updateMenu();
    744 }
    745 #endif /* RT_OS_DARWIN */
    746 
    747 void UISession::sltMousePointerShapeChange(bool fVisible, bool fAlpha, QPoint hotCorner, QSize size, QVector<uint8_t> shape)
    748 {
    749     /* In case of shape data is present: */
    750     if (shape.size() > 0)
    751     {
    752         /* We are ignoring visibility flag: */
    753         m_fIsHidingHostPointer = false;
    754 
    755         /* And updating current cursor shape: */
    756         setPointerShape(shape.data(), fAlpha,
    757                         hotCorner.x(), hotCorner.y(),
    758                         size.width(), size.height());
    759     }
    760     /* In case of shape data is NOT present: */
    761     else
    762     {
    763         /* Remember if we should hide the cursor: */
    764         m_fIsHidingHostPointer = !fVisible;
    765     }
    766 
    767     /* Notify listeners about mouse capability changed: */
    768     emit sigMousePointerShapeChange();
    769 
    770 }
    771 
    772 void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative, bool fSupportsMultiTouch, bool fNeedsHostCursor)
    773 {
    774     LogRelFlow(("UISession::sltMouseCapabilityChange: "
    775                 "Supports absolute: %s, Supports relative: %s, "
    776                 "Supports multi-touch: %s, Needs host cursor: %s\n",
    777                 fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
    778                 fSupportsMultiTouch ? "TRUE" : "FALSE", fNeedsHostCursor ? "TRUE" : "FALSE"));
    779 
    780     /* Check if something had changed: */
    781     if (   m_fIsMouseSupportsAbsolute != fSupportsAbsolute
    782         || m_fIsMouseSupportsRelative != fSupportsRelative
    783         || m_fIsMouseSupportsMultiTouch != fSupportsMultiTouch
    784         || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
    785     {
    786         /* Store new data: */
    787         m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
    788         m_fIsMouseSupportsRelative = fSupportsRelative;
    789         m_fIsMouseSupportsMultiTouch = fSupportsMultiTouch;
    790         m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
    791 
    792         /* Notify listeners about mouse capability changed: */
    793         emit sigMouseCapabilityChange();
    794     }
    795 }
    796 
    797 void UISession::sltKeyboardLedsChangeEvent(bool fNumLock, bool fCapsLock, bool fScrollLock)
    798 {
    799     /* Check if something had changed: */
    800     if (   m_fNumLock != fNumLock
    801         || m_fCapsLock != fCapsLock
    802         || m_fScrollLock != fScrollLock)
    803     {
    804         /* Store new num lock data: */
    805         if (m_fNumLock != fNumLock)
    806         {
    807             m_fNumLock = fNumLock;
    808             m_uNumLockAdaptionCnt = 2;
    809         }
    810 
    811         /* Store new caps lock data: */
    812         if (m_fCapsLock != fCapsLock)
    813         {
    814             m_fCapsLock = fCapsLock;
    815             m_uCapsLockAdaptionCnt = 2;
    816         }
    817 
    818         /* Store new scroll lock data: */
    819         if (m_fScrollLock != fScrollLock)
    820         {
    821             m_fScrollLock = fScrollLock;
    822         }
    823 
    824         /* Notify listeners about mouse capability changed: */
    825         emit sigKeyboardLedsChange();
    826     }
    827 }
    828 
    829 void UISession::sltStateChange(KMachineState state)
    830 {
    831     /* Check if something had changed: */
    832     if (m_machineState != state)
    833     {
    834         /* Store new data: */
    835         m_machineStatePrevious = m_machineState;
    836         m_machineState = state;
    837 
    838         /* Notify listeners about machine state changed: */
    839         emit sigMachineStateChange();
    840     }
    841 }
    842 
    843 void UISession::sltVRDEChange()
    844 {
    845     /* Get machine: */
    846     const CMachine machine = session().GetMachine();
    847     /* Get VRDE server: */
    848     const CVRDEServer &server = machine.GetVRDEServer();
    849     bool fIsVRDEServerAvailable = !server.isNull();
    850     /* Show/Hide VRDE action depending on VRDE server availability status: */
    851     // TODO: Is this status can be changed at runtime?
    852     //       Because if no => the place for that stuff is in prepareActions().
    853     actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setVisible(fIsVRDEServerAvailable);
    854     /* Check/Uncheck VRDE action depending on VRDE server activity status: */
    855     if (fIsVRDEServerAvailable)
    856         actionPool()->action(UIActionIndexRT_M_Devices_T_VRDEServer)->setChecked(server.GetEnabled());
    857     /* Notify listeners about VRDE change: */
    858     emit sigVRDEChange();
    859 }
    860 
    861 void UISession::sltVideoCaptureChange()
    862 {
    863     /* Get machine: */
    864     const CMachine machine = session().GetMachine();
    865     /* Check/Uncheck Video Capture action depending on feature status: */
    866     actionPool()->action(UIActionIndexRT_M_Devices_M_VideoCapture_T_Start)->setChecked(machine.GetVideoCaptureEnabled());
    867     /* Notify listeners about Video Capture change: */
    868     emit sigVideoCaptureChange();
    869 }
    870 
    871 void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
    872 {
    873     /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
    874     if (changeType == KGuestMonitorChangedEventType_NewOrigin)
    875         return;
    876     /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
    877     AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
    878     if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
    879         return;
    880 
    881     /* Process KGuestMonitorChangedEventType_Enabled change event: */
    882     if (   !isScreenVisible(uScreenId)
    883         && changeType == KGuestMonitorChangedEventType_Enabled)
    884         setScreenVisible(uScreenId, true);
    885     /* Process KGuestMonitorChangedEventType_Disabled change event: */
    886     else if (   isScreenVisible(uScreenId)
    887              && changeType == KGuestMonitorChangedEventType_Disabled)
    888         setScreenVisible(uScreenId, false);
    889 
    890     /* Notify listeners about the change: */
    891     emit sigGuestMonitorChange(changeType, uScreenId, screenGeo);
    892 }
    893 
    894 #ifdef RT_OS_DARWIN
    895 /**
    896  * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.
    897  * @note Watchdog is trying to determine display reconfiguration in
    898  *       UISession::sltCheckIfHostDisplayChanged() slot every 500ms for 40 tries.
    899  */
    900 void UISession::sltHandleHostDisplayAboutToChange()
    901 {
    902     LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
    903 
    904     if (m_pWatchdogDisplayChange->isActive())
    905         m_pWatchdogDisplayChange->stop();
    906     m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
    907     m_pWatchdogDisplayChange->start();
    908 }
    909 
    910 /**
    911  * MacOS X: Determines display reconfiguration.
    912  * @note Calls for UISession::sltHandleHostScreenCountChange() if screen count changed.
    913  * @note Calls for UISession::sltHandleHostScreenGeometryChange() if screen geometry changed.
    914  */
    915 void UISession::sltCheckIfHostDisplayChanged()
    916 {
    917     LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
    918 
    919     /* Acquire desktop wrapper: */
    920     QDesktopWidget *pDesktop = QApplication::desktop();
    921 
    922     /* Check if display count changed: */
    923     if (pDesktop->screenCount() != m_hostScreens.size())
    924     {
    925         /* Reset watchdog: */
    926         m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    927         /* Notify listeners about screen-count changed: */
    928         return sltHandleHostScreenCountChange();
    929     }
    930     else
    931     {
    932         /* Check if at least one display geometry changed: */
    933         for (int iScreenIndex = 0; iScreenIndex < pDesktop->screenCount(); ++iScreenIndex)
    934         {
    935             if (pDesktop->screenGeometry(iScreenIndex) != m_hostScreens.at(iScreenIndex))
    936             {
    937                 /* Reset watchdog: */
    938                 m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    939                 /* Notify listeners about screen-geometry changed: */
    940                 return sltHandleHostScreenGeometryChange();
    941             }
    942         }
    943     }
    944 
    945     /* Check if watchdog expired, restart if not: */
    946     int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
    947     if (cTryNumber > 0 && cTryNumber < 40)
    948     {
    949         /* Restart watchdog again: */
    950         m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
    951         m_pWatchdogDisplayChange->start();
    952     }
    953     else
    954     {
    955         /* Reset watchdog: */
    956         m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
    957     }
    958 }
    959 #endif /* RT_OS_DARWIN */
    960 
    961 void UISession::sltHandleHostScreenCountChange()
    962 {
    963     LogRelFlow(("UISession: Host-screen count changed.\n"));
    964 
    965     /* Recache display data: */
    966     updateHostScreenData();
    967 
    968     /* Notify current machine-logic: */
    969     emit sigHostScreenCountChange();
    970 }
    971 
    972 void UISession::sltHandleHostScreenGeometryChange()
    973 {
    974     LogRelFlow(("UISession: Host-screen geometry changed.\n"));
    975 
    976     /* Recache display data: */
    977     updateHostScreenData();
    978 
    979     /* Notify current machine-logic: */
    980     emit sigHostScreenGeometryChange();
    981 }
    982 
    983 void UISession::sltHandleHostScreenAvailableAreaChange()
    984 {
    985     LogRelFlow(("UISession: Host-screen available-area changed.\n"));
    986 
    987     /* Notify current machine-logic: */
    988     emit sigHostScreenAvailableAreaChange();
    989 }
    990 
    991 void UISession::sltAdditionsChange()
    992 {
    993     /* Get our guest: */
    994     CGuest guest = session().GetConsole().GetGuest();
    995 
    996     /* Variable flags: */
    997     ULONG ulGuestAdditionsRunLevel = guest.GetAdditionsRunLevel();
    998     LONG64 lLastUpdatedIgnored;
    999     bool fIsGuestSupportsGraphics = guest.GetFacilityStatus(KAdditionsFacilityType_Graphics, lLastUpdatedIgnored)
    1000                                     == KAdditionsFacilityStatus_Active;
    1001     bool fIsGuestSupportsSeamless = guest.GetFacilityStatus(KAdditionsFacilityType_Seamless, lLastUpdatedIgnored)
    1002                                     == KAdditionsFacilityStatus_Active;
    1003     /* Check if something had changed: */
    1004     if (m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel ||
    1005         m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
    1006         m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
    1007     {
    1008         /* Store new data: */
    1009         m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
    1010         m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
    1011         m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
    1012 
    1013         /* Notify listeners about guest additions state changed: */
    1014         emit sigAdditionsStateChange();
    1015     }
    1016 }
    1017 
    1018991bool UISession::prepareSession()
    1019992{
     
    10301003    /* True by default: */
    10311004    return true;
    1032 }
    1033 
    1034 void UISession::prepareConsoleEventHandlers()
    1035 {
    1036     /* Create console event-handler: */
    1037     UIConsoleEventHandler::create(this);
    1038 
    1039     /* Add console event connections: */
    1040     connect(gConsoleEvents, SIGNAL(sigMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)),
    1041             this, SLOT(sltMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)));
    1042 
    1043     connect(gConsoleEvents, SIGNAL(sigMouseCapabilityChange(bool, bool, bool, bool)),
    1044             this, SLOT(sltMouseCapabilityChange(bool, bool, bool, bool)));
    1045 
    1046     connect(gConsoleEvents, SIGNAL(sigKeyboardLedsChangeEvent(bool, bool, bool)),
    1047             this, SLOT(sltKeyboardLedsChangeEvent(bool, bool, bool)));
    1048 
    1049     connect(gConsoleEvents, SIGNAL(sigStateChange(KMachineState)),
    1050             this, SLOT(sltStateChange(KMachineState)));
    1051 
    1052     connect(gConsoleEvents, SIGNAL(sigAdditionsChange()),
    1053             this, SLOT(sltAdditionsChange()));
    1054 
    1055     connect(gConsoleEvents, SIGNAL(sigVRDEChange()),
    1056             this, SLOT(sltVRDEChange()));
    1057 
    1058     connect(gConsoleEvents, SIGNAL(sigVideoCaptureChange()),
    1059             this, SLOT(sltVideoCaptureChange()));
    1060 
    1061     connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
    1062             this, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)));
    1063 
    1064     connect(gConsoleEvents, SIGNAL(sigMediumChange(CMediumAttachment)),
    1065             this, SIGNAL(sigMediumChange(CMediumAttachment)));
    1066 
    1067     connect(gConsoleEvents, SIGNAL(sigUSBControllerChange()),
    1068             this, SIGNAL(sigUSBControllerChange()));
    1069 
    1070     connect(gConsoleEvents, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)),
    1071             this, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)));
    1072 
    1073     connect(gConsoleEvents, SIGNAL(sigSharedFolderChange()),
    1074             this, SIGNAL(sigSharedFolderChange()));
    1075 
    1076     connect(gConsoleEvents, SIGNAL(sigRuntimeError(bool, QString, QString)),
    1077             this, SIGNAL(sigRuntimeError(bool, QString, QString)));
    1078 
    1079 #ifdef Q_WS_MAC
    1080     connect(gConsoleEvents, SIGNAL(sigShowWindow()),
    1081             this, SIGNAL(sigShowWindows()), Qt::QueuedConnection);
    1082 #endif /* Q_WS_MAC */
    1083 
    1084     connect(gConsoleEvents, SIGNAL(sigCPUExecutionCapChange()),
    1085             this, SIGNAL(sigCPUExecutionCapChange()));
    1086 
    1087     connect(gConsoleEvents, SIGNAL(sigGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)),
    1088             this, SLOT(sltGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)));
    10891005}
    10901006
     
    12001116}
    12011117
     1118void UISession::prepareConsoleEventHandlers()
     1119{
     1120    /* Create console event-handler: */
     1121    UIConsoleEventHandler::create(this);
     1122
     1123    /* Add console event connections: */
     1124    connect(gConsoleEvents, SIGNAL(sigMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)),
     1125            this, SLOT(sltMousePointerShapeChange(bool, bool, QPoint, QSize, QVector<uint8_t>)));
     1126
     1127    connect(gConsoleEvents, SIGNAL(sigMouseCapabilityChange(bool, bool, bool, bool)),
     1128            this, SLOT(sltMouseCapabilityChange(bool, bool, bool, bool)));
     1129
     1130    connect(gConsoleEvents, SIGNAL(sigKeyboardLedsChangeEvent(bool, bool, bool)),
     1131            this, SLOT(sltKeyboardLedsChangeEvent(bool, bool, bool)));
     1132
     1133    connect(gConsoleEvents, SIGNAL(sigStateChange(KMachineState)),
     1134            this, SLOT(sltStateChange(KMachineState)));
     1135
     1136    connect(gConsoleEvents, SIGNAL(sigAdditionsChange()),
     1137            this, SLOT(sltAdditionsChange()));
     1138
     1139    connect(gConsoleEvents, SIGNAL(sigVRDEChange()),
     1140            this, SLOT(sltVRDEChange()));
     1141
     1142    connect(gConsoleEvents, SIGNAL(sigVideoCaptureChange()),
     1143            this, SLOT(sltVideoCaptureChange()));
     1144
     1145    connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
     1146            this, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)));
     1147
     1148    connect(gConsoleEvents, SIGNAL(sigMediumChange(CMediumAttachment)),
     1149            this, SIGNAL(sigMediumChange(CMediumAttachment)));
     1150
     1151    connect(gConsoleEvents, SIGNAL(sigUSBControllerChange()),
     1152            this, SIGNAL(sigUSBControllerChange()));
     1153
     1154    connect(gConsoleEvents, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)),
     1155            this, SIGNAL(sigUSBDeviceStateChange(CUSBDevice, bool, CVirtualBoxErrorInfo)));
     1156
     1157    connect(gConsoleEvents, SIGNAL(sigSharedFolderChange()),
     1158            this, SIGNAL(sigSharedFolderChange()));
     1159
     1160    connect(gConsoleEvents, SIGNAL(sigRuntimeError(bool, QString, QString)),
     1161            this, SIGNAL(sigRuntimeError(bool, QString, QString)));
     1162
     1163#ifdef Q_WS_MAC
     1164    connect(gConsoleEvents, SIGNAL(sigShowWindow()),
     1165            this, SIGNAL(sigShowWindows()), Qt::QueuedConnection);
     1166#endif /* Q_WS_MAC */
     1167
     1168    connect(gConsoleEvents, SIGNAL(sigCPUExecutionCapChange()),
     1169            this, SIGNAL(sigCPUExecutionCapChange()));
     1170
     1171    connect(gConsoleEvents, SIGNAL(sigGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)),
     1172            this, SLOT(sltGuestMonitorChange(KGuestMonitorChangedEventType, ulong, QRect)));
     1173}
     1174
    12021175void UISession::prepareScreens()
    12031176{
     
    13991372        m_session.detach();
    14001373    }
     1374}
     1375
     1376void UISession::cleanup()
     1377{
     1378#ifdef Q_WS_WIN
     1379    /* Destroy alpha cursor: */
     1380    if (m_alphaCursor)
     1381        DestroyIcon(m_alphaCursor);
     1382#endif /* Q_WS_WIN */
     1383
     1384    /* Save settings: */
     1385    saveSessionSettings();
     1386
     1387    /* Cleanup framebuffers: */
     1388    cleanupFramebuffers();
     1389
     1390    /* Cleanup console event-handlers: */
     1391    cleanupConsoleEventHandlers();
     1392
     1393    /* Cleanup connections: */
     1394    cleanupConnections();
     1395
     1396    /* Cleanup actions: */
     1397    cleanupActions();
     1398
     1399    /* Cleanup session: */
     1400    cleanupSession();
    14011401}
    14021402
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