Changeset 53001 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Oct 8, 2014 4:59:48 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
r53000 r53001 159 159 delete pSession; 160 160 pSession = 0; 161 } 162 163 void 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 329 bool 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 356 bool 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 371 bool 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 424 void UISession::closeRuntimeUI() 425 { 426 /* Start corresponding slot asynchronously: */ 427 emit sigCloseRuntimeUI(); 428 } 429 430 UIMachineLogic* UISession::machineLogic() const 431 { 432 return uimachine()->machineLogic(); 433 } 434 435 QWidget* UISession::mainMachineWindow() const 436 { 437 return machineLogic()->mainMachineWindow(); 438 } 439 440 bool UISession::isVisualStateAllowed(UIVisualStateType state) const 441 { 442 return m_pMachine->isVisualStateAllowed(state); 443 } 444 445 void UISession::changeVisualState(UIVisualStateType visualStateType) 446 { 447 m_pMachine->asyncChangeVisualState(visualStateType); 448 } 449 450 bool 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 473 void 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 592 void 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 619 void UISession::sltHandleMenuBarConfigurationChange() 620 { 621 /* Update Mac OS X menu-bar: */ 622 updateMenu(); 623 } 624 #endif /* RT_OS_DARWIN */ 625 626 void 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 651 void 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 676 void 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 708 void 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 722 void 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 740 void 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 750 void 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 */ 779 void 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 */ 794 void 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 840 void 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 851 void 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 862 void UISession::sltHandleHostScreenAvailableAreaChange() 863 { 864 LogRelFlow(("UISession: Host-screen available-area changed.\n")); 865 866 /* Notify current machine-logic: */ 867 emit sigHostScreenAvailableAreaChange(); 868 } 869 870 void 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 } 161 895 } 162 896 … … 215 949 } 216 950 951 UISession::~UISession() 952 { 953 } 954 217 955 bool UISession::prepare() 218 956 { … … 251 989 } 252 990 253 UISession::~UISession()254 {255 }256 257 void UISession::cleanup()258 {259 #ifdef Q_WS_WIN260 /* 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_GUI317 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 else344 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 else360 {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 this379 * 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 else396 fShouldWeClose = msgCenter().warnAboutVirtNotEnabledGuestRequired(fVTxAMDVSupported);397 398 if (fShouldWeClose)399 {400 /* At this point the console is powered up. So we have to close401 * 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 else417 msgCenter().cannotPowerDownMachine(console);418 closeRuntimeUI();419 return;420 }421 422 setPause(false);423 }424 425 #ifdef VBOX_WITH_VIDEOHWACCEL426 LogRel(("2D video acceleration is %s.\n",427 machine.GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()428 ? "enabled"429 : "disabled"));430 #endif431 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 else437 LogRel(("HID LEDs sync is disabled.\n"));438 #else439 LogRel(("HID LEDs sync is not supported on this platform.\n"));440 #endif441 442 #ifdef VBOX_GUI_WITH_PIDFILE443 vboxGlobal().createPidfile();444 #endif445 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 else468 {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 else520 {521 /* Failed in progress: */522 msgCenter().cannotPowerDownMachine(progress, machine.GetName());523 return false;524 }525 }526 else527 {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 else537 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() const552 {553 return uimachine()->machineLogic();554 }555 556 QWidget* UISession::mainMachineWindow() const557 {558 return machineLogic()->mainMachineWindow();559 }560 561 bool UISession::isVisualStateAllowed(UIVisualStateType state) const562 {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 else580 console.Resume();581 582 bool ok = console.isOk();583 if (!ok)584 {585 if (fOn)586 msgCenter().cannotPauseMachine(console);587 else588 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_UI602 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 OS622 * simply isn't supported yet), so silently fall back to "old" .ISO623 * 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 else650 {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 can726 * still hide it and hope it will behave correctly727 * 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_DARWIN740 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 else762 {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 != fSupportsAbsolute782 || m_fIsMouseSupportsRelative != fSupportsRelative783 || m_fIsMouseSupportsMultiTouch != fSupportsMultiTouch784 || 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 != fNumLock801 || m_fCapsLock != fCapsLock802 || 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_DARWIN895 /**896 * MacOS X: Restarts display-reconfiguration watchdog timer from the beginning.897 * @note Watchdog is trying to determine display reconfiguration in898 * 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 else931 {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 else954 {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 1018 991 bool UISession::prepareSession() 1019 992 { … … 1030 1003 /* True by default: */ 1031 1004 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_MAC1080 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)));1089 1005 } 1090 1006 … … 1200 1116 } 1201 1117 1118 void 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 1202 1175 void UISession::prepareScreens() 1203 1176 { … … 1399 1372 m_session.detach(); 1400 1373 } 1374 } 1375 1376 void 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(); 1401 1401 } 1402 1402
Note:
See TracChangeset
for help on using the changeset viewer.