VirtualBox

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

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

FE/Qt: bugref:10322: Runtime UI: Reworking CConsole wrapper usage step-by-step; Stuff related to ACPI shutdown.

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