VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp@ 98700

Last change on this file since 98700 was 98700, checked in by vboxsync, 2 years ago

FE/Qt: bugref:10322: Runtime UI: Reworking CMachine wrapper usage step-by-step; DnD related stuff.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 63.0 KB
Line 
1/* $Id: UISession.cpp 98700 2023-02-23 10:13:07Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UISession class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QApplication>
30#include <QWidget>
31#ifdef VBOX_WS_WIN
32# include <iprt/win/windows.h> /* Workaround for compile errors if included directly by QtWin. */
33# include <QtWin>
34#endif
35
36/* GUI includes: */
37#include "UIActionPoolRuntime.h"
38#include "UICommon.h"
39#include "UIConsoleEventHandler.h"
40#include "UIDetailsGenerator.h"
41#include "UIExtraDataManager.h"
42#include "UIFrameBuffer.h"
43#include "UIMachine.h"
44#include "UIMachineLogic.h"
45#include "UIMachineView.h"
46#include "UIMachineWindow.h"
47#include "UIMedium.h"
48#include "UIMessageCenter.h"
49#include "UIMousePointerShapeData.h"
50#include "UINotificationCenter.h"
51#include "UISession.h"
52#include "UISettingsDialogSpecific.h"
53#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
54# include "UIKeyboardHandler.h"
55# include <signal.h>
56#endif
57
58/* COM includes: */
59#include "CEmulatedUSB.h"
60#include "CGraphicsAdapter.h"
61#include "CHostNetworkInterface.h"
62#include "CHostUSBDevice.h"
63#include "CHostVideoInputDevice.h"
64#include "CMedium.h"
65#include "CMediumAttachment.h"
66#include "CSnapshot.h"
67#include "CStorageController.h"
68#include "CSystemProperties.h"
69#include "CUSBController.h"
70#include "CUSBDevice.h"
71#include "CUSBDeviceFilter.h"
72#include "CUSBDeviceFilters.h"
73#ifdef VBOX_WITH_NETFLT
74# include "CNetworkAdapter.h"
75#endif
76
77/* Other VBox includes: */
78#ifdef VBOX_WITH_DEBUGGER_GUI
79# include <VBox/dbggui.h>
80# include <iprt/ldr.h>
81#endif
82
83/* VirtualBox interface declarations: */
84#include <VBox/com/VirtualBox.h>
85
86/* External includes: */
87#ifdef VBOX_WS_X11
88# include <X11/Xlib.h>
89# include <X11/Xutil.h>
90#endif
91
92
93#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
94static void signalHandlerSIGUSR1(int sig, siginfo_t *, void *);
95#endif
96
97/* static */
98bool UISession::create(UISession *&pSession, UIMachine *pMachine)
99{
100 /* Make sure NULL pointer passed: */
101 AssertReturn(!pSession, false);
102
103 /* Create session UI: */
104 pSession = new UISession(pMachine);
105 AssertPtrReturn(pSession, false);
106
107 /* Make sure it's prepared: */
108 if (!pSession->prepare())
109 {
110 /* Destroy session UI otherwise: */
111 destroy(pSession);
112 /* False in that case: */
113 return false;
114 }
115
116 /* True by default: */
117 return true;
118}
119
120/* static */
121void UISession::destroy(UISession *&pSession)
122{
123 /* Make sure valid pointer passed: */
124 AssertPtrReturnVoid(pSession);
125
126 /* Delete session: */
127 delete pSession;
128 pSession = 0;
129}
130
131bool UISession::initialize()
132{
133 /* Preprocess initialization: */
134 if (!preprocessInitialization())
135 return false;
136
137 /* Notify user about mouse&keyboard auto-capturing: */
138 if (gEDataManager->autoCaptureEnabled())
139 UINotificationMessage::remindAboutAutoCapture();
140
141 m_enmMachineState = machine().GetState();
142
143 /* Apply debug settings from the command line. */
144 if (!debugger().isNull() && debugger().isOk())
145 {
146 if (uiCommon().areWeToExecuteAllInIem())
147 debugger().SetExecuteAllInIEM(true);
148 if (!uiCommon().isDefaultWarpPct())
149 debugger().SetVirtualTimeRate(uiCommon().getWarpPct());
150 }
151
152 /* Apply ad-hoc reconfigurations from the command line: */
153 if (uiCommon().hasFloppyImageToMount())
154 mountAdHocImage(KDeviceType_Floppy, UIMediumDeviceType_Floppy, uiCommon().getFloppyImage().toString());
155 if (uiCommon().hasDvdImageToMount())
156 mountAdHocImage(KDeviceType_DVD, UIMediumDeviceType_DVD, uiCommon().getDvdImage().toString());
157
158 /* Power UP if this is NOT separate process: */
159 if (!uiCommon().isSeparateProcess())
160 if (!powerUp())
161 return false;
162
163 /* Make sure all the pending Console events converted to signals
164 * during the powerUp() progress above reached their destinations.
165 * That is necessary to make sure all the pending machine state change events processed.
166 * We can't just use the machine state directly acquired from IMachine because there
167 * will be few places which are using stale machine state, not just this one. */
168 QApplication::sendPostedEvents(0, QEvent::MetaCall);
169
170 /* Check if we missed a really quick termination after successful startup: */
171 if (isTurnedOff())
172 {
173 LogRel(("GUI: Aborting startup due to invalid machine state detected: %d\n", machineState()));
174 return false;
175 }
176
177 /* Fetch corresponding states: */
178 if (uiCommon().isSeparateProcess())
179 {
180 sltAdditionsChange();
181 }
182 machineLogic()->initializePostPowerUp();
183
184#ifdef VBOX_GUI_WITH_PIDFILE
185 uiCommon().createPidfile();
186#endif /* VBOX_GUI_WITH_PIDFILE */
187
188 /* True by default: */
189 return true;
190}
191
192bool UISession::powerUp()
193{
194 /* Power UP machine: */
195 CProgress comProgress = uiCommon().shouldStartPaused() ? console().PowerUpPaused() : console().PowerUp();
196
197 /* Check for immediate failure: */
198 if (!console().isOk() || comProgress.isNull())
199 {
200 if (uiCommon().showStartVMErrors())
201 msgCenter().cannotStartMachine(console(), machineName());
202 LogRel(("GUI: Aborting startup due to power up issue detected...\n"));
203 return false;
204 }
205
206 /* Some logging right after we powered up: */
207 LogRel(("GUI: Qt version: %s\n", UICommon::qtRTVersionString().toUtf8().constData()));
208#ifdef VBOX_WS_X11
209 LogRel(("GUI: X11 Window Manager code: %d\n", (int)uiCommon().typeOfWindowManager()));
210#endif
211#if defined(VBOX_WS_MAC) || defined(VBOX_WS_WIN)
212 LogRel(("GUI: HID LEDs sync is %s\n", uimachine()->isHidLedsSyncEnabled() ? "enabled" : "disabled"));
213#else
214 LogRel(("GUI: HID LEDs sync is not supported on this platform\n"));
215#endif
216
217 /* Enable 'manual-override',
218 * preventing automatic Runtime UI closing
219 * and visual representation mode changes: */
220 uimachine()->setManualOverrideMode(true);
221
222 /* Show "Starting/Restoring" progress dialog: */
223 if (isSaved())
224 {
225 msgCenter().showModalProgressDialog(comProgress, machineName(), ":/progress_state_restore_90px.png", 0, 0);
226 /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
227 machineLogic()->adjustMachineWindowsGeometry();
228 }
229 else
230 {
231#ifdef VBOX_IS_QT6_OR_LATER /** @todo why is this any problem on qt6? */
232 msgCenter().showModalProgressDialog(comProgress, machineName(), ":/progress_start_90px.png", 0, 0);
233#else
234 msgCenter().showModalProgressDialog(comProgress, machineName(), ":/progress_start_90px.png");
235#endif
236 /* After VM start, machine-window(s) size-hint(s) should be sent: */
237 machineLogic()->sendMachineWindowsSizeHints();
238 }
239
240 /* Check for progress failure: */
241 if (!comProgress.isOk() || comProgress.GetResultCode() != 0)
242 {
243 if (uiCommon().showStartVMErrors())
244 msgCenter().cannotStartMachine(comProgress, machineName());
245 LogRel(("GUI: Aborting startup due to power up progress issue detected...\n"));
246 return false;
247 }
248
249 /* Disable 'manual-override' finally: */
250 uimachine()->setManualOverrideMode(false);
251
252 /* True by default: */
253 return true;
254}
255
256WId UISession::mainMachineWindowId() const
257{
258 return mainMachineWindow() ? mainMachineWindow()->winId() : 0;
259}
260
261bool UISession::acquireLiveMachineState(KMachineState &enmState)
262{
263 CMachine comMachine = machine();
264 const KMachineState enmMachineState = comMachine.GetState();
265 const bool fSuccess = comMachine.isOk();
266 if (!fSuccess)
267 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
268 else
269 enmState = enmMachineState;
270 return fSuccess;
271}
272
273bool UISession::reset()
274{
275 CConsole comConsole = console();
276 comConsole.Reset();
277 const bool fSuccess = comConsole.isOk();
278 if (!fSuccess)
279 UINotificationMessage::cannotResetMachine(comConsole);
280 return fSuccess;
281}
282
283bool UISession::setPause(bool fPause)
284{
285 CConsole comConsole = console();
286 if (fPause)
287 comConsole.Pause();
288 else
289 comConsole.Resume();
290 const bool fSuccess = comConsole.isOk();
291 if (!fSuccess)
292 {
293 if (fPause)
294 UINotificationMessage::cannotPauseMachine(comConsole);
295 else
296 UINotificationMessage::cannotResumeMachine(comConsole);
297 }
298 return fSuccess;
299}
300
301bool UISession::acquireSnapshotCount(ulong &uCount)
302{
303 CMachine comMachine = machine();
304 const ULONG uSnapshotCount = comMachine.GetSnapshotCount();
305 const bool fSuccess = comMachine.isOk();
306 if (!fSuccess)
307 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
308 else
309 uCount = uSnapshotCount;
310 return fSuccess;
311}
312
313bool UISession::acquireCurrentSnapshotName(QString &strName)
314{
315 CMachine comMachine = machine();
316 CSnapshot comSnapshot = comMachine.GetCurrentSnapshot();
317 bool fSuccess = comMachine.isOk();
318 if (!fSuccess)
319 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
320 {
321 const QString strSnapshotName = comSnapshot.GetName();
322 fSuccess = comSnapshot.isOk();
323 if (!fSuccess)
324 UINotificationMessage::cannotAcquireSnapshotParameter(comSnapshot);
325 else
326 strName = strSnapshotName;
327 }
328 return fSuccess;
329}
330
331bool UISession::putScancode(LONG iCode)
332{
333 CKeyboard comKeyboard = keyboard();
334 comKeyboard.PutScancode(iCode);
335 const bool fSuccess = comKeyboard.isOk();
336 if (!fSuccess)
337 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
338 return fSuccess;
339}
340
341bool UISession::putScancodes(const QVector<LONG> &codes)
342{
343 CKeyboard comKeyboard = keyboard();
344 comKeyboard.PutScancodes(codes);
345 const bool fSuccess = comKeyboard.isOk();
346 if (!fSuccess)
347 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
348 return fSuccess;
349}
350
351bool UISession::putCAD()
352{
353 CKeyboard comKeyboard = keyboard();
354 comKeyboard.PutCAD();
355 const bool fSuccess = comKeyboard.isOk();
356 if (!fSuccess)
357 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
358 return fSuccess;
359}
360
361bool UISession::releaseKeys()
362{
363 CKeyboard comKeyboard = keyboard();
364 comKeyboard.ReleaseKeys();
365 const bool fSuccess = comKeyboard.isOk();
366 if (!fSuccess)
367 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
368 return fSuccess;
369}
370
371bool UISession::putUsageCode(LONG iUsageCode, LONG iUsagePage, bool fKeyRelease)
372{
373 CKeyboard comKeyboard = keyboard();
374 comKeyboard.PutUsageCode(iUsageCode, iUsagePage, fKeyRelease);
375 const bool fSuccess = comKeyboard.isOk();
376 if (!fSuccess)
377 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
378 return fSuccess;
379}
380
381bool UISession::getAbsoluteSupported()
382{
383 return mouse().GetAbsoluteSupported();
384}
385
386bool UISession::getRelativeSupported()
387{
388 return mouse().GetRelativeSupported();
389}
390
391bool UISession::getTouchScreenSupported()
392{
393 return mouse().GetTouchScreenSupported();
394}
395
396bool UISession::getTouchPadSupported()
397{
398 return mouse().GetTouchPadSupported();
399}
400
401bool UISession::getNeedsHostCursor()
402{
403 return mouse().GetNeedsHostCursor();
404}
405
406bool UISession::putMouseEvent(long iDx, long iDy, long iDz, long iDw, long iButtonState)
407{
408 CMouse comMouse = mouse();
409 comMouse.PutMouseEvent(iDx, iDy, iDz, iDw, iButtonState);
410 const bool fSuccess = comMouse.isOk();
411 if (!fSuccess)
412 UINotificationMessage::cannotChangeMouseParameter(comMouse);
413 return fSuccess;
414}
415
416bool UISession::putMouseEventAbsolute(long iX, long iY, long iDz, long iDw, long iButtonState)
417{
418 CMouse comMouse = mouse();
419 comMouse.PutMouseEventAbsolute(iX, iY, iDz, iDw, iButtonState);
420 const bool fSuccess = comMouse.isOk();
421 if (!fSuccess)
422 UINotificationMessage::cannotChangeMouseParameter(comMouse);
423 return fSuccess;
424}
425
426bool UISession::putEventMultiTouch(long iCount, const QVector<LONG64> &contacts, bool fIsTouchScreen, ulong uScanTime)
427{
428 CMouse comMouse = mouse();
429 comMouse.PutEventMultiTouch(iCount, contacts, fIsTouchScreen, uScanTime);
430 const bool fSuccess = comMouse.isOk();
431 if (!fSuccess)
432 UINotificationMessage::cannotChangeMouseParameter(comMouse);
433 return fSuccess;
434}
435
436#ifdef VBOX_WITH_DRAG_AND_DROP
437bool UISession::acquireDnDMode(KDnDMode &enmMode)
438{
439 CMachine comMachine = machine();
440 const KDnDMode enmDnDMode = comMachine.GetDnDMode();
441 const bool fSuccess = comMachine.isOk();
442 if (!fSuccess)
443 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
444 else
445 enmMode = enmDnDMode;
446 return fSuccess;
447}
448#endif /* VBOX_WITH_DRAG_AND_DROP */
449
450bool UISession::addEncryptionPassword(const QString &strId, const QString &strPassword, bool fClearOnSuspend)
451{
452 CConsole comConsole = console();
453 comConsole.AddEncryptionPassword(strId, strPassword, fClearOnSuspend);
454 const bool fSuccess = comConsole.isOk();
455 if (!fSuccess)
456 msgCenter().cannotAddDiskEncryptionPassword(comConsole);
457 return fSuccess;
458}
459
460bool UISession::usbDevices(QList<USBDeviceInfo> &guiUSBDevices)
461{
462 const CHost comHost = uiCommon().host();
463 const CHostUSBDeviceVector comHostUSBDevices = comHost.GetUSBDevices();
464 bool fSuccess = comHost.isOk();
465 if (!fSuccess)
466 UINotificationMessage::cannotAcquireHostParameter(comHost);
467 else
468 {
469 foreach (const CHostUSBDevice &comHostUSBDevice, comHostUSBDevices)
470 {
471 /* Get USB device from current host USB device,
472 * this stuff requires #include <VBox/com/VirtualBox.h> */
473 const CUSBDevice comUSBDevice(comHostUSBDevice);
474
475 /* Fill structure fields: */
476 USBDeviceInfo guiUSBDevice;
477 if (fSuccess)
478 {
479 guiUSBDevice.m_uId = comUSBDevice.GetId();
480 fSuccess = comUSBDevice.isOk();
481 }
482 if (fSuccess)
483 {
484 /// @todo make sure UICommon::usbDetails is checked for errors as well
485 guiUSBDevice.m_strName = uiCommon().usbDetails(comUSBDevice);
486 fSuccess = comUSBDevice.isOk();
487 }
488 if (fSuccess)
489 {
490 /// @todo make sure UICommon::usbToolTip is checked for errors as well
491 guiUSBDevice.m_strToolTip = uiCommon().usbToolTip(comUSBDevice);
492 fSuccess = comUSBDevice.isOk();
493 }
494 if (fSuccess)
495 {
496 /* Check if that USB device was already attached to this session;
497 * Nothing to check for errors here because error is valid case as well. */
498 const CUSBDevice comAttachedDevice = console().FindUSBDeviceById(guiUSBDevice.m_uId);
499 guiUSBDevice.m_fIsChecked = !comAttachedDevice.isNull();
500 }
501 if (fSuccess)
502 {
503 guiUSBDevice.m_fIsEnabled = comHostUSBDevice.GetState() != KUSBDeviceState_Unavailable;
504 fSuccess = comHostUSBDevice.isOk();
505 }
506
507 /* Append or break if necessary: */
508 if (fSuccess)
509 guiUSBDevices << guiUSBDevice;
510 else
511 break;
512 }
513 }
514 return fSuccess;
515}
516
517bool UISession::attachUSBDevice(const QUuid &uId)
518{
519 CConsole comConsole = console();
520 comConsole.AttachUSBDevice(uId, QString(""));
521 const bool fSuccess = comConsole.isOk();
522 if (!fSuccess)
523 {
524 CHost comHost = uiCommon().host();
525 /* Nothing to check for errors here because error is valid case as well. */
526 CHostUSBDevice comHostUSBDevice = comHost.FindUSBDeviceById(uId);
527 /* Get USB device from current host USB device,
528 * this stuff requires #include <VBox/com/VirtualBox.h> */
529 CUSBDevice comUSBDevice(comHostUSBDevice);
530 UINotificationMessage::cannotAttachUSBDevice(comConsole, uiCommon().usbDetails(comUSBDevice));
531 /// @todo make sure UICommon::usbDetails is checked for errors as well
532 }
533 return fSuccess;
534}
535
536bool UISession::detachUSBDevice(const QUuid &uId)
537{
538 CConsole comConsole = console();
539 comConsole.DetachUSBDevice(uId);
540 const bool fSuccess = comConsole.isOk();
541 if (!fSuccess)
542 {
543 CUSBDevice comUSBDevice = CConsole(comConsole).FindUSBDeviceById(uId);
544 UINotificationMessage::cannotDetachUSBDevice(comConsole, uiCommon().usbDetails(comUSBDevice));
545 /// @todo make sure UICommon::usbDetails is checked for errors as well
546 }
547 return fSuccess;
548}
549
550bool UISession::webcamDevices(QList<WebcamDeviceInfo> &guiWebcamDevices)
551{
552 const CHost comHost = uiCommon().host();
553 const CHostVideoInputDeviceVector comHostVideoInputDevices = comHost.GetVideoInputDevices();
554 bool fSuccess = comHost.isOk();
555 if (!fSuccess)
556 UINotificationMessage::cannotAcquireHostParameter(comHost);
557 else
558 {
559 CConsole comConsole = console();
560 CEmulatedUSB comEmulatedUSB = comConsole.GetEmulatedUSB();
561 fSuccess = comConsole.isOk();
562 if (!fSuccess)
563 UINotificationMessage::cannotAcquireConsoleParameter(comConsole);
564 else
565 {
566 const QVector<QString> attachedWebcamPaths = comEmulatedUSB.GetWebcams();
567 fSuccess = comEmulatedUSB.isOk();
568 if (!fSuccess)
569 UINotificationMessage::cannotAcquireEmulatedUSBParameter(comEmulatedUSB);
570 else
571 {
572 foreach (const CHostVideoInputDevice &comHostVideoInputDevice, comHostVideoInputDevices)
573 {
574 /* Fill structure fields: */
575 WebcamDeviceInfo guiWebcamDevice;
576 if (fSuccess)
577 {
578 guiWebcamDevice.m_strName = comHostVideoInputDevice.GetName();
579 fSuccess = comHostVideoInputDevice.isOk();
580 }
581 if (fSuccess)
582 {
583 guiWebcamDevice.m_strPath = comHostVideoInputDevice.GetPath();
584 fSuccess = comHostVideoInputDevice.isOk();
585 }
586 if (fSuccess)
587 {
588 /// @todo make sure UICommon::usbToolTip is checked for errors as well
589 guiWebcamDevice.m_strToolTip = uiCommon().usbToolTip(comHostVideoInputDevice);
590 fSuccess = comHostVideoInputDevice.isOk();
591 }
592 if (fSuccess)
593 guiWebcamDevice.m_fIsChecked = attachedWebcamPaths.contains(guiWebcamDevice.m_strPath);
594
595 /* Append or break if necessary: */
596 if (fSuccess)
597 guiWebcamDevices << guiWebcamDevice;
598 else
599 break;
600 }
601 }
602 }
603 }
604 return fSuccess;
605}
606
607bool UISession::webcamAttach(const QString &strPath, const QString &strName)
608{
609 CConsole comConsole = console();
610 CEmulatedUSB comDispatcher = comConsole.GetEmulatedUSB();
611 bool fSuccess = comConsole.isOk();
612 if (!fSuccess)
613 UINotificationMessage::cannotAcquireConsoleParameter(comConsole);
614 else
615 {
616 comDispatcher.WebcamAttach(strPath, "");
617 fSuccess = comDispatcher.isOk();
618 if (!fSuccess)
619 UINotificationMessage::cannotAttachWebCam(comDispatcher, strName, machineName());
620 }
621 return fSuccess;
622}
623
624bool UISession::webcamDetach(const QString &strPath, const QString &strName)
625{
626 CConsole comConsole = console();
627 CEmulatedUSB comDispatcher = comConsole.GetEmulatedUSB();
628 bool fSuccess = comConsole.isOk();
629 if (!fSuccess)
630 UINotificationMessage::cannotAcquireConsoleParameter(comConsole);
631 else
632 {
633 comDispatcher.WebcamDetach(strPath);
634 fSuccess = comDispatcher.isOk();
635 if (!fSuccess)
636 UINotificationMessage::cannotDetachWebCam(comDispatcher, strName, machineName());
637 }
638 return fSuccess;
639}
640
641bool UISession::guestAdditionsUpgradable()
642{
643 if (!machine().isOk())
644 return false;
645
646 /* Auto GA update is currently for Windows and Linux guests only */
647 const CGuestOSType osType = uiCommon().vmGuestOSType(machine().GetOSTypeId());
648 if (!osType.isOk())
649 return false;
650
651 const QString strGuestFamily = osType.GetFamilyId();
652 bool fIsWindowOrLinux = strGuestFamily.contains("windows", Qt::CaseInsensitive) || strGuestFamily.contains("linux", Qt::CaseInsensitive);
653
654 if (!fIsWindowOrLinux)
655 return false;
656
657 /* Also check whether we have something to update automatically: */
658 if (m_ulGuestAdditionsRunLevel < (ulong)KAdditionsRunLevelType_Userland)
659 return false;
660
661 return true;
662}
663
664UIFrameBuffer *UISession::frameBuffer(ulong uScreenId) const
665{
666 Assert(uScreenId < (ulong)m_frameBufferVector.size());
667 return m_frameBufferVector.value((int)uScreenId, 0);
668}
669
670void UISession::setFrameBuffer(ulong uScreenId, UIFrameBuffer *pFrameBuffer)
671{
672 Assert(uScreenId < (ulong)m_frameBufferVector.size());
673 if (uScreenId < (ulong)m_frameBufferVector.size())
674 m_frameBufferVector[(int)uScreenId] = pFrameBuffer;
675}
676
677QSize UISession::frameBufferSize(ulong uScreenId) const
678{
679 UIFrameBuffer *pFramebuffer = frameBuffer(uScreenId);
680 return pFramebuffer ? QSize(pFramebuffer->width(), pFramebuffer->height()) : QSize();
681}
682
683bool UISession::acquireGraphicsControllerType(KGraphicsControllerType &enmType)
684{
685 CMachine comMachine = machine();
686 CGraphicsAdapter comAdapter = comMachine.GetGraphicsAdapter();
687 bool fSuccess = comMachine.isOk();
688 if (!fSuccess)
689 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
690 else
691 {
692 const KGraphicsControllerType enmControllerType = comAdapter.GetGraphicsControllerType();
693 fSuccess = comAdapter.isOk();
694 if (!fSuccess)
695 UINotificationMessage::cannotAcquireGraphicsAdapterParameter(comAdapter);
696 else
697 enmType = enmControllerType;
698 }
699 return fSuccess;
700}
701
702bool UISession::acquireVRAMSize(ulong &uSize)
703{
704 CMachine comMachine = machine();
705 CGraphicsAdapter comAdapter = comMachine.GetGraphicsAdapter();
706 bool fSuccess = comMachine.isOk();
707 if (!fSuccess)
708 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
709 else
710 {
711 const ULONG uVRAMSize = comAdapter.GetVRAMSize();
712 fSuccess = comAdapter.isOk();
713 if (!fSuccess)
714 UINotificationMessage::cannotAcquireGraphicsAdapterParameter(comAdapter);
715 else
716 uSize = uVRAMSize;
717 }
718 return fSuccess;
719}
720
721bool UISession::acquireWhetherAccelerate3DEnabled(bool &fEnabled)
722{
723 CMachine comMachine = machine();
724 CGraphicsAdapter comAdapter = comMachine.GetGraphicsAdapter();
725 bool fSuccess = comMachine.isOk();
726 if (!fSuccess)
727 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
728 else
729 {
730 const BOOL fAccelerate3DEnabeld = comAdapter.GetAccelerate3DEnabled();
731 fSuccess = comAdapter.isOk();
732 if (!fSuccess)
733 UINotificationMessage::cannotAcquireGraphicsAdapterParameter(comAdapter);
734 else
735 fEnabled = fAccelerate3DEnabeld == TRUE;
736 }
737 return fSuccess;
738}
739
740bool UISession::acquireMonitorCount(ulong &uCount)
741{
742 CMachine comMachine = machine();
743 CGraphicsAdapter comAdapter = comMachine.GetGraphicsAdapter();
744 bool fSuccess = comMachine.isOk();
745 if (!fSuccess)
746 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
747 else
748 {
749 const ULONG uMonitorCount = comAdapter.GetMonitorCount();
750 fSuccess = comAdapter.isOk();
751 if (!fSuccess)
752 UINotificationMessage::cannotAcquireGraphicsAdapterParameter(comAdapter);
753 else
754 uCount = uMonitorCount;
755 }
756 return fSuccess;
757}
758
759bool UISession::acquireGuestScreenParameters(ulong uScreenId,
760 ulong &uWidth, ulong &uHeight, ulong &uBitsPerPixel,
761 long &xOrigin, long &yOrigin, KGuestMonitorStatus &enmMonitorStatus)
762{
763 CDisplay comDisplay = display();
764 ULONG uGuestWidth = 0, uGuestHeight = 0, uGuestBitsPerPixel = 0;
765 LONG iGuestXOrigin = 0, iGuestYOrigin = 0;
766 KGuestMonitorStatus enmGuestMonitorStatus = KGuestMonitorStatus_Disabled;
767 comDisplay.GetScreenResolution(uScreenId, uGuestWidth, uGuestHeight, uGuestBitsPerPixel,
768 iGuestXOrigin, iGuestYOrigin, enmGuestMonitorStatus);
769 const bool fSuccess = comDisplay.isOk();
770 if (!fSuccess)
771 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
772 else
773 {
774 uWidth = uGuestWidth;
775 uHeight = uGuestHeight;
776 uBitsPerPixel = uGuestBitsPerPixel;
777 xOrigin = iGuestXOrigin;
778 yOrigin = iGuestYOrigin;
779 enmMonitorStatus = enmGuestMonitorStatus;
780 }
781 return fSuccess;
782}
783
784bool UISession::acquireSavedGuestScreenInfo(ulong uScreenId,
785 long &xOrigin, long &yOrigin,
786 ulong &uWidth, ulong &uHeight, bool &fEnabled)
787{
788 CMachine comMachine = machine();
789 ULONG uGuestXOrigin = 0, uGuestYOrigin = 0, uGuestWidth = 0, uGuestHeight = 0;
790 BOOL fGuestEnabled = FALSE;
791 comMachine.QuerySavedGuestScreenInfo(uScreenId, uGuestXOrigin, uGuestYOrigin, uGuestWidth, uGuestHeight, fGuestEnabled);
792 const bool fSuccess = comMachine.isOk();
793 if (!fSuccess)
794 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
795 else
796 {
797 xOrigin = uGuestXOrigin;
798 yOrigin = uGuestYOrigin;
799 uWidth = uGuestWidth;
800 uHeight = uGuestHeight;
801 fEnabled = fGuestEnabled == TRUE;
802 }
803 return fSuccess;
804}
805
806bool UISession::setVideoModeHint(ulong uScreenId, bool fEnabled, bool fChangeOrigin, long xOrigin, long yOrigin,
807 ulong uWidth, ulong uHeight, ulong uBitsPerPixel, bool fNotify)
808{
809 CDisplay comDisplay = display();
810 comDisplay.SetVideoModeHint(uScreenId, fEnabled, fChangeOrigin, xOrigin, yOrigin,
811 uWidth, uHeight, uBitsPerPixel, fNotify);
812 const bool fSuccess = comDisplay.isOk();
813 if (!fSuccess)
814 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
815 return fSuccess;
816}
817
818bool UISession::acquireVideoModeHint(ulong uScreenId, bool &fEnabled, bool &fChangeOrigin,
819 long &xOrigin, long &yOrigin, ulong &uWidth, ulong &uHeight,
820 ulong &uBitsPerPixel)
821{
822 CDisplay comDisplay = display();
823 BOOL fGuestEnabled = FALSE, fGuestChangeOrigin = FALSE;
824 LONG iGuestXOrigin = 0, iGuestYOrigin = 0;
825 ULONG uGuestWidth = 0, uGuestHeight = 0, uGuestBitsPerPixel = 0;
826 comDisplay.GetVideoModeHint(uScreenId, fGuestEnabled, fGuestChangeOrigin,
827 iGuestXOrigin, iGuestYOrigin, uGuestWidth, uGuestHeight,
828 uGuestBitsPerPixel);
829 const bool fSuccess = comDisplay.isOk();
830 if (!fSuccess)
831 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
832 else
833 {
834 fEnabled = fGuestEnabled == TRUE;
835 fChangeOrigin = fGuestChangeOrigin == TRUE;
836 xOrigin = iGuestXOrigin;
837 yOrigin = iGuestYOrigin;
838 uWidth = uGuestWidth;
839 uHeight = uGuestHeight;
840 uBitsPerPixel = uGuestBitsPerPixel;
841 }
842 return fSuccess;
843}
844
845bool UISession::acquireScreenShot(ulong uScreenId, ulong uWidth, ulong uHeight, KBitmapFormat enmFormat, uchar *pBits)
846{
847 CDisplay comDisplay = display();
848 bool fSuccess = false;
849 /* For separate process: */
850 if (uiCommon().isSeparateProcess())
851 {
852 /* Take screen-data to array first: */
853 const QVector<BYTE> screenData = comDisplay.TakeScreenShotToArray(uScreenId, uWidth, uHeight, enmFormat);
854 fSuccess = comDisplay.isOk();
855 if (!fSuccess)
856 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
857 else
858 {
859 /* And copy that data to screen-shot if it is Ok: */
860 if (!screenData.isEmpty())
861 memcpy(pBits, screenData.data(), uWidth * uHeight * 4);
862 }
863 }
864 /* For the same process: */
865 else
866 {
867 /* Take the screen-shot directly: */
868 comDisplay.TakeScreenShot(uScreenId, pBits, uWidth, uHeight, enmFormat);
869 fSuccess = comDisplay.isOk();
870 if (!fSuccess)
871 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
872 }
873 return fSuccess;
874}
875
876bool UISession::acquireSavedScreenshotInfo(ulong uScreenId, ulong &uWidth, ulong &uHeight, QVector<KBitmapFormat> &formats)
877{
878 CMachine comMachine = machine();
879 ULONG uGuestWidth = 0, uGuestHeight = 0;
880 QVector<KBitmapFormat> guestFormats = comMachine.QuerySavedScreenshotInfo(uScreenId, uGuestWidth, uGuestHeight);
881 const bool fSuccess = comMachine.isOk();
882 if (!fSuccess)
883 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
884 else
885 {
886 uWidth = uGuestWidth;
887 uHeight = uGuestHeight;
888 formats = guestFormats;
889 }
890 return fSuccess;
891}
892
893bool UISession::acquireSavedScreenshot(ulong uScreenId, KBitmapFormat enmFormat,
894 ulong &uWidth, ulong &uHeight, QVector<BYTE> &screenshot)
895{
896 CMachine comMachine = machine();
897 ULONG uGuestWidth = 0, uGuestHeight = 0;
898 const QVector<BYTE> guestScreenshot = comMachine.ReadSavedScreenshotToArray(uScreenId, enmFormat,
899 uGuestWidth, uGuestHeight);
900 const bool fSuccess = comMachine.isOk();
901 if (!fSuccess)
902 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
903 else
904 {
905 uWidth = uGuestWidth;
906 uHeight = uGuestHeight;
907 screenshot = guestScreenshot;
908 }
909 return fSuccess;
910}
911
912bool UISession::notifyScaleFactorChange(ulong uScreenId, ulong uScaleFactorWMultiplied, ulong uScaleFactorHMultiplied)
913{
914 CDisplay comDisplay = display();
915 comDisplay.NotifyScaleFactorChange(uScreenId, uScaleFactorWMultiplied, uScaleFactorHMultiplied);
916 const bool fSuccess = comDisplay.isOk();
917 if (!fSuccess)
918 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
919 return fSuccess;
920}
921
922bool UISession::notifyHiDPIOutputPolicyChange(bool fUnscaledHiDPI)
923{
924 CDisplay comDisplay = display();
925 comDisplay.NotifyHiDPIOutputPolicyChange(fUnscaledHiDPI);
926 const bool fSuccess = comDisplay.isOk();
927 if (!fSuccess)
928 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
929 return fSuccess;
930}
931
932bool UISession::setSeamlessMode(bool fEnabled)
933{
934 CDisplay comDisplay = display();
935 comDisplay.SetSeamlessMode(fEnabled);
936 const bool fSuccess = comDisplay.isOk();
937 if (!fSuccess)
938 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
939 return fSuccess;
940}
941
942bool UISession::viewportChanged(ulong uScreenId, ulong xOrigin, ulong yOrigin, ulong uWidth, ulong uHeight)
943{
944 CDisplay comDisplay = display();
945 comDisplay.ViewportChanged(uScreenId, xOrigin, yOrigin, uWidth, uHeight);
946 const bool fSuccess = comDisplay.isOk();
947 if (!fSuccess)
948 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
949 return fSuccess;
950}
951
952bool UISession::invalidateAndUpdate()
953{
954 CDisplay comDisplay = display();
955 comDisplay.InvalidateAndUpdate();
956 const bool fSuccess = comDisplay.isOk();
957 if (!fSuccess)
958 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
959 return fSuccess;
960}
961
962bool UISession::invalidateAndUpdateScreen(ulong uScreenId)
963{
964 CDisplay comDisplay = display();
965 comDisplay.InvalidateAndUpdateScreen(uScreenId);
966 const bool fSuccess = comDisplay.isOk();
967 if (!fSuccess)
968 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
969 return fSuccess;
970}
971
972bool UISession::acquireDeviceActivity(const QVector<KDeviceType> &deviceTypes, QVector<KDeviceActivity> &states)
973{
974 CConsole comConsole = console();
975 const QVector<KDeviceActivity> currentStates = comConsole.GetDeviceActivity(deviceTypes);
976 const bool fSuccess = comConsole.isOk();
977 if (!fSuccess)
978 UINotificationMessage::cannotAcquireConsoleParameter(comConsole);
979 else
980 states = currentStates;
981 return fSuccess;
982}
983
984void UISession::acquireHardDiskStatusInfo(QString &strInfo, bool &fAttachmentsPresent)
985{
986 CMachine comMachine = machine();
987 UIDetailsGenerator::acquireHardDiskStatusInfo(comMachine, strInfo, fAttachmentsPresent);
988}
989
990void UISession::acquireOpticalDiskStatusInfo(QString &strInfo, bool &fAttachmentsPresent, bool &fAttachmentsMounted)
991{
992 CMachine comMachine = machine();
993 UIDetailsGenerator::acquireOpticalDiskStatusInfo(comMachine, strInfo, fAttachmentsPresent, fAttachmentsMounted);
994}
995
996void UISession::acquireFloppyDiskStatusInfo(QString &strInfo, bool &fAttachmentsPresent, bool &fAttachmentsMounted)
997{
998 CMachine comMachine = machine();
999 UIDetailsGenerator::acquireFloppyDiskStatusInfo(comMachine, strInfo, fAttachmentsPresent, fAttachmentsMounted);
1000}
1001
1002void UISession::acquireAudioStatusInfo(QString &strInfo, bool &fAudioEnabled, bool &fEnabledOutput, bool &fEnabledInput)
1003{
1004 CMachine comMachine = machine();
1005 UIDetailsGenerator::acquireAudioStatusInfo(comMachine, strInfo, fAudioEnabled, fEnabledOutput, fEnabledInput);
1006}
1007
1008void UISession::acquireNetworkStatusInfo(QString &strInfo, bool &fAdaptersPresent, bool &fCablesDisconnected)
1009{
1010 CMachine comMachine = machine();
1011 UIDetailsGenerator::acquireNetworkStatusInfo(comMachine, strInfo, fAdaptersPresent, fCablesDisconnected);
1012}
1013
1014void UISession::acquireUsbStatusInfo(QString &strInfo, bool &fUsbEnableds)
1015{
1016 CMachine comMachine = machine();
1017 CConsole comConsole = console();
1018 UIDetailsGenerator::acquireUsbStatusInfo(comMachine, comConsole, strInfo, fUsbEnableds);
1019}
1020
1021void UISession::acquireSharedFoldersStatusInfo(QString &strInfo, bool &fFoldersPresent)
1022{
1023 CMachine comMachine = machine();
1024 CConsole comConsole = console();
1025 CGuest comGuest = guest();
1026 UIDetailsGenerator::acquireSharedFoldersStatusInfo(comMachine, comConsole, comGuest, strInfo, fFoldersPresent);
1027}
1028
1029void UISession::acquireDisplayStatusInfo(QString &strInfo, bool &fAcceleration3D)
1030{
1031 CMachine comMachine = machine();
1032 UIDetailsGenerator::acquireDisplayStatusInfo(comMachine, strInfo, fAcceleration3D);
1033}
1034
1035void UISession::acquireRecordingStatusInfo(QString &strInfo, bool &fRecordingEnabled, bool &fMachinePaused)
1036{
1037 CMachine comMachine = machine();
1038 fMachinePaused = isPaused();
1039 UIDetailsGenerator::acquireRecordingStatusInfo(comMachine, strInfo, fRecordingEnabled);
1040}
1041
1042void UISession::acquireFeaturesStatusInfo(QString &strInfo, KVMExecutionEngine &enmEngine,
1043 bool fNestedPagingEnabled, bool fUxEnabled,
1044 KParavirtProvider enmProvider)
1045{
1046 CMachine comMachine = machine();
1047 UIDetailsGenerator::acquireFeaturesStatusInfo(comMachine, strInfo,
1048 enmEngine,
1049 fNestedPagingEnabled, fUxEnabled,
1050 enmProvider);
1051}
1052
1053bool UISession::setLogEnabled(bool fEnabled)
1054{
1055 CMachineDebugger comDebugger = debugger();
1056 comDebugger.SetLogEnabled(fEnabled ? TRUE : FALSE);
1057 const bool fSuccess = comDebugger.isOk();
1058 if (!fSuccess)
1059 UINotificationMessage::cannotChangeMachineDebuggerParameter(comDebugger);
1060 return fSuccess;
1061}
1062
1063bool UISession::acquireWhetherLogEnabled(bool &fEnabled)
1064{
1065 CMachineDebugger comDebugger = debugger();
1066 const BOOL fLogEnabled = comDebugger.GetLogEnabled();
1067 const bool fSuccess = comDebugger.isOk();
1068 if (!fSuccess)
1069 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
1070 else
1071 fEnabled = fLogEnabled == TRUE;
1072 return fSuccess;
1073}
1074
1075bool UISession::acquireExecutionEngineType(KVMExecutionEngine &enmType)
1076{
1077 CMachineDebugger comDebugger = debugger();
1078 const KVMExecutionEngine enmEngineType = comDebugger.GetExecutionEngine();
1079 const bool fSuccess = comDebugger.isOk();
1080 if (!fSuccess)
1081 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
1082 else
1083 enmType = enmEngineType;
1084 return fSuccess;
1085}
1086
1087bool UISession::acquireWhetherHwVirtExNestedPagingEnabled(bool &fEnabled)
1088{
1089 CMachineDebugger comDebugger = debugger();
1090 const BOOL fFeatureEnabled = comDebugger.GetHWVirtExNestedPagingEnabled();
1091 const bool fSuccess = comDebugger.isOk();
1092 if (!fSuccess)
1093 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
1094 else
1095 fEnabled = fFeatureEnabled == TRUE;
1096 return fSuccess;
1097}
1098
1099bool UISession::acquireWhetherHwVirtExUXEnabled(bool &fEnabled)
1100{
1101 CMachineDebugger comDebugger = debugger();
1102 const BOOL fFeatureEnabled = comDebugger.GetHWVirtExUXEnabled();
1103 const bool fSuccess = comDebugger.isOk();
1104 if (!fSuccess)
1105 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
1106 else
1107 fEnabled = fFeatureEnabled == TRUE;
1108 return fSuccess;
1109}
1110
1111bool UISession::acquireEffectiveCPULoad(ulong &uLoad)
1112{
1113 CMachineDebugger comDebugger = debugger();
1114 ULONG uPctExecuting;
1115 ULONG uPctHalted;
1116 ULONG uPctOther;
1117 comDebugger.GetCPULoad(0x7fffffff, uPctExecuting, uPctHalted, uPctOther);
1118 const bool fSuccess = comDebugger.isOk();
1119 if (!fSuccess)
1120 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
1121 else
1122 uLoad = uPctExecuting + uPctOther;
1123 return fSuccess;
1124}
1125
1126#ifdef VBOX_WITH_DEBUGGER_GUI
1127bool UISession::dbgCreated(void *pActionDebug)
1128{
1129 if (m_pDbgGui)
1130 return true;
1131
1132 RTLDRMOD hLdrMod = uiCommon().getDebuggerModule();
1133 if (hLdrMod == NIL_RTLDRMOD)
1134 return false;
1135
1136 PFNDBGGUICREATE pfnGuiCreate;
1137 int rc = RTLdrGetSymbol(hLdrMod, "DBGGuiCreate", (void**)&pfnGuiCreate);
1138 if (RT_SUCCESS(rc))
1139 {
1140 ISession *pISession = session().raw();
1141 rc = pfnGuiCreate(pISession, &m_pDbgGui, &m_pDbgGuiVT);
1142 if (RT_SUCCESS(rc))
1143 {
1144 if ( DBGGUIVT_ARE_VERSIONS_COMPATIBLE(m_pDbgGuiVT->u32Version, DBGGUIVT_VERSION)
1145 || m_pDbgGuiVT->u32EndVersion == m_pDbgGuiVT->u32Version)
1146 {
1147 m_pDbgGuiVT->pfnSetParent(m_pDbgGui, activeMachineWindow());
1148 m_pDbgGuiVT->pfnSetMenu(m_pDbgGui, pActionDebug);
1149 dbgAdjustRelativePos();
1150 return true;
1151 }
1152
1153 LogRel(("GUI: DBGGuiCreate failed, incompatible versions (loaded %#x/%#x, expected %#x)\n",
1154 m_pDbgGuiVT->u32Version, m_pDbgGuiVT->u32EndVersion, DBGGUIVT_VERSION));
1155 }
1156 else
1157 LogRel(("GUI: DBGGuiCreate failed, rc=%Rrc\n", rc));
1158 }
1159 else
1160 LogRel(("GUI: RTLdrGetSymbol(,\"DBGGuiCreate\",) -> %Rrc\n", rc));
1161
1162 m_pDbgGui = 0;
1163 m_pDbgGuiVT = 0;
1164 return false;
1165}
1166
1167void UISession::dbgDestroy()
1168{
1169 if (m_pDbgGui)
1170 {
1171 m_pDbgGuiVT->pfnDestroy(m_pDbgGui);
1172 m_pDbgGui = 0;
1173 m_pDbgGuiVT = 0;
1174 }
1175}
1176
1177void UISession::dbgShowStatistics()
1178{
1179 const QByteArray &expandBytes = uiCommon().getDebuggerStatisticsExpand().toUtf8();
1180 const QByteArray &filterBytes = uiCommon().getDebuggerStatisticsFilter().toUtf8();
1181 m_pDbgGuiVT->pfnShowStatistics(m_pDbgGui, filterBytes.constData(), expandBytes.constData());
1182}
1183
1184void UISession::dbgShowCommandLine()
1185{
1186 m_pDbgGuiVT->pfnShowCommandLine(m_pDbgGui);
1187}
1188
1189void UISession::dbgAdjustRelativePos()
1190{
1191 if (m_pDbgGui)
1192 {
1193 const QRect rct = activeMachineWindow()->frameGeometry();
1194 m_pDbgGuiVT->pfnAdjustRelativePos(m_pDbgGui, rct.x(), rct.y(), rct.width(), rct.height());
1195 }
1196}
1197#endif /* VBOX_WITH_DEBUGGER_GUI */
1198
1199bool UISession::acquireWhetherGuestEnteredACPIMode(bool &fEntered)
1200{
1201 CConsole comConsole = console();
1202 const BOOL fGuestEntered = comConsole.GetGuestEnteredACPIMode();
1203 const bool fSuccess = comConsole.isOk();
1204 if (!fSuccess)
1205 UINotificationMessage::cannotAcquireConsoleParameter(comConsole);
1206 else
1207 fEntered = fGuestEntered == TRUE;
1208 return fSuccess;
1209}
1210
1211void UISession::saveState()
1212{
1213 if ( isPaused()
1214 || (isRunning() && pause()))
1215 {
1216 /* Enable 'manual-override',
1217 * preventing automatic Runtime UI closing: */
1218 uimachine()->setManualOverrideMode(true);
1219
1220 /* Now, do the magic: */
1221 LogRel(("GUI: Saving VM state..\n"));
1222 UINotificationProgressMachineSaveState *pNotification =
1223 new UINotificationProgressMachineSaveState(machine());
1224 connect(pNotification, &UINotificationProgressMachineSaveState::sigMachineStateSaved,
1225 this, &UISession::sltHandleMachineStateSaved);
1226 gpNotificationCenter->append(pNotification);
1227 }
1228}
1229
1230void UISession::shutdown()
1231{
1232 /* Check whether guest is in proper mode: */
1233 bool fValidMode = false;
1234 acquireWhetherGuestEnteredACPIMode(fValidMode);
1235 if (!fValidMode)
1236 UINotificationMessage::cannotSendACPIToMachine();
1237 else
1238 {
1239 /* Now, do the magic: */
1240 LogRel(("GUI: Sending ACPI shutdown signal..\n"));
1241 CConsole comConsole = console();
1242 comConsole.PowerButton();
1243 if (!comConsole.isOk())
1244 UINotificationMessage::cannotACPIShutdownMachine(comConsole);
1245 }
1246}
1247
1248void UISession::powerOff(bool fIncludingDiscard)
1249{
1250 /* Enable 'manual-override',
1251 * preventing automatic Runtime UI closing: */
1252 uimachine()->setManualOverrideMode(true);
1253
1254 /* Now, do the magic: */
1255 LogRel(("GUI: Powering VM off..\n"));
1256 UINotificationProgressMachinePowerOff *pNotification =
1257 new UINotificationProgressMachinePowerOff(machine(),
1258 console(),
1259 fIncludingDiscard);
1260 connect(pNotification, &UINotificationProgressMachinePowerOff::sigMachinePoweredOff,
1261 this, &UISession::sltHandleMachinePoweredOff);
1262 gpNotificationCenter->append(pNotification);
1263}
1264
1265void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
1266{
1267 if (!guestAdditionsUpgradable())
1268 return sltMountDVDAdHoc(strSource);
1269
1270 /* Update guest additions automatically: */
1271 UINotificationProgressGuestAdditionsInstall *pNotification =
1272 new UINotificationProgressGuestAdditionsInstall(guest(), strSource);
1273 connect(pNotification, &UINotificationProgressGuestAdditionsInstall::sigGuestAdditionsInstallationFailed,
1274 this, &UISession::sltMountDVDAdHoc);
1275 gpNotificationCenter->append(pNotification);
1276}
1277
1278void UISession::sltMountDVDAdHoc(const QString &strSource)
1279{
1280 mountAdHocImage(KDeviceType_DVD, UIMediumDeviceType_DVD, strSource);
1281}
1282
1283void UISession::sltDetachCOM()
1284{
1285 /* Cleanup everything COM related: */
1286 cleanupFramebuffers();
1287 cleanupConsoleEventHandlers();
1288 cleanupNotificationCenter();
1289 cleanupSession();
1290}
1291
1292void UISession::sltStateChange(KMachineState enmState)
1293{
1294 /* Check if something had changed: */
1295 if (m_enmMachineState != enmState)
1296 {
1297 /* Store new data: */
1298 m_enmMachineStatePrevious = m_enmMachineState;
1299 m_enmMachineState = enmState;
1300
1301 /* Notify listeners about machine state changed: */
1302 emit sigMachineStateChange();
1303 }
1304}
1305
1306void UISession::sltAdditionsChange()
1307{
1308 /* Acquire actual states: */
1309 const ulong ulGuestAdditionsRunLevel = guest().GetAdditionsRunLevel();
1310 LONG64 iLastUpdatedIgnored;
1311 const bool fIsGuestSupportsGraphics = guest().GetFacilityStatus(KAdditionsFacilityType_Graphics, iLastUpdatedIgnored)
1312 == KAdditionsFacilityStatus_Active;
1313 const bool fIsGuestSupportsSeamless = guest().GetFacilityStatus(KAdditionsFacilityType_Seamless, iLastUpdatedIgnored)
1314 == KAdditionsFacilityStatus_Active;
1315
1316 /* Check if something had changed: */
1317 if ( m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel
1318 || m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics
1319 || m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
1320 {
1321 /* Store new data: */
1322 m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
1323 m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
1324 m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
1325
1326 /* Notify listeners about GA state really changed: */
1327 LogRel(("GUI: UISession::sltAdditionsChange: GA state really changed, notifying listeners.\n"));
1328 emit sigAdditionsStateActualChange();
1329 }
1330 else
1331 LogRel(("GUI: UISession::sltAdditionsChange: GA state doesn't really changed, still notifying listeners.\n"));
1332
1333 /* Notify listeners about GA state change event came: */
1334 emit sigAdditionsStateChange();
1335}
1336
1337void UISession::sltHandleMachineStateSaved(bool fSuccess)
1338{
1339 /* Let user try again if saving failed: */
1340 if (!fSuccess)
1341 {
1342 /* Disable 'manual-override' finally: */
1343 uimachine()->setManualOverrideMode(false);
1344 }
1345 /* Close Runtime UI otherwise: */
1346 else
1347 uimachine()->closeRuntimeUI();
1348}
1349
1350void UISession::sltHandleMachinePoweredOff(bool fSuccess, bool fIncludingDiscard)
1351{
1352 /* Let user try again if power off failed: */
1353 if (!fSuccess)
1354 {
1355 /* Disable 'manual-override' finally: */
1356 uimachine()->setManualOverrideMode(false);
1357 }
1358 /* Check for other tasks otherwise: */
1359 else
1360 {
1361 if (fIncludingDiscard)
1362 {
1363 /* Now, do more magic! */
1364 UINotificationProgressSnapshotRestore *pNotification =
1365 new UINotificationProgressSnapshotRestore(uiCommon().managedVMUuid());
1366 connect(pNotification, &UINotificationProgressSnapshotRestore::sigSnapshotRestored,
1367 this, &UISession::sltHandleSnapshotRestored);
1368 gpNotificationCenter->append(pNotification);
1369 }
1370 else
1371 uimachine()->closeRuntimeUI();
1372 }
1373}
1374
1375void UISession::sltHandleSnapshotRestored(bool)
1376{
1377 /* Close Runtime UI independent of snapshot restoring state: */
1378 uimachine()->closeRuntimeUI();
1379}
1380
1381UISession::UISession(UIMachine *pMachine)
1382 : QObject(pMachine)
1383 /* Base variables: */
1384 , m_pMachine(pMachine)
1385 , m_pConsoleEventhandler(0)
1386 /* Common variables: */
1387 , m_enmMachineStatePrevious(KMachineState_Null)
1388 , m_enmMachineState(KMachineState_Null)
1389 /* Guest additions flags: */
1390 , m_ulGuestAdditionsRunLevel(0)
1391 , m_fIsGuestSupportsGraphics(false)
1392 , m_fIsGuestSupportsSeamless(false)
1393#ifdef VBOX_WITH_DEBUGGER_GUI
1394 /* Debug UI stuff: */
1395 , m_pDbgGui(0)
1396 , m_pDbgGuiVT(0)
1397#endif /* VBOX_WITH_DEBUGGER_GUI */
1398{
1399}
1400
1401UISession::~UISession()
1402{
1403}
1404
1405bool UISession::prepare()
1406{
1407 /* Prepare COM stuff: */
1408 if (!prepareSession())
1409 return false;
1410
1411 /* Cache media early if requested: */
1412 if (uiCommon().agressiveCaching())
1413 recacheMachineMedia();
1414
1415 /* Prepare GUI stuff: */
1416 prepareNotificationCenter();
1417 prepareConsoleEventHandlers();
1418 prepareFramebuffers();
1419 prepareConnections();
1420 prepareSignalHandling();
1421
1422 /* True by default: */
1423 return true;
1424}
1425
1426bool UISession::prepareSession()
1427{
1428 /* Open session: */
1429 m_comSession = uiCommon().openSession(uiCommon().managedVMUuid(),
1430 uiCommon().isSeparateProcess()
1431 ? KLockType_Shared
1432 : KLockType_VM);
1433 if (m_comSession.isNull())
1434 return false;
1435
1436 /* Get machine: */
1437 m_comMachine = m_comSession.GetMachine();
1438 if (m_comMachine.isNull())
1439 return false;
1440
1441 /* Get console: */
1442 m_comConsole = m_comSession.GetConsole();
1443 if (m_comConsole.isNull())
1444 return false;
1445
1446 /* Get display: */
1447 m_comDisplay = m_comConsole.GetDisplay();
1448 if (m_comDisplay.isNull())
1449 return false;
1450
1451 /* Get guest: */
1452 m_comGuest = m_comConsole.GetGuest();
1453 if (m_comGuest.isNull())
1454 return false;
1455
1456 /* Get mouse: */
1457 m_comMouse = m_comConsole.GetMouse();
1458 if (m_comMouse.isNull())
1459 return false;
1460
1461 /* Get keyboard: */
1462 m_comKeyboard = m_comConsole.GetKeyboard();
1463 if (m_comKeyboard.isNull())
1464 return false;
1465
1466 /* Get debugger: */
1467 m_comDebugger = m_comConsole.GetDebugger();
1468 if (m_comDebugger.isNull())
1469 return false;
1470
1471 /* Update machine-name: */
1472 m_strMachineName = machine().GetName();
1473
1474 /* Update machine-state: */
1475 m_enmMachineState = machine().GetState();
1476
1477 /* True by default: */
1478 return true;
1479}
1480
1481void UISession::prepareNotificationCenter()
1482{
1483 UINotificationCenter::create();
1484}
1485
1486void UISession::prepareConsoleEventHandlers()
1487{
1488 /* Create console event-handler: */
1489 m_pConsoleEventhandler = new UIConsoleEventHandler(this);
1490
1491 /* Console event connections: */
1492 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigAdditionsChange,
1493 this, &UISession::sltAdditionsChange);
1494 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigAudioAdapterChange,
1495 this, &UISession::sigAudioAdapterChange);
1496 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigClipboardModeChange,
1497 this, &UISession::sigClipboardModeChange);
1498 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigCPUExecutionCapChange,
1499 this, &UISession::sigCPUExecutionCapChange);
1500 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigDnDModeChange,
1501 this, &UISession::sigDnDModeChange);
1502 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigGuestMonitorChange,
1503 this, &UISession::sigGuestMonitorChange);
1504 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMediumChange,
1505 this, &UISession::sigMediumChange);
1506 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigNetworkAdapterChange,
1507 this, &UISession::sigNetworkAdapterChange);
1508 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigRecordingChange,
1509 this, &UISession::sigRecordingChange);
1510 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigSharedFolderChange,
1511 this, &UISession::sigSharedFolderChange);
1512 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigStateChange,
1513 this, &UISession::sltStateChange);
1514 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigStorageDeviceChange,
1515 this, &UISession::sigStorageDeviceChange);
1516 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigUSBControllerChange,
1517 this, &UISession::sigUSBControllerChange);
1518 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigUSBDeviceStateChange,
1519 this, &UISession::sigUSBDeviceStateChange);
1520 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigVRDEChange,
1521 this, &UISession::sigVRDEChange);
1522 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigRuntimeError,
1523 this, &UISession::sigRuntimeError);
1524
1525#ifdef VBOX_WS_MAC
1526 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigShowWindow,
1527 this, &UISession::sigShowWindows, Qt::QueuedConnection);
1528#endif
1529
1530 /* Console keyboard connections: */
1531 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigKeyboardLedsChange,
1532 this, &UISession::sigKeyboardLedsChange);
1533
1534 /* Console mouse connections: */
1535 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMousePointerShapeChange,
1536 this, &UISession::sigMousePointerShapeChange);
1537 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMouseCapabilityChange,
1538 this, &UISession::sigMouseCapabilityChange);
1539 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigCursorPositionChange,
1540 this, &UISession::sigCursorPositionChange);
1541}
1542
1543void UISession::prepareFramebuffers()
1544{
1545 /* Each framebuffer will be really prepared on first UIMachineView creation;
1546 * For now we should just create an empty frame-buffer vector to fill later. */
1547 ulong cMonitorCount = 0;
1548 acquireMonitorCount(cMonitorCount);
1549 m_frameBufferVector.resize(cMonitorCount);
1550}
1551
1552void UISession::prepareConnections()
1553{
1554 /* UICommon connections: */
1555 connect(&uiCommon(), &UICommon::sigAskToDetachCOM, this, &UISession::sltDetachCOM);
1556}
1557
1558void UISession::prepareSignalHandling()
1559{
1560#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
1561 struct sigaction sa;
1562 sa.sa_sigaction = &signalHandlerSIGUSR1;
1563 sigemptyset(&sa.sa_mask);
1564 sa.sa_flags = SA_RESTART | SA_SIGINFO;
1565 sigaction(SIGUSR1, &sa, NULL);
1566#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
1567}
1568
1569void UISession::cleanupFramebuffers()
1570{
1571 /* Cleanup framebuffers finally: */
1572 for (int i = m_frameBufferVector.size() - 1; i >= 0; --i)
1573 {
1574 UIFrameBuffer *pFrameBuffer = m_frameBufferVector[i];
1575 if (pFrameBuffer)
1576 {
1577 /* Mark framebuffer as unused: */
1578 pFrameBuffer->setMarkAsUnused(true);
1579 /* Detach framebuffer from Display: */
1580 pFrameBuffer->detach();
1581 /* Delete framebuffer reference: */
1582 delete pFrameBuffer;
1583 }
1584 }
1585 m_frameBufferVector.clear();
1586}
1587
1588void UISession::cleanupConsoleEventHandlers()
1589{
1590 /* Destroy console event-handler: */
1591 delete m_pConsoleEventhandler;
1592 m_pConsoleEventhandler = 0;
1593}
1594
1595void UISession::cleanupNotificationCenter()
1596{
1597 UINotificationCenter::destroy();
1598}
1599
1600void UISession::cleanupSession()
1601{
1602 /* Detach debugger: */
1603 if (!m_comDebugger.isNull())
1604 m_comDebugger.detach();
1605
1606 /* Detach keyboard: */
1607 if (!m_comKeyboard.isNull())
1608 m_comKeyboard.detach();
1609
1610 /* Detach mouse: */
1611 if (!m_comMouse.isNull())
1612 m_comMouse.detach();
1613
1614 /* Detach guest: */
1615 if (!m_comGuest.isNull())
1616 m_comGuest.detach();
1617
1618 /* Detach display: */
1619 if (!m_comDisplay.isNull())
1620 m_comDisplay.detach();
1621
1622 /* Detach console: */
1623 if (!m_comConsole.isNull())
1624 m_comConsole.detach();
1625
1626 /* Detach machine: */
1627 if (!m_comMachine.isNull())
1628 m_comMachine.detach();
1629
1630 /* Close session: */
1631 if (!m_comSession.isNull() && uiCommon().isVBoxSVCAvailable())
1632 {
1633 m_comSession.UnlockMachine();
1634 m_comSession.detach();
1635 }
1636}
1637
1638UIMachineLogic *UISession::machineLogic() const
1639{
1640 return uimachine() ? uimachine()->machineLogic() : 0;
1641}
1642
1643UIMachineWindow *UISession::activeMachineWindow() const
1644{
1645 return machineLogic() ? machineLogic()->activeMachineWindow() : 0;
1646}
1647
1648QWidget *UISession::mainMachineWindow() const
1649{
1650 return machineLogic() ? machineLogic()->mainMachineWindow() : 0;
1651}
1652
1653bool UISession::preprocessInitialization()
1654{
1655#ifdef VBOX_WITH_NETFLT
1656 /* Skip network interface name checks if VM in saved state: */
1657 if (!isSaved())
1658 {
1659 /* Make sure all the attached and enabled network
1660 * adapters are present on the host. This check makes sense
1661 * in two cases only - when attachement type is Bridged Network
1662 * or Host-only Interface. NOTE: Only currently enabled
1663 * attachement type is checked (incorrect parameters check for
1664 * currently disabled attachement types is skipped). */
1665 QStringList failedInterfaceNames;
1666 QStringList availableInterfaceNames;
1667
1668 /* Create host network interface names list: */
1669 foreach (const CHostNetworkInterface &comNetIface, uiCommon().host().GetNetworkInterfaces())
1670 {
1671 availableInterfaceNames << comNetIface.GetName();
1672 availableInterfaceNames << comNetIface.GetShortName();
1673 }
1674
1675 /* Enumerate all the virtual network adapters: */
1676 const ulong cCount = uiCommon().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(machine().GetChipsetType());
1677 for (ulong uAdapterIndex = 0; uAdapterIndex < cCount; ++uAdapterIndex)
1678 {
1679 CNetworkAdapter comNetworkAdapter = machine().GetNetworkAdapter(uAdapterIndex);
1680 if (comNetworkAdapter.GetEnabled())
1681 {
1682 /* Get physical network interface name for
1683 * currently enabled network attachement type: */
1684 QString strInterfaceName;
1685 switch (comNetworkAdapter.GetAttachmentType())
1686 {
1687 case KNetworkAttachmentType_Bridged:
1688 strInterfaceName = comNetworkAdapter.GetBridgedInterface();
1689 break;
1690#ifndef VBOX_WITH_VMNET
1691 case KNetworkAttachmentType_HostOnly:
1692 strInterfaceName = comNetworkAdapter.GetHostOnlyInterface();
1693 break;
1694#endif /* !VBOX_WITH_VMNET */
1695 default:
1696 break;
1697 }
1698
1699 if ( !strInterfaceName.isEmpty()
1700 && !availableInterfaceNames.contains(strInterfaceName))
1701 {
1702 LogRel(("GUI: Invalid network interface found: %s\n", strInterfaceName.toUtf8().constData()));
1703 failedInterfaceNames << QString("%1 (adapter %2)").arg(strInterfaceName).arg(uAdapterIndex + 1);
1704 }
1705 }
1706 }
1707
1708 /* Check if non-existent interfaces found: */
1709 if (!failedInterfaceNames.isEmpty())
1710 {
1711 if (msgCenter().warnAboutNetworkInterfaceNotFound(machineName(), failedInterfaceNames.join(", ")))
1712 machineLogic()->openNetworkSettingsDialog();
1713 else
1714 {
1715 LogRel(("GUI: Aborting startup due to preprocess initialization issue detected...\n"));
1716 return false;
1717 }
1718 }
1719 }
1720#endif /* VBOX_WITH_NETFLT */
1721
1722 /* Check for USB enumeration warning. Don't return false even if we have a warning: */
1723 CHost comHost = uiCommon().host();
1724 if (comHost.GetUSBDevices().isEmpty() && comHost.isWarning())
1725 {
1726 /* Do not bitch if USB disabled: */
1727 if (!machine().GetUSBControllers().isEmpty())
1728 {
1729 /* Do not bitch if there are no filters (check if enabled too?): */
1730 if (!machine().GetUSBDeviceFilters().GetDeviceFilters().isEmpty())
1731 UINotificationMessage::cannotEnumerateHostUSBDevices(comHost);
1732 }
1733 }
1734
1735 /* True by default: */
1736 return true;
1737}
1738
1739bool UISession::mountAdHocImage(KDeviceType enmDeviceType, UIMediumDeviceType enmMediumType, const QString &strMediumName)
1740{
1741 /* Get VBox: */
1742 CVirtualBox comVBox = uiCommon().virtualBox();
1743
1744 /* Prepare medium to mount: */
1745 UIMedium guiMedium;
1746
1747 /* The 'none' medium name means ejecting what ever is in the drive,
1748 * in that case => leave the guiMedium variable null. */
1749 if (strMediumName != "none")
1750 {
1751 /* Open the medium: */
1752 const CMedium comMedium = comVBox.OpenMedium(strMediumName, enmDeviceType, KAccessMode_ReadWrite, false /* fForceNewUuid */);
1753 if (!comVBox.isOk() || comMedium.isNull())
1754 {
1755 UINotificationMessage::cannotOpenMedium(comVBox, strMediumName);
1756 return false;
1757 }
1758
1759 /* Make sure medium ID is valid: */
1760 const QUuid uMediumId = comMedium.GetId();
1761 AssertReturn(!uMediumId.isNull(), false);
1762
1763 /* Try to find UIMedium among cached: */
1764 guiMedium = uiCommon().medium(uMediumId);
1765 if (guiMedium.isNull())
1766 {
1767 /* Cache new one if necessary: */
1768 guiMedium = UIMedium(comMedium, enmMediumType, KMediumState_Created);
1769 uiCommon().createMedium(guiMedium);
1770 }
1771 }
1772
1773 /* Search for a suitable storage slots: */
1774 QList<ExactStorageSlot> aFreeStorageSlots;
1775 QList<ExactStorageSlot> aBusyStorageSlots;
1776 foreach (const CStorageController &comController, machine().GetStorageControllers())
1777 {
1778 foreach (const CMediumAttachment &comAttachment, machine().GetMediumAttachmentsOfController(comController.GetName()))
1779 {
1780 /* Look for an optical devices only: */
1781 if (comAttachment.GetType() == enmDeviceType)
1782 {
1783 /* Append storage slot to corresponding list: */
1784 if (comAttachment.GetMedium().isNull())
1785 aFreeStorageSlots << ExactStorageSlot(comController.GetName(), comController.GetBus(),
1786 comAttachment.GetPort(), comAttachment.GetDevice());
1787 else
1788 aBusyStorageSlots << ExactStorageSlot(comController.GetName(), comController.GetBus(),
1789 comAttachment.GetPort(), comAttachment.GetDevice());
1790 }
1791 }
1792 }
1793
1794 /* Make sure at least one storage slot found: */
1795 QList<ExactStorageSlot> sStorageSlots = aFreeStorageSlots + aBusyStorageSlots;
1796 if (sStorageSlots.isEmpty())
1797 {
1798 UINotificationMessage::cannotMountImage(machineName(), strMediumName);
1799 return false;
1800 }
1801
1802 /* Try to mount medium into first available storage slot: */
1803 while (!sStorageSlots.isEmpty())
1804 {
1805 const ExactStorageSlot storageSlot = sStorageSlots.takeFirst();
1806 machine().MountMedium(storageSlot.controller, storageSlot.port, storageSlot.device, guiMedium.medium(), false /* force */);
1807 if (machine().isOk())
1808 break;
1809 }
1810
1811 /* Show error message if necessary: */
1812 if (!machine().isOk())
1813 {
1814 msgCenter().cannotRemountMedium(machine(), guiMedium, true /* mount? */, false /* retry? */, activeMachineWindow());
1815 return false;
1816 }
1817
1818 /* Save machine settings: */
1819 machine().SaveSettings();
1820
1821 /* Show error message if necessary: */
1822 if (!machine().isOk())
1823 {
1824 UINotificationMessage::cannotSaveMachineSettings(machine());
1825 return false;
1826 }
1827
1828 /* True by default: */
1829 return true;
1830}
1831
1832void UISession::recacheMachineMedia()
1833{
1834 /* Compose a list of machine media: */
1835 CMediumVector comMedia;
1836
1837 /* Enumerate all the controllers: */
1838 foreach (const CStorageController &comController, machine().GetStorageControllers())
1839 {
1840 /* Enumerate all the attachments: */
1841 foreach (const CMediumAttachment &comAttachment, machine().GetMediumAttachmentsOfController(comController.GetName()))
1842 {
1843 /* Skip unrelated device types: */
1844 const KDeviceType enmDeviceType = comAttachment.GetType();
1845 if ( enmDeviceType != KDeviceType_HardDisk
1846 && enmDeviceType != KDeviceType_Floppy
1847 && enmDeviceType != KDeviceType_DVD)
1848 continue;
1849 if ( comAttachment.GetIsEjected()
1850 || comAttachment.GetMedium().isNull())
1851 continue;
1852 comMedia.append(comAttachment.GetMedium());
1853 }
1854 }
1855
1856 /* Start media enumeration: */
1857 uiCommon().enumerateMedia(comMedia);
1858}
1859
1860#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
1861/**
1862 * Custom signal handler. When switching VTs, we might not get release events
1863 * for Ctrl-Alt and in case a savestate is performed on the new VT, the VM will
1864 * be saved with modifier keys stuck. This is annoying enough for introducing
1865 * this hack.
1866 */
1867/* static */
1868static void signalHandlerSIGUSR1(int sig, siginfo_t * /* pInfo */, void * /*pSecret */)
1869{
1870 /* Only SIGUSR1 is interesting: */
1871 if (sig == SIGUSR1)
1872 if (gpMachine)
1873 gpMachine->machineLogic()->keyboardHandler()->releaseAllPressedKeys();
1874}
1875#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette