VirtualBox

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

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

FE/Qt: bugref:10322: Runtime UI: Cleanup for arguments of mouse/keyboard wrappers.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.6 KB
Line 
1/* $Id: UISession.cpp 98601 2023-02-16 13:05:04Z 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 "CGraphicsAdapter.h"
60#include "CHostNetworkInterface.h"
61#include "CHostUSBDevice.h"
62#include "CMedium.h"
63#include "CMediumAttachment.h"
64#include "CSnapshot.h"
65#include "CStorageController.h"
66#include "CSystemProperties.h"
67#include "CUSBController.h"
68#include "CUSBDeviceFilter.h"
69#include "CUSBDeviceFilters.h"
70#ifdef VBOX_WITH_NETFLT
71# include "CNetworkAdapter.h"
72#endif
73
74/* External includes: */
75#ifdef VBOX_WS_X11
76# include <X11/Xlib.h>
77# include <X11/Xutil.h>
78#endif
79
80
81#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
82static void signalHandlerSIGUSR1(int sig, siginfo_t *, void *);
83#endif
84
85/* static */
86bool UISession::create(UISession *&pSession, UIMachine *pMachine)
87{
88 /* Make sure NULL pointer passed: */
89 AssertReturn(!pSession, false);
90
91 /* Create session UI: */
92 pSession = new UISession(pMachine);
93 AssertPtrReturn(pSession, false);
94
95 /* Make sure it's prepared: */
96 if (!pSession->prepare())
97 {
98 /* Destroy session UI otherwise: */
99 destroy(pSession);
100 /* False in that case: */
101 return false;
102 }
103
104 /* True by default: */
105 return true;
106}
107
108/* static */
109void UISession::destroy(UISession *&pSession)
110{
111 /* Make sure valid pointer passed: */
112 AssertPtrReturnVoid(pSession);
113
114 /* Delete session: */
115 delete pSession;
116 pSession = 0;
117}
118
119bool UISession::initialize()
120{
121 /* Preprocess initialization: */
122 if (!preprocessInitialization())
123 return false;
124
125 /* Notify user about mouse&keyboard auto-capturing: */
126 if (gEDataManager->autoCaptureEnabled())
127 UINotificationMessage::remindAboutAutoCapture();
128
129 m_enmMachineState = machine().GetState();
130
131 /* Apply debug settings from the command line. */
132 if (!debugger().isNull() && debugger().isOk())
133 {
134 if (uiCommon().areWeToExecuteAllInIem())
135 debugger().SetExecuteAllInIEM(true);
136 if (!uiCommon().isDefaultWarpPct())
137 debugger().SetVirtualTimeRate(uiCommon().getWarpPct());
138 }
139
140 /* Apply ad-hoc reconfigurations from the command line: */
141 if (uiCommon().hasFloppyImageToMount())
142 mountAdHocImage(KDeviceType_Floppy, UIMediumDeviceType_Floppy, uiCommon().getFloppyImage().toString());
143 if (uiCommon().hasDvdImageToMount())
144 mountAdHocImage(KDeviceType_DVD, UIMediumDeviceType_DVD, uiCommon().getDvdImage().toString());
145
146 /* Power UP if this is NOT separate process: */
147 if (!uiCommon().isSeparateProcess())
148 if (!powerUp())
149 return false;
150
151 /* Make sure all the pending Console events converted to signals
152 * during the powerUp() progress above reached their destinations.
153 * That is necessary to make sure all the pending machine state change events processed.
154 * We can't just use the machine state directly acquired from IMachine because there
155 * will be few places which are using stale machine state, not just this one. */
156 QApplication::sendPostedEvents(0, QEvent::MetaCall);
157
158 /* Check if we missed a really quick termination after successful startup: */
159 if (isTurnedOff())
160 {
161 LogRel(("GUI: Aborting startup due to invalid machine state detected: %d\n", machineState()));
162 return false;
163 }
164
165 /* Fetch corresponding states: */
166 if (uiCommon().isSeparateProcess())
167 {
168 sltAdditionsChange();
169 }
170 machineLogic()->initializePostPowerUp();
171
172#ifdef VBOX_GUI_WITH_PIDFILE
173 uiCommon().createPidfile();
174#endif /* VBOX_GUI_WITH_PIDFILE */
175
176 /* True by default: */
177 return true;
178}
179
180bool UISession::powerUp()
181{
182 /* Power UP machine: */
183 CProgress comProgress = uiCommon().shouldStartPaused() ? console().PowerUpPaused() : console().PowerUp();
184
185 /* Check for immediate failure: */
186 if (!console().isOk() || comProgress.isNull())
187 {
188 if (uiCommon().showStartVMErrors())
189 msgCenter().cannotStartMachine(console(), machineName());
190 LogRel(("GUI: Aborting startup due to power up issue detected...\n"));
191 return false;
192 }
193
194 /* Some logging right after we powered up: */
195 LogRel(("GUI: Qt version: %s\n", UICommon::qtRTVersionString().toUtf8().constData()));
196#ifdef VBOX_WS_X11
197 LogRel(("GUI: X11 Window Manager code: %d\n", (int)uiCommon().typeOfWindowManager()));
198#endif
199#if defined(VBOX_WS_MAC) || defined(VBOX_WS_WIN)
200 LogRel(("GUI: HID LEDs sync is %s\n", uimachine()->isHidLedsSyncEnabled() ? "enabled" : "disabled"));
201#else
202 LogRel(("GUI: HID LEDs sync is not supported on this platform\n"));
203#endif
204
205 /* Enable 'manual-override',
206 * preventing automatic Runtime UI closing
207 * and visual representation mode changes: */
208 uimachine()->setManualOverrideMode(true);
209
210 /* Show "Starting/Restoring" progress dialog: */
211 if (isSaved())
212 {
213 msgCenter().showModalProgressDialog(comProgress, machineName(), ":/progress_state_restore_90px.png", 0, 0);
214 /* After restoring from 'saved' state, machine-window(s) geometry should be adjusted: */
215 machineLogic()->adjustMachineWindowsGeometry();
216 }
217 else
218 {
219#ifdef VBOX_IS_QT6_OR_LATER /** @todo why is this any problem on qt6? */
220 msgCenter().showModalProgressDialog(comProgress, machineName(), ":/progress_start_90px.png", 0, 0);
221#else
222 msgCenter().showModalProgressDialog(comProgress, machineName(), ":/progress_start_90px.png");
223#endif
224 /* After VM start, machine-window(s) size-hint(s) should be sent: */
225 machineLogic()->sendMachineWindowsSizeHints();
226 }
227
228 /* Check for progress failure: */
229 if (!comProgress.isOk() || comProgress.GetResultCode() != 0)
230 {
231 if (uiCommon().showStartVMErrors())
232 msgCenter().cannotStartMachine(comProgress, machineName());
233 LogRel(("GUI: Aborting startup due to power up progress issue detected...\n"));
234 return false;
235 }
236
237 /* Disable 'manual-override' finally: */
238 uimachine()->setManualOverrideMode(false);
239
240 /* True by default: */
241 return true;
242}
243
244WId UISession::mainMachineWindowId() const
245{
246 return mainMachineWindow() ? mainMachineWindow()->winId() : 0;
247}
248
249bool UISession::setPause(bool fPause)
250{
251 CConsole comConsole = console();
252 if (fPause)
253 comConsole.Pause();
254 else
255 comConsole.Resume();
256 const bool fSuccess = comConsole.isOk();
257 if (!fSuccess)
258 {
259 if (fPause)
260 UINotificationMessage::cannotPauseMachine(comConsole);
261 else
262 UINotificationMessage::cannotResumeMachine(comConsole);
263 }
264 return fSuccess;
265}
266
267bool UISession::putScancode(LONG iCode)
268{
269 CKeyboard comKeyboard = keyboard();
270 comKeyboard.PutScancode(iCode);
271 const bool fSuccess = comKeyboard.isOk();
272 if (!fSuccess)
273 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
274 return fSuccess;
275}
276
277bool UISession::putScancodes(const QVector<LONG> &codes)
278{
279 CKeyboard comKeyboard = keyboard();
280 comKeyboard.PutScancodes(codes);
281 const bool fSuccess = comKeyboard.isOk();
282 if (!fSuccess)
283 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
284 return fSuccess;
285}
286
287bool UISession::putCAD()
288{
289 CKeyboard comKeyboard = keyboard();
290 comKeyboard.PutCAD();
291 const bool fSuccess = comKeyboard.isOk();
292 if (!fSuccess)
293 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
294 return fSuccess;
295}
296
297bool UISession::releaseKeys()
298{
299 CKeyboard comKeyboard = keyboard();
300 comKeyboard.ReleaseKeys();
301 const bool fSuccess = comKeyboard.isOk();
302 if (!fSuccess)
303 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
304 return fSuccess;
305}
306
307bool UISession::putUsageCode(LONG iUsageCode, LONG iUsagePage, bool fKeyRelease)
308{
309 CKeyboard comKeyboard = keyboard();
310 comKeyboard.PutUsageCode(iUsageCode, iUsagePage, fKeyRelease);
311 const bool fSuccess = comKeyboard.isOk();
312 if (!fSuccess)
313 UINotificationMessage::cannotChangeKeyboardParameter(comKeyboard);
314 return fSuccess;
315}
316
317bool UISession::getAbsoluteSupported()
318{
319 return mouse().GetAbsoluteSupported();
320}
321
322bool UISession::getRelativeSupported()
323{
324 return mouse().GetRelativeSupported();
325}
326
327bool UISession::getTouchScreenSupported()
328{
329 return mouse().GetTouchScreenSupported();
330}
331
332bool UISession::getTouchPadSupported()
333{
334 return mouse().GetTouchPadSupported();
335}
336
337bool UISession::getNeedsHostCursor()
338{
339 return mouse().GetNeedsHostCursor();
340}
341
342bool UISession::putMouseEvent(long iDx, long iDy, long iDz, long iDw, long iButtonState)
343{
344 CMouse comMouse = mouse();
345 comMouse.PutMouseEvent(iDx, iDy, iDz, iDw, iButtonState);
346 const bool fSuccess = comMouse.isOk();
347 if (!fSuccess)
348 UINotificationMessage::cannotChangeMouseParameter(comMouse);
349 return fSuccess;
350}
351
352bool UISession::putMouseEventAbsolute(long iX, long iY, long iDz, long iDw, long iButtonState)
353{
354 CMouse comMouse = mouse();
355 comMouse.PutMouseEventAbsolute(iX, iY, iDz, iDw, iButtonState);
356 const bool fSuccess = comMouse.isOk();
357 if (!fSuccess)
358 UINotificationMessage::cannotChangeMouseParameter(comMouse);
359 return fSuccess;
360}
361
362bool UISession::putEventMultiTouch(long iCount, const QVector<LONG64> &contacts, bool fIsTouchScreen, ulong uScanTime)
363{
364 CMouse comMouse = mouse();
365 comMouse.PutEventMultiTouch(iCount, contacts, fIsTouchScreen, uScanTime);
366 const bool fSuccess = comMouse.isOk();
367 if (!fSuccess)
368 UINotificationMessage::cannotChangeMouseParameter(comMouse);
369 return fSuccess;
370}
371
372bool UISession::guestAdditionsUpgradable()
373{
374 if (!machine().isOk())
375 return false;
376
377 /* Auto GA update is currently for Windows and Linux guests only */
378 const CGuestOSType osType = uiCommon().vmGuestOSType(machine().GetOSTypeId());
379 if (!osType.isOk())
380 return false;
381
382 const QString strGuestFamily = osType.GetFamilyId();
383 bool fIsWindowOrLinux = strGuestFamily.contains("windows", Qt::CaseInsensitive) || strGuestFamily.contains("linux", Qt::CaseInsensitive);
384
385 if (!fIsWindowOrLinux)
386 return false;
387
388 /* Also check whether we have something to update automatically: */
389 if (m_ulGuestAdditionsRunLevel < (ulong)KAdditionsRunLevelType_Userland)
390 return false;
391
392 return true;
393}
394
395UIFrameBuffer *UISession::frameBuffer(ulong uScreenId) const
396{
397 Assert(uScreenId < (ulong)m_frameBufferVector.size());
398 return m_frameBufferVector.value((int)uScreenId, 0);
399}
400
401void UISession::setFrameBuffer(ulong uScreenId, UIFrameBuffer *pFrameBuffer)
402{
403 Assert(uScreenId < (ulong)m_frameBufferVector.size());
404 if (uScreenId < (ulong)m_frameBufferVector.size())
405 m_frameBufferVector[(int)uScreenId] = pFrameBuffer;
406}
407
408QSize UISession::frameBufferSize(ulong uScreenId) const
409{
410 UIFrameBuffer *pFramebuffer = frameBuffer(uScreenId);
411 return pFramebuffer ? QSize(pFramebuffer->width(), pFramebuffer->height()) : QSize();
412}
413
414bool UISession::acquireGuestScreenParameters(ulong uScreenId,
415 ulong &uWidth, ulong &uHeight, ulong &uBitsPerPixel,
416 long &xOrigin, long &yOrigin, KGuestMonitorStatus &enmMonitorStatus)
417{
418 CDisplay comDisplay = display();
419 ULONG uGuestWidth = 0, uGuestHeight = 0, uGuestBitsPerPixel = 0;
420 LONG iGuestXOrigin = 0, iGuestYOrigin = 0;
421 KGuestMonitorStatus enmGuestMonitorStatus = KGuestMonitorStatus_Disabled;
422 comDisplay.GetScreenResolution(uScreenId, uGuestWidth, uGuestHeight, uGuestBitsPerPixel,
423 iGuestXOrigin, iGuestYOrigin, enmGuestMonitorStatus);
424 const bool fSuccess = comDisplay.isOk();
425 if (!fSuccess)
426 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
427 uWidth = uGuestWidth;
428 uHeight = uGuestHeight;
429 uBitsPerPixel = uGuestBitsPerPixel;
430 xOrigin = iGuestXOrigin;
431 yOrigin = iGuestYOrigin;
432 enmMonitorStatus = enmGuestMonitorStatus;
433 return fSuccess;
434}
435
436bool UISession::setVideoModeHint(ulong uScreenId, bool fEnabled, bool fChangeOrigin, long xOrigin, long yOrigin,
437 ulong uWidth, ulong uHeight, ulong uBitsPerPixel, bool fNotify)
438{
439 CDisplay comDisplay = display();
440 comDisplay.SetVideoModeHint(uScreenId, fEnabled, fChangeOrigin, xOrigin, yOrigin,
441 uWidth, uHeight, uBitsPerPixel, fNotify);
442 const bool fSuccess = comDisplay.isOk();
443 if (!fSuccess)
444 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
445 return fSuccess;
446}
447
448bool UISession::acquireVideoModeHint(ulong uScreenId, bool &fEnabled, bool &fChangeOrigin,
449 long &xOrigin, long &yOrigin, ulong &uWidth, ulong &uHeight,
450 ulong &uBitsPerPixel)
451{
452 CDisplay comDisplay = display();
453 BOOL fGuestEnabled = false, fGuestChangeOrigin = false;
454 LONG iGuestXOrigin = 0, iGuestYOrigin = 0;
455 ULONG uGuestWidth = 0, uGuestHeight = 0, uGuestBitsPerPixel = 0;
456 comDisplay.GetVideoModeHint(uScreenId, fGuestEnabled, fGuestChangeOrigin,
457 iGuestXOrigin, iGuestYOrigin, uGuestWidth, uGuestHeight,
458 uGuestBitsPerPixel);
459 const bool fSuccess = comDisplay.isOk();
460 if (!fSuccess)
461 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
462 fEnabled = fGuestEnabled;
463 fChangeOrigin = fGuestChangeOrigin;
464 xOrigin = iGuestXOrigin;
465 yOrigin = iGuestYOrigin;
466 uWidth = uGuestWidth;
467 uHeight = uGuestHeight;
468 uBitsPerPixel = uGuestBitsPerPixel;
469 return fSuccess;
470}
471
472bool UISession::acquireScreenShot(ulong uScreenId, ulong uWidth, ulong uHeight, KBitmapFormat enmFormat, uchar *pBits)
473{
474 CDisplay comDisplay = display();
475 bool fSuccess = false;
476 /* For separate process: */
477 if (uiCommon().isSeparateProcess())
478 {
479 /* Take screen-data to array first: */
480 const QVector<BYTE> screenData = comDisplay.TakeScreenShotToArray(uScreenId, uWidth, uHeight, enmFormat);
481 fSuccess = comDisplay.isOk();
482 if (!fSuccess)
483 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
484 else
485 {
486 /* And copy that data to screen-shot if it is Ok: */
487 if (!screenData.isEmpty())
488 memcpy(pBits, screenData.data(), uWidth * uHeight * 4);
489 }
490 }
491 /* For the same process: */
492 else
493 {
494 /* Take the screen-shot directly: */
495 comDisplay.TakeScreenShot(uScreenId, pBits, uWidth, uHeight, enmFormat);
496 fSuccess = comDisplay.isOk();
497 if (!fSuccess)
498 UINotificationMessage::cannotAcquireDisplayParameter(comDisplay);
499 }
500 return fSuccess;
501}
502
503bool UISession::notifyScaleFactorChange(ulong uScreenId, ulong uScaleFactorWMultiplied, ulong uScaleFactorHMultiplied)
504{
505 CDisplay comDisplay = display();
506 comDisplay.NotifyScaleFactorChange(uScreenId, uScaleFactorWMultiplied, uScaleFactorHMultiplied);
507 const bool fSuccess = comDisplay.isOk();
508 if (!fSuccess)
509 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
510 return fSuccess;
511}
512
513bool UISession::notifyHiDPIOutputPolicyChange(bool fUnscaledHiDPI)
514{
515 CDisplay comDisplay = display();
516 comDisplay.NotifyHiDPIOutputPolicyChange(fUnscaledHiDPI);
517 const bool fSuccess = comDisplay.isOk();
518 if (!fSuccess)
519 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
520 return fSuccess;
521}
522
523bool UISession::setSeamlessMode(bool fEnabled)
524{
525 CDisplay comDisplay = display();
526 comDisplay.SetSeamlessMode(fEnabled);
527 const bool fSuccess = comDisplay.isOk();
528 if (!fSuccess)
529 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
530 return fSuccess;
531}
532
533bool UISession::viewportChanged(ulong uScreenId, ulong xOrigin, ulong yOrigin, ulong uWidth, ulong uHeight)
534{
535 CDisplay comDisplay = display();
536 comDisplay.ViewportChanged(uScreenId, xOrigin, yOrigin, uWidth, uHeight);
537 const bool fSuccess = comDisplay.isOk();
538 if (!fSuccess)
539 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
540 return fSuccess;
541}
542
543bool UISession::invalidateAndUpdate()
544{
545 CDisplay comDisplay = display();
546 comDisplay.InvalidateAndUpdate();
547 const bool fSuccess = comDisplay.isOk();
548 if (!fSuccess)
549 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
550 return fSuccess;
551}
552
553bool UISession::invalidateAndUpdateScreen(ulong uScreenId)
554{
555 CDisplay comDisplay = display();
556 comDisplay.InvalidateAndUpdateScreen(uScreenId);
557 const bool fSuccess = comDisplay.isOk();
558 if (!fSuccess)
559 UINotificationMessage::cannotChangeDisplayParameter(comDisplay);
560 return fSuccess;
561}
562
563bool UISession::acquireDeviceActivity(const QVector<KDeviceType> &deviceTypes, QVector<KDeviceActivity> &states)
564{
565 CConsole comConsole = console();
566 states = comConsole.GetDeviceActivity(deviceTypes);
567 const bool fSuccess = comConsole.isOk();
568 if (!fSuccess)
569 UINotificationMessage::cannotAcquireConsoleParameter(comConsole);
570 return fSuccess;
571}
572
573void UISession::acquireHardDiskStatusInfo(QString &strInfo, bool &fAttachmentsPresent)
574{
575 CMachine comMachine = machine();
576 UIDetailsGenerator::acquireHardDiskStatusInfo(comMachine, strInfo, fAttachmentsPresent);
577}
578
579void UISession::acquireOpticalDiskStatusInfo(QString &strInfo, bool &fAttachmentsPresent, bool &fAttachmentsMounted)
580{
581 CMachine comMachine = machine();
582 UIDetailsGenerator::acquireOpticalDiskStatusInfo(comMachine, strInfo, fAttachmentsPresent, fAttachmentsMounted);
583}
584
585void UISession::acquireFloppyDiskStatusInfo(QString &strInfo, bool &fAttachmentsPresent, bool &fAttachmentsMounted)
586{
587 CMachine comMachine = machine();
588 UIDetailsGenerator::acquireFloppyDiskStatusInfo(comMachine, strInfo, fAttachmentsPresent, fAttachmentsMounted);
589}
590
591void UISession::acquireAudioStatusInfo(QString &strInfo, bool &fAudioEnabled, bool &fEnabledOutput, bool &fEnabledInput)
592{
593 CMachine comMachine = machine();
594 UIDetailsGenerator::acquireAudioStatusInfo(comMachine, strInfo, fAudioEnabled, fEnabledOutput, fEnabledInput);
595}
596
597void UISession::acquireNetworkStatusInfo(QString &strInfo, bool &fAdaptersPresent, bool &fCablesDisconnected)
598{
599 CMachine comMachine = machine();
600 UIDetailsGenerator::acquireNetworkStatusInfo(comMachine, strInfo, fAdaptersPresent, fCablesDisconnected);
601}
602
603void UISession::acquireUsbStatusInfo(QString &strInfo, bool &fUsbEnableds)
604{
605 CMachine comMachine = machine();
606 CConsole comConsole = console();
607 UIDetailsGenerator::acquireUsbStatusInfo(comMachine, comConsole, strInfo, fUsbEnableds);
608}
609
610void UISession::acquireSharedFoldersStatusInfo(QString &strInfo, bool &fFoldersPresent)
611{
612 CMachine comMachine = machine();
613 CConsole comConsole = console();
614 CGuest comGuest = guest();
615 UIDetailsGenerator::acquireSharedFoldersStatusInfo(comMachine, comConsole, comGuest, strInfo, fFoldersPresent);
616}
617
618void UISession::acquireDisplayStatusInfo(QString &strInfo, bool &fAcceleration3D)
619{
620 CMachine comMachine = machine();
621 UIDetailsGenerator::acquireDisplayStatusInfo(comMachine, strInfo, fAcceleration3D);
622}
623
624void UISession::acquireRecordingStatusInfo(QString &strInfo, bool &fRecordingEnabled, bool &fMachinePaused)
625{
626 CMachine comMachine = machine();
627 fMachinePaused = isPaused();
628 UIDetailsGenerator::acquireRecordingStatusInfo(comMachine, strInfo, fRecordingEnabled);
629}
630
631void UISession::acquireFeaturesStatusInfo(QString &strInfo, KVMExecutionEngine &enmEngine,
632 bool fNestedPagingEnabled, bool fUxEnabled,
633 KParavirtProvider enmProvider)
634{
635 CMachine comMachine = machine();
636 UIDetailsGenerator::acquireFeaturesStatusInfo(comMachine, strInfo,
637 enmEngine,
638 fNestedPagingEnabled, fUxEnabled,
639 enmProvider);
640}
641
642void UISession::setLogEnabled(bool fEnabled)
643{
644 CMachineDebugger comDebugger = debugger();
645 comDebugger.SetLogEnabled(fEnabled ? TRUE : FALSE);
646 if (!comDebugger.isOk())
647 UINotificationMessage::cannotChangeMachineDebuggerParameter(comDebugger);
648}
649
650bool UISession::isLogEnabled()
651{
652 CMachineDebugger comDebugger = debugger();
653 const BOOL fEnabled = comDebugger.GetLogEnabled();
654 if (!comDebugger.isOk())
655 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
656 return fEnabled == TRUE;
657}
658
659KVMExecutionEngine UISession::executionEngineType()
660{
661 CMachineDebugger comDebugger = debugger();
662 const KVMExecutionEngine enmEngine = comDebugger.GetExecutionEngine();
663 if (!comDebugger.isOk())
664 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
665 return enmEngine;
666}
667
668bool UISession::isHwVirtExNestedPagingEnabled()
669{
670 CMachineDebugger comDebugger = debugger();
671 const BOOL fEnabled = comDebugger.GetHWVirtExNestedPagingEnabled();
672 if (!comDebugger.isOk())
673 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
674 return fEnabled == TRUE;
675}
676
677bool UISession::isHwVirtExUXEnabled()
678{
679 CMachineDebugger comDebugger = debugger();
680 const BOOL fEnabled = comDebugger.GetHWVirtExUXEnabled();
681 if (!comDebugger.isOk())
682 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
683 return fEnabled == TRUE;
684}
685
686int UISession::cpuLoadPercentage()
687{
688 CMachineDebugger comDebugger = debugger();
689 ULONG uPctExecuting;
690 ULONG uPctHalted;
691 ULONG uPctOther;
692 comDebugger.GetCPULoad(0x7fffffff, uPctExecuting, uPctHalted, uPctOther);
693 if (!comDebugger.isOk())
694 UINotificationMessage::cannotAcquireMachineDebuggerParameter(comDebugger);
695 return uPctExecuting + uPctOther;
696}
697
698bool UISession::prepareToBeSaved()
699{
700 return isPaused()
701 || (isRunning() && pause());
702}
703
704bool UISession::prepareToBeShutdowned()
705{
706 const bool fValidMode = console().GetGuestEnteredACPIMode();
707 if (!fValidMode)
708 UINotificationMessage::cannotSendACPIToMachine();
709 return fValidMode;
710}
711
712void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
713{
714 if (!guestAdditionsUpgradable())
715 return sltMountDVDAdHoc(strSource);
716
717 /* Update guest additions automatically: */
718 UINotificationProgressGuestAdditionsInstall *pNotification =
719 new UINotificationProgressGuestAdditionsInstall(guest(), strSource);
720 connect(pNotification, &UINotificationProgressGuestAdditionsInstall::sigGuestAdditionsInstallationFailed,
721 this, &UISession::sltMountDVDAdHoc);
722 gpNotificationCenter->append(pNotification);
723}
724
725void UISession::sltMountDVDAdHoc(const QString &strSource)
726{
727 mountAdHocImage(KDeviceType_DVD, UIMediumDeviceType_DVD, strSource);
728}
729
730void UISession::sltDetachCOM()
731{
732 /* Cleanup everything COM related: */
733 cleanupFramebuffers();
734 cleanupConsoleEventHandlers();
735 cleanupNotificationCenter();
736 cleanupSession();
737}
738
739void UISession::sltStateChange(KMachineState enmState)
740{
741 /* Check if something had changed: */
742 if (m_enmMachineState != enmState)
743 {
744 /* Store new data: */
745 m_enmMachineStatePrevious = m_enmMachineState;
746 m_enmMachineState = enmState;
747
748 /* Notify listeners about machine state changed: */
749 emit sigMachineStateChange();
750 }
751}
752
753void UISession::sltAdditionsChange()
754{
755 /* Acquire actual states: */
756 const ulong ulGuestAdditionsRunLevel = guest().GetAdditionsRunLevel();
757 LONG64 iLastUpdatedIgnored;
758 const bool fIsGuestSupportsGraphics = guest().GetFacilityStatus(KAdditionsFacilityType_Graphics, iLastUpdatedIgnored)
759 == KAdditionsFacilityStatus_Active;
760 const bool fIsGuestSupportsSeamless = guest().GetFacilityStatus(KAdditionsFacilityType_Seamless, iLastUpdatedIgnored)
761 == KAdditionsFacilityStatus_Active;
762
763 /* Check if something had changed: */
764 if ( m_ulGuestAdditionsRunLevel != ulGuestAdditionsRunLevel
765 || m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics
766 || m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
767 {
768 /* Store new data: */
769 m_ulGuestAdditionsRunLevel = ulGuestAdditionsRunLevel;
770 m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
771 m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
772
773 /* Notify listeners about GA state really changed: */
774 LogRel(("GUI: UISession::sltAdditionsChange: GA state really changed, notifying listeners.\n"));
775 emit sigAdditionsStateActualChange();
776 }
777 else
778 LogRel(("GUI: UISession::sltAdditionsChange: GA state doesn't really changed, still notifying listeners.\n"));
779
780 /* Notify listeners about GA state change event came: */
781 emit sigAdditionsStateChange();
782}
783
784UISession::UISession(UIMachine *pMachine)
785 : QObject(pMachine)
786 /* Base variables: */
787 , m_pMachine(pMachine)
788 , m_pConsoleEventhandler(0)
789 /* Common variables: */
790 , m_enmMachineStatePrevious(KMachineState_Null)
791 , m_enmMachineState(KMachineState_Null)
792 /* Guest additions flags: */
793 , m_ulGuestAdditionsRunLevel(0)
794 , m_fIsGuestSupportsGraphics(false)
795 , m_fIsGuestSupportsSeamless(false)
796{
797}
798
799UISession::~UISession()
800{
801}
802
803bool UISession::prepare()
804{
805 /* Prepare COM stuff: */
806 if (!prepareSession())
807 return false;
808
809 /* Cache media early if requested: */
810 if (uiCommon().agressiveCaching())
811 recacheMachineMedia();
812
813 /* Prepare GUI stuff: */
814 prepareNotificationCenter();
815 prepareConsoleEventHandlers();
816 prepareFramebuffers();
817 prepareConnections();
818 prepareSignalHandling();
819
820 /* True by default: */
821 return true;
822}
823
824bool UISession::prepareSession()
825{
826 /* Open session: */
827 m_comSession = uiCommon().openSession(uiCommon().managedVMUuid(),
828 uiCommon().isSeparateProcess()
829 ? KLockType_Shared
830 : KLockType_VM);
831 if (m_comSession.isNull())
832 return false;
833
834 /* Get machine: */
835 m_comMachine = m_comSession.GetMachine();
836 if (m_comMachine.isNull())
837 return false;
838
839 /* Get console: */
840 m_comConsole = m_comSession.GetConsole();
841 if (m_comConsole.isNull())
842 return false;
843
844 /* Get display: */
845 m_comDisplay = m_comConsole.GetDisplay();
846 if (m_comDisplay.isNull())
847 return false;
848
849 /* Get guest: */
850 m_comGuest = m_comConsole.GetGuest();
851 if (m_comGuest.isNull())
852 return false;
853
854 /* Get mouse: */
855 m_comMouse = m_comConsole.GetMouse();
856 if (m_comMouse.isNull())
857 return false;
858
859 /* Get keyboard: */
860 m_comKeyboard = m_comConsole.GetKeyboard();
861 if (m_comKeyboard.isNull())
862 return false;
863
864 /* Get debugger: */
865 m_comDebugger = m_comConsole.GetDebugger();
866 if (m_comDebugger.isNull())
867 return false;
868
869 /* Update machine-name: */
870 m_strMachineName = machine().GetName();
871
872 /* Update machine-state: */
873 m_enmMachineState = machine().GetState();
874
875 /* True by default: */
876 return true;
877}
878
879void UISession::prepareNotificationCenter()
880{
881 UINotificationCenter::create();
882}
883
884void UISession::prepareConsoleEventHandlers()
885{
886 /* Create console event-handler: */
887 m_pConsoleEventhandler = new UIConsoleEventHandler(this);
888
889 /* Console event connections: */
890 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigAdditionsChange,
891 this, &UISession::sltAdditionsChange);
892 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigAudioAdapterChange,
893 this, &UISession::sigAudioAdapterChange);
894 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigClipboardModeChange,
895 this, &UISession::sigClipboardModeChange);
896 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigCPUExecutionCapChange,
897 this, &UISession::sigCPUExecutionCapChange);
898 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigDnDModeChange,
899 this, &UISession::sigDnDModeChange);
900 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigGuestMonitorChange,
901 this, &UISession::sigGuestMonitorChange);
902 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMediumChange,
903 this, &UISession::sigMediumChange);
904 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigNetworkAdapterChange,
905 this, &UISession::sigNetworkAdapterChange);
906 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigRecordingChange,
907 this, &UISession::sigRecordingChange);
908 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigSharedFolderChange,
909 this, &UISession::sigSharedFolderChange);
910 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigStateChange,
911 this, &UISession::sltStateChange);
912 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigStorageDeviceChange,
913 this, &UISession::sigStorageDeviceChange);
914 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigUSBControllerChange,
915 this, &UISession::sigUSBControllerChange);
916 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigUSBDeviceStateChange,
917 this, &UISession::sigUSBDeviceStateChange);
918 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigVRDEChange,
919 this, &UISession::sigVRDEChange);
920 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigRuntimeError,
921 this, &UISession::sigRuntimeError);
922
923#ifdef VBOX_WS_MAC
924 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigShowWindow,
925 this, &UISession::sigShowWindows, Qt::QueuedConnection);
926#endif
927
928 /* Console keyboard connections: */
929 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigKeyboardLedsChange,
930 this, &UISession::sigKeyboardLedsChange);
931
932 /* Console mouse connections: */
933 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMousePointerShapeChange,
934 this, &UISession::sigMousePointerShapeChange);
935 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigMouseCapabilityChange,
936 this, &UISession::sigMouseCapabilityChange);
937 connect(m_pConsoleEventhandler, &UIConsoleEventHandler::sigCursorPositionChange,
938 this, &UISession::sigCursorPositionChange);
939}
940
941void UISession::prepareFramebuffers()
942{
943 /* Each framebuffer will be really prepared on first UIMachineView creation: */
944 m_frameBufferVector.resize(machine().GetGraphicsAdapter().GetMonitorCount());
945}
946
947void UISession::prepareConnections()
948{
949 /* UICommon connections: */
950 connect(&uiCommon(), &UICommon::sigAskToDetachCOM, this, &UISession::sltDetachCOM);
951}
952
953void UISession::prepareSignalHandling()
954{
955#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
956 struct sigaction sa;
957 sa.sa_sigaction = &signalHandlerSIGUSR1;
958 sigemptyset(&sa.sa_mask);
959 sa.sa_flags = SA_RESTART | SA_SIGINFO;
960 sigaction(SIGUSR1, &sa, NULL);
961#endif /* VBOX_GUI_WITH_KEYS_RESET_HANDLER */
962}
963
964void UISession::cleanupFramebuffers()
965{
966 /* Cleanup framebuffers finally: */
967 for (int i = m_frameBufferVector.size() - 1; i >= 0; --i)
968 {
969 UIFrameBuffer *pFrameBuffer = m_frameBufferVector[i];
970 if (pFrameBuffer)
971 {
972 /* Mark framebuffer as unused: */
973 pFrameBuffer->setMarkAsUnused(true);
974 /* Detach framebuffer from Display: */
975 pFrameBuffer->detach();
976 /* Delete framebuffer reference: */
977 delete pFrameBuffer;
978 }
979 }
980 m_frameBufferVector.clear();
981}
982
983void UISession::cleanupConsoleEventHandlers()
984{
985 /* Destroy console event-handler: */
986 delete m_pConsoleEventhandler;
987 m_pConsoleEventhandler = 0;
988}
989
990void UISession::cleanupNotificationCenter()
991{
992 UINotificationCenter::destroy();
993}
994
995void UISession::cleanupSession()
996{
997 /* Detach debugger: */
998 if (!m_comDebugger.isNull())
999 m_comDebugger.detach();
1000
1001 /* Detach keyboard: */
1002 if (!m_comKeyboard.isNull())
1003 m_comKeyboard.detach();
1004
1005 /* Detach mouse: */
1006 if (!m_comMouse.isNull())
1007 m_comMouse.detach();
1008
1009 /* Detach guest: */
1010 if (!m_comGuest.isNull())
1011 m_comGuest.detach();
1012
1013 /* Detach display: */
1014 if (!m_comDisplay.isNull())
1015 m_comDisplay.detach();
1016
1017 /* Detach console: */
1018 if (!m_comConsole.isNull())
1019 m_comConsole.detach();
1020
1021 /* Detach machine: */
1022 if (!m_comMachine.isNull())
1023 m_comMachine.detach();
1024
1025 /* Close session: */
1026 if (!m_comSession.isNull() && uiCommon().isVBoxSVCAvailable())
1027 {
1028 m_comSession.UnlockMachine();
1029 m_comSession.detach();
1030 }
1031}
1032
1033UIMachineLogic *UISession::machineLogic() const
1034{
1035 return uimachine() ? uimachine()->machineLogic() : 0;
1036}
1037
1038UIMachineWindow *UISession::activeMachineWindow() const
1039{
1040 return machineLogic() ? machineLogic()->activeMachineWindow() : 0;
1041}
1042
1043QWidget *UISession::mainMachineWindow() const
1044{
1045 return machineLogic() ? machineLogic()->mainMachineWindow() : 0;
1046}
1047
1048bool UISession::preprocessInitialization()
1049{
1050#ifdef VBOX_WITH_NETFLT
1051 /* Skip network interface name checks if VM in saved state: */
1052 if (!isSaved())
1053 {
1054 /* Make sure all the attached and enabled network
1055 * adapters are present on the host. This check makes sense
1056 * in two cases only - when attachement type is Bridged Network
1057 * or Host-only Interface. NOTE: Only currently enabled
1058 * attachement type is checked (incorrect parameters check for
1059 * currently disabled attachement types is skipped). */
1060 QStringList failedInterfaceNames;
1061 QStringList availableInterfaceNames;
1062
1063 /* Create host network interface names list: */
1064 foreach (const CHostNetworkInterface &comNetIface, uiCommon().host().GetNetworkInterfaces())
1065 {
1066 availableInterfaceNames << comNetIface.GetName();
1067 availableInterfaceNames << comNetIface.GetShortName();
1068 }
1069
1070 /* Enumerate all the virtual network adapters: */
1071 const ulong cCount = uiCommon().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(machine().GetChipsetType());
1072 for (ulong uAdapterIndex = 0; uAdapterIndex < cCount; ++uAdapterIndex)
1073 {
1074 CNetworkAdapter comNetworkAdapter = machine().GetNetworkAdapter(uAdapterIndex);
1075 if (comNetworkAdapter.GetEnabled())
1076 {
1077 /* Get physical network interface name for
1078 * currently enabled network attachement type: */
1079 QString strInterfaceName;
1080 switch (comNetworkAdapter.GetAttachmentType())
1081 {
1082 case KNetworkAttachmentType_Bridged:
1083 strInterfaceName = comNetworkAdapter.GetBridgedInterface();
1084 break;
1085#ifndef VBOX_WITH_VMNET
1086 case KNetworkAttachmentType_HostOnly:
1087 strInterfaceName = comNetworkAdapter.GetHostOnlyInterface();
1088 break;
1089#endif /* !VBOX_WITH_VMNET */
1090 default:
1091 break;
1092 }
1093
1094 if ( !strInterfaceName.isEmpty()
1095 && !availableInterfaceNames.contains(strInterfaceName))
1096 {
1097 LogRel(("GUI: Invalid network interface found: %s\n", strInterfaceName.toUtf8().constData()));
1098 failedInterfaceNames << QString("%1 (adapter %2)").arg(strInterfaceName).arg(uAdapterIndex + 1);
1099 }
1100 }
1101 }
1102
1103 /* Check if non-existent interfaces found: */
1104 if (!failedInterfaceNames.isEmpty())
1105 {
1106 if (msgCenter().warnAboutNetworkInterfaceNotFound(machineName(), failedInterfaceNames.join(", ")))
1107 machineLogic()->openNetworkSettingsDialog();
1108 else
1109 {
1110 LogRel(("GUI: Aborting startup due to preprocess initialization issue detected...\n"));
1111 return false;
1112 }
1113 }
1114 }
1115#endif /* VBOX_WITH_NETFLT */
1116
1117 /* Check for USB enumeration warning. Don't return false even if we have a warning: */
1118 CHost comHost = uiCommon().host();
1119 if (comHost.GetUSBDevices().isEmpty() && comHost.isWarning())
1120 {
1121 /* Do not bitch if USB disabled: */
1122 if (!machine().GetUSBControllers().isEmpty())
1123 {
1124 /* Do not bitch if there are no filters (check if enabled too?): */
1125 if (!machine().GetUSBDeviceFilters().GetDeviceFilters().isEmpty())
1126 UINotificationMessage::cannotEnumerateHostUSBDevices(comHost);
1127 }
1128 }
1129
1130 /* True by default: */
1131 return true;
1132}
1133
1134bool UISession::mountAdHocImage(KDeviceType enmDeviceType, UIMediumDeviceType enmMediumType, const QString &strMediumName)
1135{
1136 /* Get VBox: */
1137 CVirtualBox comVBox = uiCommon().virtualBox();
1138
1139 /* Prepare medium to mount: */
1140 UIMedium guiMedium;
1141
1142 /* The 'none' medium name means ejecting what ever is in the drive,
1143 * in that case => leave the guiMedium variable null. */
1144 if (strMediumName != "none")
1145 {
1146 /* Open the medium: */
1147 const CMedium comMedium = comVBox.OpenMedium(strMediumName, enmDeviceType, KAccessMode_ReadWrite, false /* fForceNewUuid */);
1148 if (!comVBox.isOk() || comMedium.isNull())
1149 {
1150 UINotificationMessage::cannotOpenMedium(comVBox, strMediumName);
1151 return false;
1152 }
1153
1154 /* Make sure medium ID is valid: */
1155 const QUuid uMediumId = comMedium.GetId();
1156 AssertReturn(!uMediumId.isNull(), false);
1157
1158 /* Try to find UIMedium among cached: */
1159 guiMedium = uiCommon().medium(uMediumId);
1160 if (guiMedium.isNull())
1161 {
1162 /* Cache new one if necessary: */
1163 guiMedium = UIMedium(comMedium, enmMediumType, KMediumState_Created);
1164 uiCommon().createMedium(guiMedium);
1165 }
1166 }
1167
1168 /* Search for a suitable storage slots: */
1169 QList<ExactStorageSlot> aFreeStorageSlots;
1170 QList<ExactStorageSlot> aBusyStorageSlots;
1171 foreach (const CStorageController &comController, machine().GetStorageControllers())
1172 {
1173 foreach (const CMediumAttachment &comAttachment, machine().GetMediumAttachmentsOfController(comController.GetName()))
1174 {
1175 /* Look for an optical devices only: */
1176 if (comAttachment.GetType() == enmDeviceType)
1177 {
1178 /* Append storage slot to corresponding list: */
1179 if (comAttachment.GetMedium().isNull())
1180 aFreeStorageSlots << ExactStorageSlot(comController.GetName(), comController.GetBus(),
1181 comAttachment.GetPort(), comAttachment.GetDevice());
1182 else
1183 aBusyStorageSlots << ExactStorageSlot(comController.GetName(), comController.GetBus(),
1184 comAttachment.GetPort(), comAttachment.GetDevice());
1185 }
1186 }
1187 }
1188
1189 /* Make sure at least one storage slot found: */
1190 QList<ExactStorageSlot> sStorageSlots = aFreeStorageSlots + aBusyStorageSlots;
1191 if (sStorageSlots.isEmpty())
1192 {
1193 UINotificationMessage::cannotMountImage(machineName(), strMediumName);
1194 return false;
1195 }
1196
1197 /* Try to mount medium into first available storage slot: */
1198 while (!sStorageSlots.isEmpty())
1199 {
1200 const ExactStorageSlot storageSlot = sStorageSlots.takeFirst();
1201 machine().MountMedium(storageSlot.controller, storageSlot.port, storageSlot.device, guiMedium.medium(), false /* force */);
1202 if (machine().isOk())
1203 break;
1204 }
1205
1206 /* Show error message if necessary: */
1207 if (!machine().isOk())
1208 {
1209 msgCenter().cannotRemountMedium(machine(), guiMedium, true /* mount? */, false /* retry? */, activeMachineWindow());
1210 return false;
1211 }
1212
1213 /* Save machine settings: */
1214 machine().SaveSettings();
1215
1216 /* Show error message if necessary: */
1217 if (!machine().isOk())
1218 {
1219 UINotificationMessage::cannotSaveMachineSettings(machine());
1220 return false;
1221 }
1222
1223 /* True by default: */
1224 return true;
1225}
1226
1227void UISession::recacheMachineMedia()
1228{
1229 /* Compose a list of machine media: */
1230 CMediumVector comMedia;
1231
1232 /* Enumerate all the controllers: */
1233 foreach (const CStorageController &comController, machine().GetStorageControllers())
1234 {
1235 /* Enumerate all the attachments: */
1236 foreach (const CMediumAttachment &comAttachment, machine().GetMediumAttachmentsOfController(comController.GetName()))
1237 {
1238 /* Skip unrelated device types: */
1239 const KDeviceType enmDeviceType = comAttachment.GetType();
1240 if ( enmDeviceType != KDeviceType_HardDisk
1241 && enmDeviceType != KDeviceType_Floppy
1242 && enmDeviceType != KDeviceType_DVD)
1243 continue;
1244 if ( comAttachment.GetIsEjected()
1245 || comAttachment.GetMedium().isNull())
1246 continue;
1247 comMedia.append(comAttachment.GetMedium());
1248 }
1249 }
1250
1251 /* Start media enumeration: */
1252 uiCommon().enumerateMedia(comMedia);
1253}
1254
1255#ifdef VBOX_GUI_WITH_KEYS_RESET_HANDLER
1256/**
1257 * Custom signal handler. When switching VTs, we might not get release events
1258 * for Ctrl-Alt and in case a savestate is performed on the new VT, the VM will
1259 * be saved with modifier keys stuck. This is annoying enough for introducing
1260 * this hack.
1261 */
1262/* static */
1263static void signalHandlerSIGUSR1(int sig, siginfo_t * /* pInfo */, void * /*pSecret */)
1264{
1265 /* Only SIGUSR1 is interesting: */
1266 if (sig == SIGUSR1)
1267 if (gpMachine)
1268 gpMachine->machineLogic()->keyboardHandler()->releaseAllPressedKeys();
1269}
1270#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