VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp

Last change on this file was 106292, checked in by vboxsync, 8 weeks ago

FE/Qt: Runtime UI: Make sure UIMachine properly conveys actual addition state changes (not just any addition state changes); That is required to enable/disable Seamless mode if it becames available (or not).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 80.7 KB
Line 
1/* $Id: UIMachine.cpp 106292 2024-10-10 15:15:38Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachine class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2024 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#ifdef VBOX_WS_WIN
31# include <QBitmap>
32#endif
33#ifdef VBOX_WS_MAC
34# include <QMenuBar>
35# include <QTimer>
36#endif
37
38/* GUI includes: */
39#include "UIActionPoolRuntime.h"
40#include "UICommon.h"
41#include "UIDesktopWidgetWatchdog.h"
42#include "UIExtraDataManager.h"
43#include "UIGlobalSession.h"
44#include "UIIconPool.h"
45#include "UILocalMachineStuff.h"
46#include "UILoggingDefs.h"
47#include "UIMachine.h"
48#include "UIMachineLogic.h"
49#include "UIMachineWindow.h"
50#include "UIMessageCenter.h"
51#include "UINotificationCenter.h"
52#include "UISession.h"
53#ifdef VBOX_WS_MAC
54# include "UICocoaApplication.h"
55# include "VBoxUtils-darwin.h"
56#endif
57
58/* COM includes: */
59#include "CAudioAdapter.h"
60#include "CAudioSettings.h"
61#include "CConsole.h"
62#include "CGraphicsAdapter.h"
63#include "CHostVideoInputDevice.h"
64#include "CMachine.h"
65#include "CMediumAttachment.h"
66#include "CNetworkAdapter.h"
67#include "CProgress.h"
68#include "CRecordingSettings.h"
69#include "CSession.h"
70#include "CSnapshot.h"
71#include "CSystemProperties.h"
72#include "CUSBController.h"
73#include "CUSBDeviceFilters.h"
74#include "CVRDEServer.h"
75
76
77#ifdef VBOX_WS_MAC
78/**
79 * MacOS X: Application Services: Core Graphics: Display reconfiguration callback.
80 *
81 * Notifies UIMachine about @a display configuration change.
82 * Corresponding change described by Core Graphics @a flags.
83 * Uses UIMachine @a pHandler to process this change.
84 *
85 * @note Last argument (@a pHandler) must always be valid pointer to UIMachine object.
86 * @note Calls for UIMachine::sltHandleHostDisplayAboutToChange() slot if display configuration changed.
87 */
88void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *pHandler)
89{
90 /* Which flags we are handling? */
91 int iHandledFlags = kCGDisplayAddFlag /* display added */
92 | kCGDisplayRemoveFlag /* display removed */
93 | kCGDisplaySetModeFlag /* display mode changed */;
94
95 /* Handle 'display-add' case: */
96 if (flags & kCGDisplayAddFlag)
97 LogRelFlow(("GUI: UIMachine::cgDisplayReconfigurationCallback: Display added.\n"));
98 /* Handle 'display-remove' case: */
99 else if (flags & kCGDisplayRemoveFlag)
100 LogRelFlow(("GUI: UIMachine::cgDisplayReconfigurationCallback: Display removed.\n"));
101 /* Handle 'mode-set' case: */
102 else if (flags & kCGDisplaySetModeFlag)
103 LogRelFlow(("GUI: UIMachine::cgDisplayReconfigurationCallback: Display mode changed.\n"));
104
105 /* Ask handler to process our callback: */
106 if (flags & iHandledFlags)
107 QTimer::singleShot(0, static_cast<UIMachine*>(pHandler),
108 SLOT(sltHandleHostDisplayAboutToChange()));
109
110 Q_UNUSED(display);
111}
112#endif /* VBOX_WS_MAC */
113
114
115/* static */
116UIMachine *UIMachine::s_pInstance = 0;
117
118/* static */
119bool UIMachine::startMachine()
120{
121 /* Make sure machine is not created: */
122 AssertReturn(!s_pInstance, false);
123
124 /* Restore current snapshot if requested: */
125 if ( uiCommon().shouldRestoreCurrentSnapshot()
126 || !uiCommon().getSnapshotToRestore().isEmpty())
127 {
128 /* Create temporary session: */
129 CSession comSession = openSession(KLockType_VM);
130 if (comSession.isNull())
131 return false;
132
133 /* Which VM we operate on? */
134 CMachine comMachine = comSession.GetMachine();
135 /* Which snapshot are we restoring? */
136 CSnapshot comSnapshot = uiCommon().shouldRestoreCurrentSnapshot()
137 ? comMachine.GetCurrentSnapshot()
138 : comMachine.FindSnapshot(uiCommon().getSnapshotToRestore());
139
140 /* Prepare restore-snapshot progress: */
141 CProgress comProgress = comMachine.RestoreSnapshot(comSnapshot);
142 if (!comMachine.isOk())
143 return msgCenter().cannotRestoreSnapshot(comMachine,
144 comSnapshot.isOk() ? comSnapshot.GetName()
145 /** @todo deal better with snapshot-not found issues: */
146 : uiCommon().shouldRestoreCurrentSnapshot() ? "current"
147 : uiCommon().getSnapshotToRestore(),
148 comMachine.GetName());
149
150 /* Show the snapshot-discarding progress: */
151 msgCenter().showModalProgressDialog(comProgress, comMachine.GetName(), ":/progress_snapshot_discard_90px.png");
152 if (comProgress.GetResultCode() != 0)
153 return msgCenter().cannotRestoreSnapshot(comProgress, comSnapshot.GetName(), comMachine.GetName());
154
155 /* Unlock session finally: */
156 comSession.UnlockMachine();
157
158 /* Clear snapshot-restoring request: */
159 uiCommon().clearSnapshotRestoreOptions();
160 }
161
162 /* For separate process we should launch VM before UI: */
163 if (uiCommon().isSeparateProcess())
164 {
165 /* Get corresponding machine: */
166 CMachine machine = gpGlobalSession->virtualBox().FindMachine(uiCommon().managedVMUuid().toString());
167 AssertMsgReturn(!machine.isNull(), ("UICommon::managedVMUuid() should have filter that case before!\n"), false);
168
169 /* Try to launch corresponding machine: */
170 if (!launchMachine(machine, UILaunchMode_Separate))
171 return false;
172 }
173
174 /* Try to create machine UI: */
175 return create();
176}
177
178/* static */
179bool UIMachine::create()
180{
181 /* Make sure machine is not created: */
182 AssertReturn(!s_pInstance, false);
183
184 /* Create machine UI: */
185 new UIMachine;
186
187 /* Make sure it's prepared: */
188 if (!s_pInstance->prepare())
189 {
190 /* Destroy machine UI otherwise: */
191 destroy();
192 /* False in that case: */
193 return false;
194 }
195
196 /* True by default: */
197 return true;
198}
199
200/* static */
201void UIMachine::destroy()
202{
203 /* Make sure machine is created: */
204 if (!s_pInstance)
205 return;
206
207 /* Protect versus recursive call: */
208 UIMachine *pInstance = s_pInstance;
209 s_pInstance = 0;
210 /* Cleanup machine UI: */
211 pInstance->cleanup();
212 /* Destroy machine UI: */
213 delete pInstance;
214}
215
216UIFrameBuffer *UIMachine::frameBuffer(ulong uScreenId)
217{
218 return uisession()->frameBuffer(uScreenId);
219}
220
221QWidget* UIMachine::activeWindow() const
222{
223 return machineLogic() && machineLogic()->activeMachineWindow()
224 ? machineLogic()->activeMachineWindow()
225 : 0;
226}
227
228bool UIMachine::isSessionValid() const
229{
230 return uisession() ? uisession()->isValid() : false;
231}
232
233void UIMachine::asyncChangeVisualState(UIVisualStateType visualState)
234{
235 emit sigRequestAsyncVisualStateChange(visualState);
236}
237
238void UIMachine::setRequestedVisualState(UIVisualStateType visualStateType)
239{
240 /* Remember requested visual state: */
241 m_enmRequestedVisualState = visualStateType;
242
243 /* Save only if it's different from Invalid and from current one: */
244 if ( m_enmRequestedVisualState != UIVisualStateType_Invalid
245 && gEDataManager->requestedVisualState(uiCommon().managedVMUuid()) != m_enmRequestedVisualState)
246 gEDataManager->setRequestedVisualState(m_enmRequestedVisualState, uiCommon().managedVMUuid());
247}
248
249UIVisualStateType UIMachine::requestedVisualState() const
250{
251 return m_enmRequestedVisualState;
252}
253
254QString UIMachine::machineName() const
255{
256 return uisession()->machineName();
257}
258
259QString UIMachine::osTypeId() const
260{
261 return uisession()->osTypeId();
262}
263
264void UIMachine::acquireMachinePixmap(const QSize &size, QPixmap &pixmap)
265{
266 return uisession()->acquireMachinePixmap(size, pixmap);
267}
268
269void UIMachine::acquireUserMachineIcon(QIcon &icon)
270{
271 return uisession()->acquireUserMachineIcon(icon);
272}
273
274bool UIMachine::acquireArchitectureType(KPlatformArchitecture &enmType)
275{
276 return uisession()->acquireArchitectureType(enmType);
277}
278
279bool UIMachine::acquireChipsetType(KChipsetType &enmType)
280{
281 return uisession()->acquireChipsetType(enmType);
282}
283
284void UIMachine::updateStateAdditionsActions()
285{
286 /* Make sure action-pool knows whether GA supports graphics: */
287 actionPool()->toRuntime()->setGuestSupportsGraphics(isGuestSupportsGraphics());
288 /* Enable/Disable Upgrade Additions action depending on feature status: */
289 actionPool()->action(UIActionIndexRT_M_Devices_S_UpgradeGuestAdditions)->setEnabled(uisession()->guestAdditionsUpgradable());
290}
291
292void UIMachine::updateStateAudioActions()
293{
294 /* Make sure Audio adapter is present: */
295 bool fAdapterPresent = false;
296 acquireWhetherAudioAdapterPresent(fAdapterPresent);
297 if (fAdapterPresent)
298 {
299 /* Check/Uncheck Audio adapter output/input actions depending on features status: */
300 bool fAudioOutputEnabled = false;
301 bool fAudioInputEnabled = false;
302 acquireWhetherAudioAdapterOutputEnabled(fAudioOutputEnabled);
303 acquireWhetherAudioAdapterInputEnabled(fAudioInputEnabled);
304 actionPool()->action(UIActionIndexRT_M_Devices_M_Audio_T_Output)->blockSignals(true);
305 actionPool()->action(UIActionIndexRT_M_Devices_M_Audio_T_Output)->setChecked(fAudioOutputEnabled);
306 actionPool()->action(UIActionIndexRT_M_Devices_M_Audio_T_Output)->blockSignals(false);
307 actionPool()->action(UIActionIndexRT_M_Devices_M_Audio_T_Input)->blockSignals(true);
308 actionPool()->action(UIActionIndexRT_M_Devices_M_Audio_T_Input)->setChecked(fAudioInputEnabled);
309 actionPool()->action(UIActionIndexRT_M_Devices_M_Audio_T_Input)->blockSignals(false);
310 }
311}
312
313void UIMachine::updateStateRecordingAction()
314{
315 /* Make sure Recording settings present: */
316 bool fSettingsPresent = false;
317 acquireWhetherRecordingSettingsPresent(fSettingsPresent);
318 AssertMsgReturnVoid(fSettingsPresent,
319 ("Recording settings can't be null!\n"));
320
321 /* Check/Uncheck Recording action depending on feature status: */
322 bool fSettingsEnabled = false;
323 acquireWhetherRecordingSettingsEnabled(fSettingsEnabled);
324 actionPool()->action(UIActionIndexRT_M_View_M_Recording_T_Start)->blockSignals(true);
325 actionPool()->action(UIActionIndexRT_M_View_M_Recording_T_Start)->setChecked(fSettingsEnabled);
326 actionPool()->action(UIActionIndexRT_M_View_M_Recording_T_Start)->blockSignals(false);
327}
328
329void UIMachine::updateStateVRDEServerAction()
330{
331 /* Make sure VRDE server present: */
332 bool fServerPresent = false;
333 acquireWhetherVRDEServerPresent(fServerPresent);
334 AssertMsgReturnVoid(fServerPresent,
335 ("VRDE server can't be null!\n"));
336
337 /* Check/Uncheck VRDE Server action depending on feature status: */
338 bool fServerEnabled = false;
339 acquireWhetherVRDEServerEnabled(fServerEnabled);
340 actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->blockSignals(true);
341 actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->setChecked(fServerEnabled);
342 actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer)->blockSignals(false);
343}
344
345KMachineState UIMachine::machineStatePrevious() const
346{
347 return uisession()->machineStatePrevious();
348}
349
350KMachineState UIMachine::machineState() const
351{
352 return uisession()->machineState();
353}
354
355void UIMachine::forgetPreviousMachineState()
356{
357 uisession()->forgetPreviousMachineState();
358}
359
360bool UIMachine::acquireLiveMachineState(KMachineState &enmState)
361{
362 return uisession()->acquireLiveMachineState(enmState);
363}
364
365bool UIMachine::isTurnedOff() const
366{
367 return uisession()->isTurnedOff();
368}
369
370bool UIMachine::isPaused() const
371{
372 return uisession()->isPaused();
373}
374
375bool UIMachine::wasPaused() const
376{
377 return uisession()->wasPaused();
378}
379
380bool UIMachine::isRunning() const
381{
382 return uisession()->isRunning();
383}
384
385bool UIMachine::isStuck() const
386{
387 return uisession()->isStuck();
388}
389
390bool UIMachine::isGuestScreenUnDrawable() const
391{
392 return uisession()->isGuestScreenUnDrawable();
393}
394
395bool UIMachine::reset()
396{
397 return uisession()->reset();
398}
399
400bool UIMachine::pause()
401{
402 return uisession()->pause();
403}
404
405bool UIMachine::unpause()
406{
407 return uisession()->unpause();
408}
409
410bool UIMachine::setPause(bool fPause)
411{
412 return uisession()->setPause(fPause);
413}
414
415bool UIMachine::acquireSettingsFilePath(QString &strPath)
416{
417 return uisession()->acquireSettingsFilePath(strPath);
418}
419
420bool UIMachine::saveSettings()
421{
422 return uisession()->saveSettings();
423}
424
425bool UIMachine::acquireSnapshotCount(ulong &uCount)
426{
427 return uisession()->acquireSnapshotCount(uCount);
428}
429
430bool UIMachine::acquireCurrentSnapshotName(QString &strName)
431{
432 return uisession()->acquireCurrentSnapshotName(strName);
433}
434
435bool UIMachine::acquireMaxSnapshotIndex(const QString &strNameTemplate, ulong &uIndex)
436{
437 return uisession()->acquireMaxSnapshotIndex(strNameTemplate, uIndex);
438}
439
440void UIMachine::takeSnapshot(const QString &strName, const QString &strDescription)
441{
442 return uisession()->takeSnapshot(strName, strDescription);
443}
444
445bool UIMachine::acquireWhetherAudioAdapterPresent(bool &fPresent)
446{
447 return uisession()->acquireWhetherAudioAdapterPresent(fPresent);
448}
449
450bool UIMachine::acquireWhetherAudioAdapterEnabled(bool &fEnabled)
451{
452 return uisession()->acquireWhetherAudioAdapterEnabled(fEnabled);
453}
454
455bool UIMachine::acquireWhetherAudioAdapterOutputEnabled(bool &fEnabled)
456{
457 return uisession()->acquireWhetherAudioAdapterOutputEnabled(fEnabled);
458}
459
460bool UIMachine::acquireWhetherAudioAdapterInputEnabled(bool &fEnabled)
461{
462 return uisession()->acquireWhetherAudioAdapterInputEnabled(fEnabled);
463}
464
465bool UIMachine::setAudioAdapterOutputEnabled(bool fEnabled)
466{
467 return uisession()->setAudioAdapterOutputEnabled(fEnabled);
468}
469
470bool UIMachine::setAudioAdapterInputEnabled(bool fEnabled)
471{
472 return uisession()->setAudioAdapterInputEnabled(fEnabled);
473}
474
475bool UIMachine::isScreenVisibleHostDesires(ulong uScreenId) const
476{
477 /* Make sure index feats the bounds: */
478 AssertReturn(uScreenId < (ulong)m_guestScreenVisibilityVectorHostDesires.size(), false);
479
480 /* Return 'actual' (host-desire) visibility status: */
481 return m_guestScreenVisibilityVectorHostDesires.value((int)uScreenId);
482}
483
484void UIMachine::setScreenVisibleHostDesires(ulong uScreenId, bool fIsMonitorVisible)
485{
486 /* Make sure index feats the bounds: */
487 AssertReturnVoid(uScreenId < (ulong)m_guestScreenVisibilityVectorHostDesires.size());
488
489 /* Remember 'actual' (host-desire) visibility status: */
490 m_guestScreenVisibilityVectorHostDesires[(int)uScreenId] = fIsMonitorVisible;
491
492 /* And remember the request in extra data for guests with VMSVGA: */
493 /* This should be done before the actual hint is sent in case the guest overrides it. */
494 gEDataManager->setLastGuestScreenVisibilityStatus(uScreenId, fIsMonitorVisible, uiCommon().managedVMUuid());
495}
496
497bool UIMachine::isScreenVisible(ulong uScreenId) const
498{
499 /* Make sure index feats the bounds: */
500 AssertReturn(uScreenId < (ulong)m_guestScreenVisibilityVector.size(), false);
501
502 /* Return 'actual' visibility status: */
503 return m_guestScreenVisibilityVector.value((int)uScreenId);
504}
505
506void UIMachine::setScreenVisible(ulong uScreenId, bool fIsMonitorVisible)
507{
508 /* Make sure index feats the bounds: */
509 AssertReturnVoid(uScreenId < (ulong)m_guestScreenVisibilityVector.size());
510
511 /* Remember 'actual' visibility status: */
512 m_guestScreenVisibilityVector[(int)uScreenId] = fIsMonitorVisible;
513 /* Remember 'desired' visibility status: */
514 // See note in UIMachineView::sltHandleNotifyChange() regarding the graphics controller check. */
515 KGraphicsControllerType enmType = KGraphicsControllerType_Null;
516 acquireGraphicsControllerType(enmType);
517 if (enmType != KGraphicsControllerType_VMSVGA)
518 gEDataManager->setLastGuestScreenVisibilityStatus(uScreenId, fIsMonitorVisible, uiCommon().managedVMUuid());
519
520 /* Make sure action-pool knows guest-screen visibility status: */
521 actionPool()->toRuntime()->setGuestScreenVisible(uScreenId, fIsMonitorVisible);
522}
523
524int UIMachine::countOfVisibleWindows()
525{
526 int cCountOfVisibleWindows = 0;
527 for (int i = 0; i < m_guestScreenVisibilityVector.size(); ++i)
528 if (m_guestScreenVisibilityVector[i])
529 ++cCountOfVisibleWindows;
530 return cCountOfVisibleWindows;
531}
532
533QList<int> UIMachine::listOfVisibleWindows() const
534{
535 QList<int> visibleWindows;
536 for (int i = 0; i < m_guestScreenVisibilityVector.size(); ++i)
537 if (m_guestScreenVisibilityVector.at(i))
538 visibleWindows.push_back(i);
539 return visibleWindows;
540}
541
542QSize UIMachine::guestScreenSize(ulong uScreenId) const
543{
544 return uisession()->frameBufferSize(uScreenId);
545}
546
547QSize UIMachine::lastFullScreenSize(ulong uScreenId) const
548{
549 /* Make sure index fits the bounds: */
550 AssertReturn(uScreenId < (ulong)m_monitorLastFullScreenSizeVector.size(), QSize(-1, -1));
551
552 /* Return last full-screen size: */
553 return m_monitorLastFullScreenSizeVector.value((int)uScreenId);
554}
555
556void UIMachine::setLastFullScreenSize(ulong uScreenId, QSize size)
557{
558 /* Make sure index fits the bounds: */
559 AssertReturnVoid(uScreenId < (ulong)m_monitorLastFullScreenSizeVector.size());
560
561 /* Remember last full-screen size: */
562 m_monitorLastFullScreenSizeVector[(int)uScreenId] = size;
563}
564
565bool UIMachine::acquireGraphicsControllerType(KGraphicsControllerType &enmType)
566{
567 return uisession()->acquireGraphicsControllerType(enmType);
568}
569
570bool UIMachine::acquireVRAMSize(ulong &uSize)
571{
572 return uisession()->acquireVRAMSize(uSize);
573}
574
575bool UIMachine::acquireWhetherAccelerate3DEnabled(bool &fEnabled)
576{
577 return uisession()->acquireWhetherAccelerate3DEnabled(fEnabled);
578}
579
580bool UIMachine::acquireMonitorCount(ulong &uCount)
581{
582 return uisession()->acquireMonitorCount(uCount);
583}
584
585bool UIMachine::acquireGuestScreenParameters(ulong uScreenId,
586 ulong &uWidth, ulong &uHeight, ulong &uBitsPerPixel,
587 long &xOrigin, long &yOrigin, KGuestMonitorStatus &enmMonitorStatus)
588{
589 return uisession()->acquireGuestScreenParameters(uScreenId,
590 uWidth, uHeight, uBitsPerPixel,
591 xOrigin, yOrigin, enmMonitorStatus);
592}
593
594bool UIMachine::acquireSavedGuestScreenInfo(ulong uScreenId,
595 long &xOrigin, long &yOrigin,
596 ulong &uWidth, ulong &uHeight, bool &fEnabled)
597{
598 return uisession()->acquireSavedGuestScreenInfo(uScreenId,
599 xOrigin, yOrigin,
600 uWidth, uHeight, fEnabled);
601}
602
603bool UIMachine::setVideoModeHint(ulong uScreenId, bool fEnabled, bool fChangeOrigin,
604 long xOrigin, long yOrigin, ulong uWidth, ulong uHeight,
605 ulong uBitsPerPixel, bool fNotify)
606{
607 return uisession()->setVideoModeHint(uScreenId, fEnabled, fChangeOrigin,
608 xOrigin, yOrigin, uWidth, uHeight,
609 uBitsPerPixel, fNotify);
610}
611
612bool UIMachine::acquireVideoModeHint(ulong uScreenId, bool &fEnabled, bool &fChangeOrigin,
613 long &xOrigin, long &yOrigin, ulong &uWidth, ulong &uHeight,
614 ulong &uBitsPerPixel)
615{
616 return uisession()->acquireVideoModeHint(uScreenId, fEnabled, fChangeOrigin,
617 xOrigin, yOrigin, uWidth, uHeight,
618 uBitsPerPixel);
619}
620
621bool UIMachine::acquireScreenShot(ulong uScreenId, ulong uWidth, ulong uHeight, KBitmapFormat enmFormat, uchar *pBits)
622{
623 return uisession()->acquireScreenShot(uScreenId, uWidth, uHeight, enmFormat, pBits);
624}
625
626bool UIMachine::acquireSavedScreenshotInfo(ulong uScreenId, ulong &uWidth, ulong &uHeight, QVector<KBitmapFormat> &formats)
627{
628 return uisession()->acquireSavedScreenshotInfo(uScreenId, uWidth, uHeight, formats);
629}
630
631bool UIMachine::acquireSavedScreenshot(ulong uScreenId, KBitmapFormat enmFormat,
632 ulong &uWidth, ulong &uHeight, QVector<BYTE> &screenshot)
633{
634 return uisession()->acquireSavedScreenshot(uScreenId, enmFormat,
635 uWidth, uHeight, screenshot);
636}
637
638bool UIMachine::notifyScaleFactorChange(ulong uScreenId, ulong uScaleFactorWMultiplied, ulong uScaleFactorHMultiplied)
639{
640 return uisession()->notifyScaleFactorChange(uScreenId, uScaleFactorWMultiplied, uScaleFactorHMultiplied);
641}
642
643bool UIMachine::notifyHiDPIOutputPolicyChange(bool fUnscaledHiDPI)
644{
645 return uisession()->notifyHiDPIOutputPolicyChange(fUnscaledHiDPI);
646}
647
648bool UIMachine::setSeamlessMode(bool fEnabled)
649{
650 return uisession()->setSeamlessMode(fEnabled);
651}
652
653bool UIMachine::viewportChanged(ulong uScreenId, ulong xOrigin, ulong yOrigin, ulong uWidth, ulong uHeight)
654{
655 return uisession()->viewportChanged(uScreenId, xOrigin, yOrigin, uWidth, uHeight);
656}
657
658bool UIMachine::invalidateAndUpdate()
659{
660 return uisession()->invalidateAndUpdate();
661}
662
663bool UIMachine::invalidateAndUpdateScreen(ulong uScreenId)
664{
665 return uisession()->invalidateAndUpdateScreen(uScreenId);
666}
667
668bool UIMachine::acquireWhetherVRDEServerPresent(bool &fPresent)
669{
670 return uisession()->acquireWhetherVRDEServerPresent(fPresent);
671}
672
673bool UIMachine::acquireWhetherVRDEServerEnabled(bool &fEnabled)
674{
675 return uisession()->acquireWhetherVRDEServerEnabled(fEnabled);
676}
677
678bool UIMachine::setVRDEServerEnabled(bool fEnabled)
679{
680 return uisession()->setVRDEServerEnabled(fEnabled);
681}
682
683bool UIMachine::acquireVRDEServerPort(long &iPort)
684{
685 return uisession()->acquireVRDEServerPort(iPort);
686}
687
688bool UIMachine::acquireWhetherRecordingSettingsPresent(bool &fPresent)
689{
690 return uisession()->acquireWhetherRecordingSettingsPresent(fPresent);
691}
692
693bool UIMachine::acquireWhetherRecordingSettingsEnabled(bool &fEnabled)
694{
695 return uisession()->acquireWhetherRecordingSettingsEnabled(fEnabled);
696}
697
698bool UIMachine::setRecordingSettingsEnabled(bool fEnabled)
699{
700 return uisession()->setRecordingSettingsEnabled(fEnabled);
701}
702
703bool UIMachine::isGuestAdditionsActive() const
704{
705 return uisession()->isGuestAdditionsActive();
706}
707
708bool UIMachine::isGuestSupportsGraphics() const
709{
710 return uisession()->isGuestSupportsGraphics();
711}
712
713bool UIMachine::isGuestSupportsSeamless() const
714{
715 return uisession()->isGuestSupportsSeamless();
716}
717
718bool UIMachine::acquireGuestAdditionsVersion(QString &strVersion)
719{
720 return uisession()->acquireGuestAdditionsVersion(strVersion);
721}
722
723bool UIMachine::acquireGuestAdditionsRevision(ulong &uRevision)
724{
725 return uisession()->acquireGuestAdditionsRevision(uRevision);
726}
727
728bool UIMachine::notifyGuiFocusChange(bool fInfocus)
729{
730 return uisession()->notifyGuiFocusChange(fInfocus);
731}
732
733bool UIMachine::putScancode(LONG iCode)
734{
735 return uisession()->putScancode(iCode);
736}
737
738bool UIMachine::putScancodes(const QVector<LONG> &codes)
739{
740 return uisession()->putScancodes(codes);
741}
742
743bool UIMachine::putCAD()
744{
745 return uisession()->putCAD();
746}
747
748bool UIMachine::releaseKeys()
749{
750 return uisession()->releaseKeys();
751}
752
753bool UIMachine::putUsageCode(LONG iUsageCode, LONG iUsagePage, bool fKeyRelease)
754{
755 return uisession()->putUsageCode(iUsageCode, iUsagePage, fKeyRelease);
756}
757
758bool UIMachine::putMouseEvent(long iDx, long iDy, long iDz, long iDw, long iButtonState)
759{
760 return uisession()->putMouseEvent(iDx, iDy, iDz, iDw, iButtonState);
761}
762
763bool UIMachine::putMouseEventAbsolute(long iX, long iY, long iDz, long iDw, long iButtonState)
764{
765 return uisession()->putMouseEventAbsolute(iX, iY, iDz, iDw, iButtonState);
766}
767
768bool UIMachine::putEventMultiTouch(long iCount, const QVector<LONG64> &contacts, bool fIsTouchScreen, ulong uScanTime)
769{
770 return uisession()->putEventMultiTouch(iCount, contacts, fIsTouchScreen, uScanTime);
771}
772
773bool UIMachine::acquireClipboardMode(KClipboardMode &enmMode)
774{
775 return uisession()->acquireClipboardMode(enmMode);
776}
777
778bool UIMachine::setClipboardMode(KClipboardMode enmMode)
779{
780 return uisession()->setClipboardMode(enmMode);
781}
782
783bool UIMachine::toggleClipboardFileTransfer(bool fEnabled)
784{
785 return uisession()->toggleClipboardFileTransfer(fEnabled);
786}
787
788bool UIMachine::isClipboardFileTransferEnabled()
789{
790 return uisession()->isClipboardFileTransferEnabled();
791}
792
793bool UIMachine::acquireDnDMode(KDnDMode &enmMode)
794{
795 return uisession()->acquireDnDMode(enmMode);
796}
797
798bool UIMachine::setDnDMode(KDnDMode enmMode)
799{
800 return uisession()->setDnDMode(enmMode);
801}
802
803bool UIMachine::acquireAmountOfStorageDevices(ulong &cHardDisks, ulong &cOpticalDrives, ulong &cFloppyDrives)
804{
805 return uisession()->acquireAmountOfStorageDevices(cHardDisks, cOpticalDrives, cFloppyDrives);
806}
807
808bool UIMachine::storageDevices(KDeviceType enmDeviceType, QList<StorageDeviceInfo> &guiStorageDevices)
809{
810 return uisession()->storageDevices(enmDeviceType, guiStorageDevices);
811}
812
813bool UIMachine::acquireEncryptedMedia(EncryptedMediumMap &media)
814{
815 return uisession()->acquireEncryptedMedia(media);
816}
817
818bool UIMachine::addEncryptionPassword(const QString &strId, const QString &strPassword, bool fClearOnSuspend)
819{
820 return uisession()->addEncryptionPassword(strId, strPassword, fClearOnSuspend);
821}
822
823bool UIMachine::acquireAmountOfImmutableImages(ulong &cAmount)
824{
825 return uisession()->acquireAmountOfImmutableImages(cAmount);
826}
827
828bool UIMachine::mountBootMedium(const QUuid &uMediumId)
829{
830 return uisession()->mountBootMedium(uMediumId);
831}
832
833void UIMachine::prepareStorageMenu(QMenu *pMenu,
834 QObject *pListener, const char *pszSlotName,
835 const QString &strControllerName, const StorageSlot &storageSlot)
836{
837 return uisession()->prepareStorageMenu(pMenu,
838 pListener, pszSlotName,
839 strControllerName, storageSlot);
840}
841
842void UIMachine::updateMachineStorage(const UIMediumTarget &target, UIActionPool *pActionPool)
843{
844 return uisession()->updateMachineStorage(target, pActionPool);
845}
846
847void UIMachine::acquireWhetherUSBControllerEnabled(bool &fEnabled)
848{
849 return uisession()->acquireWhetherUSBControllerEnabled(fEnabled);
850}
851
852void UIMachine::acquireWhetherVideoInputDevicesEnabled(bool &fEnabled)
853{
854 return uisession()->acquireWhetherVideoInputDevicesEnabled(fEnabled);
855}
856
857bool UIMachine::usbDevices(QList<USBDeviceInfo> &guiUSBDevices)
858{
859 return uisession()->usbDevices(guiUSBDevices);
860}
861
862bool UIMachine::attachUSBDevice(const QUuid &uId)
863{
864 return uisession()->attachUSBDevice(uId);
865}
866
867bool UIMachine::detachUSBDevice(const QUuid &uId)
868{
869 return uisession()->detachUSBDevice(uId);
870}
871
872bool UIMachine::webcamDevices(QList<WebcamDeviceInfo> &guiWebcamDevices)
873{
874 return uisession()->webcamDevices(guiWebcamDevices);
875}
876
877bool UIMachine::webcamAttach(const QString &strPath, const QString &strName)
878{
879 return uisession()->webcamAttach(strPath, strName);
880}
881
882bool UIMachine::webcamDetach(const QString &strPath, const QString &strName)
883{
884 return uisession()->webcamDetach(strPath, strName);
885}
886
887bool UIMachine::acquireWhetherNetworkAdapterEnabled(ulong uSlot, bool &fEnabled)
888{
889 return uisession()->acquireWhetherNetworkAdapterEnabled(uSlot, fEnabled);
890}
891
892bool UIMachine::acquireWhetherAtLeastOneNetworkAdapterEnabled(bool &fEnabled)
893{
894 return uisession()->acquireWhetherAtLeastOneNetworkAdapterEnabled(fEnabled);
895}
896
897bool UIMachine::acquireWhetherNetworkCableConnected(ulong uSlot, bool &fConnected)
898{
899 return uisession()->acquireWhetherNetworkCableConnected(uSlot, fConnected);
900}
901
902bool UIMachine::setNetworkCableConnected(ulong uSlot, bool fConnected)
903{
904 return uisession()->setNetworkCableConnected(uSlot, fConnected);
905}
906
907bool UIMachine::acquireDeviceActivity(const QVector<KDeviceType> &deviceTypes, QVector<KDeviceActivity> &states)
908{
909 return uisession()->acquireDeviceActivity(deviceTypes, states);
910}
911
912void UIMachine::acquireHardDiskStatusInfo(QString &strInfo, uint &cAttachmentsCount)
913{
914 uisession()->acquireHardDiskStatusInfo(strInfo, cAttachmentsCount);
915}
916
917void UIMachine::acquireOpticalDiskStatusInfo(QString &strInfo, uint &cAttachmentsCount, uint &cAttachmentsMountedCount)
918{
919 uisession()->acquireOpticalDiskStatusInfo(strInfo, cAttachmentsCount, cAttachmentsMountedCount);
920}
921
922void UIMachine::acquireFloppyDiskStatusInfo(QString &strInfo, uint &cAttachmentsCount, uint &cAttachmentsMountedCount)
923{
924 uisession()->acquireFloppyDiskStatusInfo(strInfo, cAttachmentsCount, cAttachmentsMountedCount);
925}
926
927void UIMachine::acquireAudioStatusInfo(QString &strInfo, bool &fAudioEnabled, bool &fEnabledOutput, bool &fEnabledInput)
928{
929 uisession()->acquireAudioStatusInfo(strInfo, fAudioEnabled, fEnabledOutput, fEnabledInput);
930}
931
932void UIMachine::acquireNetworkStatusInfo(QString &strInfo, bool &fAdaptersPresent, bool &fCablesDisconnected)
933{
934 uisession()->acquireNetworkStatusInfo(strInfo, fAdaptersPresent, fCablesDisconnected);
935}
936
937void UIMachine::acquireUsbStatusInfo(QString &strInfo, bool &fUsbEnabled, uint &cUsbFilterCount)
938{
939 uisession()->acquireUsbStatusInfo(strInfo, fUsbEnabled, cUsbFilterCount);
940}
941
942void UIMachine::acquireSharedFoldersStatusInfo(QString &strInfo, uint &cFoldersCount)
943{
944 uisession()->acquireSharedFoldersStatusInfo(strInfo, cFoldersCount);
945}
946
947void UIMachine::acquireDisplayStatusInfo(QString &strInfo, uint &uVRAMSize, uint &cMonitorCount, bool &fAcceleration3D)
948{
949 uisession()->acquireDisplayStatusInfo(strInfo, uVRAMSize, cMonitorCount, fAcceleration3D);
950}
951
952void UIMachine::acquireRecordingStatusInfo(QString &strInfo, bool &fRecordingEnabled, bool &fMachinePaused)
953{
954 uisession()->acquireRecordingStatusInfo(strInfo, fRecordingEnabled, fMachinePaused);
955}
956
957void UIMachine::acquireFeaturesStatusInfo(QString &strInfo, KVMExecutionEngine &enmEngine)
958{
959 enmEngine = vmExecutionEngine();
960 uisession()->acquireFeaturesStatusInfo(strInfo, enmEngine,
961 isHWVirtExNestedPagingEnabled(),
962 isHWVirtExUXEnabled(),
963 paravirtProvider());
964}
965
966void UIMachine::generateMachineInformationGeneral(const UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral &fOptions,
967 UITextTable &returnTable)
968{
969 uisession()->generateMachineInformationGeneral(fOptions, returnTable);
970}
971
972void UIMachine::generateMachineInformationSystem(const UIExtraDataMetaDefs::DetailsElementOptionTypeSystem &fOptions,
973 UITextTable &returnTable)
974{
975 uisession()->generateMachineInformationSystem(fOptions, returnTable);
976}
977
978void UIMachine::generateMachineInformationDisplay(const UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay &fOptions,
979 UITextTable &returnTable)
980{
981 uisession()->generateMachineInformationDisplay(fOptions, returnTable);
982}
983
984void UIMachine::generateMachineInformationStorage(const UIExtraDataMetaDefs::DetailsElementOptionTypeStorage &fOptions,
985 UITextTable &returnTable)
986{
987 uisession()->generateMachineInformationStorage(fOptions, returnTable);
988}
989
990void UIMachine::generateMachineInformationAudio(const UIExtraDataMetaDefs::DetailsElementOptionTypeAudio &fOptions,
991 UITextTable &returnTable)
992{
993 uisession()->generateMachineInformationAudio(fOptions, returnTable);
994}
995
996void UIMachine::generateMachineInformationNetwork(const UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork &fOptions,
997 UITextTable &returnTable)
998{
999 uisession()->generateMachineInformationNetwork(fOptions, returnTable);
1000}
1001
1002void UIMachine::generateMachineInformationSerial(const UIExtraDataMetaDefs::DetailsElementOptionTypeSerial &fOptions,
1003 UITextTable &returnTable)
1004{
1005 uisession()->generateMachineInformationSerial(fOptions, returnTable);
1006}
1007
1008void UIMachine::generateMachineInformationUSB(const UIExtraDataMetaDefs::DetailsElementOptionTypeUsb &fOptions,
1009 UITextTable &returnTable)
1010{
1011 uisession()->generateMachineInformationUSB(fOptions, returnTable);
1012}
1013
1014void UIMachine::generateMachineInformationSharedFolders(const UIExtraDataMetaDefs::DetailsElementOptionTypeSharedFolders &fOptions,
1015 UITextTable &returnTable)
1016{
1017 uisession()->generateMachineInformationSharedFolders(fOptions, returnTable);
1018}
1019
1020bool UIMachine::setLogEnabled(bool fEnabled)
1021{
1022 return uisession()->setLogEnabled(fEnabled);
1023}
1024
1025bool UIMachine::acquireWhetherLogEnabled(bool &fEnabled)
1026{
1027 return uisession()->acquireWhetherLogEnabled(fEnabled);
1028}
1029
1030bool UIMachine::acquireLogFolder(QString &strFolder)
1031{
1032 return uisession()->acquireLogFolder(strFolder);
1033}
1034
1035bool UIMachine::acquireEffectiveCPULoad(ulong &uLoad)
1036{
1037 return uisession()->acquireEffectiveCPULoad(uLoad);
1038}
1039
1040bool UIMachine::acquireUptime(LONG64 &iUpTime)
1041{
1042 return uisession()->acquireUptime(iUpTime);
1043}
1044
1045#ifdef VBOX_WITH_DEBUGGER_GUI
1046bool UIMachine::dbgCreated(void *pActionDebug)
1047{
1048 return uisession()->dbgCreated(pActionDebug);
1049}
1050
1051void UIMachine::dbgDestroy()
1052{
1053 return uisession()->dbgDestroy();
1054}
1055
1056void UIMachine::dbgShowStatistics()
1057{
1058 return uisession()->dbgShowStatistics();
1059}
1060
1061void UIMachine::dbgShowCommandLine()
1062{
1063 return uisession()->dbgShowCommandLine();
1064}
1065
1066void UIMachine::dbgAdjustRelativePos()
1067{
1068 return uisession()->dbgAdjustRelativePos();
1069}
1070#endif /* VBOX_WITH_DEBUGGER_GUI */
1071
1072bool UIMachine::acquireWhetherGuestEnteredACPIMode(bool &fEntered)
1073{
1074 return uisession()->acquireWhetherGuestEnteredACPIMode(fEntered);
1075}
1076
1077void UIMachine::detachUi()
1078{
1079 /* Manually close Runtime UI: */
1080 LogRel(("GUI: Detaching UI..\n"));
1081 closeRuntimeUI();
1082}
1083
1084void UIMachine::saveState()
1085{
1086 uisession()->saveState();
1087}
1088
1089void UIMachine::shutdown()
1090{
1091 uisession()->shutdown();
1092}
1093
1094void UIMachine::powerOff(bool fIncludingDiscard)
1095{
1096 uisession()->powerOff(fIncludingDiscard);
1097}
1098
1099void UIMachine::sltInstallGuestAdditionsFrom(const QString &strSource)
1100{
1101 uisession()->sltInstallGuestAdditionsFrom(strSource);
1102}
1103
1104void UIMachine::sltMountDVDAdHoc(const QString &strSource)
1105{
1106 uisession()->sltMountDVDAdHoc(strSource);
1107}
1108
1109void UIMachine::closeRuntimeUI()
1110{
1111 /* First, we have to hide any opened modal/popup widgets.
1112 * They then should unlock their event-loops asynchronously.
1113 * If all such loops are unlocked, we can close Runtime UI. */
1114 QWidget *pWidget = QApplication::activeModalWidget()
1115 ? QApplication::activeModalWidget()
1116 : QApplication::activePopupWidget()
1117 ? QApplication::activePopupWidget()
1118 : 0;
1119 if (pWidget)
1120 {
1121 /* First we should try to close this widget: */
1122 pWidget->close();
1123 /* If widget rejected the 'close-event' we can
1124 * still hide it and hope it will behave correctly
1125 * and unlock his event-loop if any: */
1126 if (!pWidget->isHidden())
1127 pWidget->hide();
1128 /* Asynchronously restart this slot: */
1129 QMetaObject::invokeMethod(this, "closeRuntimeUI", Qt::QueuedConnection);
1130 return;
1131 }
1132
1133 /* Asynchronously ask QApplication to quit: */
1134 LogRel(("GUI: Request for async QApp quit.\n"));
1135 m_fQuitRequested = true;
1136 QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
1137}
1138
1139void UIMachine::sltChangeVisualState(UIVisualStateType visualState)
1140{
1141 /* Create new machine-logic: */
1142 UIMachineLogic *pMachineLogic = UIMachineLogic::create(this, visualState);
1143
1144 /* First we have to check if the selected machine-logic is available at all.
1145 * Only then we delete the old machine-logic and switch to the new one. */
1146 if (pMachineLogic->checkAvailability())
1147 {
1148 /* Delete previous machine-logic if any: */
1149 UIMachineLogic::destroy(m_pMachineLogic);
1150
1151 /* Set the new machine-logic as current one: */
1152 m_pMachineLogic = pMachineLogic;
1153 m_pMachineLogic->prepare();
1154
1155 /* Remember new visual state: */
1156 m_enmVisualState = visualState;
1157
1158 /* Save requested visual state: */
1159 gEDataManager->setRequestedVisualState(m_enmVisualState, uiCommon().managedVMUuid());
1160 }
1161 else
1162 {
1163 /* Delete temporary created machine-logic: */
1164 UIMachineLogic::destroy(pMachineLogic);
1165 }
1166
1167 /* Make sure machine-logic exists: */
1168 if (!m_pMachineLogic)
1169 {
1170 /* Reset initial visual state to normal: */
1171 m_enmInitialVisualState = UIVisualStateType_Normal;
1172 /* Enter initial visual state again: */
1173 enterInitialVisualState();
1174 }
1175}
1176
1177void UIMachine::sltHandleAdditionsActualChange()
1178{
1179 updateStateAdditionsActions();
1180 emit sigAdditionsStateActualChange();
1181}
1182
1183void UIMachine::sltHandleAudioAdapterChange()
1184{
1185 updateStateAudioActions();
1186 emit sigAudioAdapterChange();
1187}
1188
1189void UIMachine::sltHandleRecordingChange()
1190{
1191 updateStateRecordingAction();
1192 emit sigRecordingChange();
1193}
1194
1195void UIMachine::sltHandleStorageDeviceChange(const CMediumAttachment &comAttachment, bool fRemoved, bool fSilent)
1196{
1197 updateActionRestrictions();
1198 emit sigStorageDeviceChange(comAttachment, fRemoved, fSilent);
1199}
1200
1201void UIMachine::sltHandleVRDEChange()
1202{
1203 updateStateVRDEServerAction();
1204 emit sigVRDEChange();
1205}
1206
1207#ifdef VBOX_WS_MAC
1208void UIMachine::sltHandleMenuBarConfigurationChange(const QUuid &uMachineID)
1209{
1210 /* Skip unrelated machine IDs: */
1211 if (uiCommon().managedVMUuid() != uMachineID)
1212 return;
1213
1214 /* Update Mac OS X menu-bar: */
1215 updateMenu();
1216}
1217#endif /* VBOX_WS_MAC */
1218
1219void UIMachine::sltHandleHostScreenCountChange()
1220{
1221 LogRelFlow(("GUI: UIMachine: Host-screen count changed.\n"));
1222
1223 /* Recache display data: */
1224 updateHostScreenData();
1225
1226 /* Notify current machine-logic: */
1227 emit sigHostScreenCountChange();
1228}
1229
1230void UIMachine::sltHandleHostScreenGeometryChange()
1231{
1232 LogRelFlow(("GUI: UIMachine: Host-screen geometry changed.\n"));
1233
1234 /* Recache display data: */
1235 updateHostScreenData();
1236
1237 /* Notify current machine-logic: */
1238 emit sigHostScreenGeometryChange();
1239}
1240
1241void UIMachine::sltHandleHostScreenAvailableAreaChange()
1242{
1243 LogRelFlow(("GUI: UIMachine: Host-screen available-area changed.\n"));
1244
1245 /* Notify current machine-logic: */
1246 emit sigHostScreenAvailableAreaChange();
1247}
1248
1249#ifdef VBOX_WS_MAC
1250void UIMachine::sltHandleHostDisplayAboutToChange()
1251{
1252 LogRelFlow(("GUI: UIMachine::sltHandleHostDisplayAboutToChange()\n"));
1253
1254 if (m_pWatchdogDisplayChange->isActive())
1255 m_pWatchdogDisplayChange->stop();
1256 m_pWatchdogDisplayChange->setProperty("tryNumber", 1);
1257 m_pWatchdogDisplayChange->start();
1258}
1259
1260void UIMachine::sltCheckIfHostDisplayChanged()
1261{
1262 LogRelFlow(("GUI: UIMachine::sltCheckIfHostDisplayChanged()\n"));
1263
1264 /* Check if display count changed: */
1265 if (UIDesktopWidgetWatchdog::screenCount() != m_hostScreens.size())
1266 {
1267 /* Reset watchdog: */
1268 m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
1269 /* Notify listeners about screen-count changed: */
1270 return sltHandleHostScreenCountChange();
1271 }
1272 else
1273 {
1274 /* Check if at least one display geometry changed: */
1275 for (int iScreenIndex = 0; iScreenIndex < UIDesktopWidgetWatchdog::screenCount(); ++iScreenIndex)
1276 {
1277 if (gpDesktop->screenGeometry(iScreenIndex) != m_hostScreens.at(iScreenIndex))
1278 {
1279 /* Reset watchdog: */
1280 m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
1281 /* Notify listeners about screen-geometry changed: */
1282 return sltHandleHostScreenGeometryChange();
1283 }
1284 }
1285 }
1286
1287 /* Check if watchdog expired, restart if not: */
1288 int cTryNumber = m_pWatchdogDisplayChange->property("tryNumber").toInt();
1289 if (cTryNumber > 0 && cTryNumber < 40)
1290 {
1291 /* Restart watchdog again: */
1292 m_pWatchdogDisplayChange->setProperty("tryNumber", ++cTryNumber);
1293 m_pWatchdogDisplayChange->start();
1294 }
1295 else
1296 {
1297 /* Reset watchdog: */
1298 m_pWatchdogDisplayChange->setProperty("tryNumber", 0);
1299 }
1300}
1301#endif /* VBOX_WS_MAC */
1302
1303void UIMachine::sltHandleGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo)
1304{
1305 /* Ignore KGuestMonitorChangedEventType_NewOrigin change event: */
1306 if (changeType == KGuestMonitorChangedEventType_NewOrigin)
1307 return;
1308 /* Ignore KGuestMonitorChangedEventType_Disabled event for primary screen: */
1309 AssertMsg(countOfVisibleWindows() > 0, ("All machine windows are hidden!"));
1310 if (changeType == KGuestMonitorChangedEventType_Disabled && uScreenId == 0)
1311 return;
1312
1313 /* Process KGuestMonitorChangedEventType_Enabled change event: */
1314 if ( !isScreenVisible(uScreenId)
1315 && changeType == KGuestMonitorChangedEventType_Enabled)
1316 setScreenVisible(uScreenId, true);
1317 /* Process KGuestMonitorChangedEventType_Disabled change event: */
1318 else if ( isScreenVisible(uScreenId)
1319 && changeType == KGuestMonitorChangedEventType_Disabled)
1320 setScreenVisible(uScreenId, false);
1321
1322 /* Notify listeners about the change: */
1323 emit sigGuestMonitorChange(changeType, uScreenId, screenGeo);
1324}
1325
1326void UIMachine::sltHandleKeyboardLedsChange(bool fNumLock, bool fCapsLock, bool fScrollLock)
1327{
1328 /* Check if something had changed: */
1329 if ( m_fNumLock != fNumLock
1330 || m_fCapsLock != fCapsLock
1331 || m_fScrollLock != fScrollLock)
1332 {
1333 /* Store new num lock data: */
1334 if (m_fNumLock != fNumLock)
1335 {
1336 m_fNumLock = fNumLock;
1337 m_uNumLockAdaptionCnt = 2;
1338 }
1339
1340 /* Store new caps lock data: */
1341 if (m_fCapsLock != fCapsLock)
1342 {
1343 m_fCapsLock = fCapsLock;
1344 m_uCapsLockAdaptionCnt = 2;
1345 }
1346
1347 /* Store new scroll lock data: */
1348 if (m_fScrollLock != fScrollLock)
1349 {
1350 m_fScrollLock = fScrollLock;
1351 }
1352
1353 /* Notify listeners: */
1354 emit sigKeyboardLedsChange();
1355 }
1356}
1357
1358void UIMachine::sltMousePointerShapeChange(const UIMousePointerShapeData &shapeData)
1359{
1360 LogRelFlow(("GUI: UIMachine::sltMousePointerShapeChange: "
1361 "Is visible: %s, Has alpha: %s, "
1362 "Hot spot: %dx%d, Shape size: %dx%d, "
1363 "Shape data: %s\n",
1364 shapeData.isVisible() ? "TRUE" : "FALSE",
1365 shapeData.hasAlpha() ? "TRUE" : "FALSE",
1366 shapeData.hotSpot().x(), shapeData.hotSpot().y(),
1367 shapeData.shapeSize().width(), shapeData.shapeSize().height(),
1368 shapeData.shape().isEmpty() ? "EMPTY" : "PRESENT"));
1369
1370 /* In case if shape itself is present: */
1371 if (shapeData.shape().size() > 0)
1372 {
1373 /* We are ignoring visibility flag: */
1374 m_fIsHidingHostPointer = false;
1375
1376 /* And updating current shape data: */
1377 m_shapeData = shapeData;
1378 updateMousePointerShape();
1379 }
1380 /* In case if shape itself is NOT present: */
1381 else
1382 {
1383 /* Remember if we should hide the cursor: */
1384 m_fIsHidingHostPointer = !shapeData.isVisible();
1385 }
1386
1387 /* Notify listeners: */
1388 emit sigMousePointerShapeChange();
1389}
1390
1391void UIMachine::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative,
1392 bool fSupportsTouchScreen, bool fSupportsTouchPad,
1393 bool fNeedsHostCursor)
1394{
1395 LogRelFlow(("GUI: UIMachine::sltMouseCapabilityChange: "
1396 "Supports absolute: %s, Supports relative: %s, "
1397 "Supports touchscreen: %s, Supports touchpad: %s, "
1398 "Needs host cursor: %s\n",
1399 fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
1400 fSupportsTouchScreen ? "TRUE" : "FALSE", fSupportsTouchPad ? "TRUE" : "FALSE",
1401 fNeedsHostCursor ? "TRUE" : "FALSE"));
1402
1403 /* Check if something had changed: */
1404 if ( m_fIsMouseSupportsAbsolute != fSupportsAbsolute
1405 || m_fIsMouseSupportsRelative != fSupportsRelative
1406 || m_fIsMouseSupportsTouchScreen != fSupportsTouchScreen
1407 || m_fIsMouseSupportsTouchPad != fSupportsTouchPad
1408 || m_fIsMouseHostCursorNeeded != fNeedsHostCursor)
1409 {
1410 /* Store new data: */
1411 m_fIsMouseSupportsAbsolute = fSupportsAbsolute;
1412 m_fIsMouseSupportsRelative = fSupportsRelative;
1413 m_fIsMouseSupportsTouchScreen = fSupportsTouchScreen;
1414 m_fIsMouseSupportsTouchPad = fSupportsTouchPad;
1415 m_fIsMouseHostCursorNeeded = fNeedsHostCursor;
1416
1417 /* Notify listeners: */
1418 emit sigMouseCapabilityChange();
1419 }
1420}
1421
1422void UIMachine::sltCursorPositionChange(bool fContainsData, unsigned long uX, unsigned long uY)
1423{
1424 LogRelFlow(("GUI: UIMachine::sltCursorPositionChange: "
1425 "Cursor position valid: %d, Cursor position: %dx%d\n",
1426 fContainsData ? "TRUE" : "FALSE", uX, uY));
1427
1428 /* Check if something had changed: */
1429 if ( m_fIsValidCursorPositionPresent != fContainsData
1430 || m_cursorPosition.x() != (int)uX
1431 || m_cursorPosition.y() != (int)uY)
1432 {
1433 /* Store new data: */
1434 m_fIsValidCursorPositionPresent = fContainsData;
1435 m_cursorPosition = QPoint(uX, uY);
1436
1437 /* Notify listeners: */
1438 emit sigCursorPositionChange();
1439 }
1440}
1441
1442UIMachine::UIMachine()
1443 : QObject(0)
1444 , m_fInitialized(false)
1445 , m_pSession(0)
1446 , m_enmAllowedVisualStates(UIVisualStateType_Invalid)
1447 , m_enmInitialVisualState(UIVisualStateType_Normal)
1448 , m_enmVisualState(UIVisualStateType_Invalid)
1449 , m_enmRequestedVisualState(UIVisualStateType_Invalid)
1450 , m_pMachineLogic(0)
1451 , m_pMachineWindowIcon(0)
1452 , m_pActionPool(0)
1453#ifdef VBOX_WS_MAC
1454 , m_pMenuBar(0)
1455#endif
1456#ifdef VBOX_WS_MAC
1457 , m_pWatchdogDisplayChange(0)
1458#endif
1459 , m_fIsGuestResizeIgnored(false)
1460 , m_fNumLock(false)
1461 , m_fCapsLock(false)
1462 , m_fScrollLock(false)
1463 , m_uNumLockAdaptionCnt(2)
1464 , m_uCapsLockAdaptionCnt(2)
1465 , m_fIsHidLedsSyncEnabled(false)
1466 , m_fIsAutoCaptureDisabled(false)
1467 , m_iKeyboardState(0)
1468 , m_fIsHidingHostPointer(true)
1469 , m_fIsValidPointerShapePresent(false)
1470 , m_fIsValidCursorPositionPresent(false)
1471 , m_fIsMouseSupportsAbsolute(false)
1472 , m_fIsMouseSupportsRelative(false)
1473 , m_fIsMouseSupportsTouchScreen(false)
1474 , m_fIsMouseSupportsTouchPad(false)
1475 , m_fIsMouseHostCursorNeeded(false)
1476 , m_fIsMouseCaptured(false)
1477 , m_fIsMouseIntegrated(true)
1478 , m_iMouseState(0)
1479 , m_enmVMExecutionEngine(KVMExecutionEngine_NotSet)
1480 , m_fIsHWVirtExNestedPagingEnabled(false)
1481 , m_fIsHWVirtExUXEnabled(false)
1482 , m_enmParavirtProvider(KParavirtProvider_None)
1483 , m_fIsManualOverride(false)
1484 , m_defaultCloseAction(MachineCloseAction_Invalid)
1485 , m_restrictedCloseActions(MachineCloseAction_Invalid)
1486 , m_fQuitRequested(false)
1487{
1488 s_pInstance = this;
1489}
1490
1491UIMachine::~UIMachine()
1492{
1493 s_pInstance = 0;
1494}
1495
1496bool UIMachine::prepare()
1497{
1498 /* Prepare stuff unrelated to VM: */
1499 prepareNotificationCenter();
1500
1501 /* Prepare VM session: */
1502 if (!prepareSession())
1503 return false;
1504
1505 /* Prepare VM related stuff: */
1506 prepareActions();
1507 prepareHostScreenData();
1508 prepareKeyboard();
1509 prepareClose();
1510 prepareVisualState();
1511
1512 /* Update VM related stuff: */
1513 updateBranding();
1514 updateGuestScreenData();
1515 enterInitialVisualState();
1516
1517 /* Try to initialize VM session: */
1518 if (!uisession()->initialize())
1519 return false;
1520
1521 /* Update stuff which doesn't send events on init: */
1522 updateVirtualizationState();
1523 updateStateAudioActions();
1524 updateMouseState();
1525
1526 /* Warn listeners about we are initialized: */
1527 m_fInitialized = true;
1528 emit sigInitialized();
1529
1530 /* True by default: */
1531 return true;
1532}
1533
1534void UIMachine::prepareNotificationCenter()
1535{
1536 UINotificationCenter::create();
1537}
1538
1539bool UIMachine::prepareSession()
1540{
1541 /* Create session UI: */
1542 m_pSession = new UISession(this);
1543 AssertPtrReturn(uisession(), false);
1544
1545 /* Console events stuff: */
1546 connect(uisession(), &UISession::sigAudioAdapterChange,
1547 this, &UIMachine::sltHandleAudioAdapterChange);
1548 connect(uisession(), &UISession::sigAdditionsStateChange,
1549 this, &UIMachine::sigAdditionsStateChange);
1550 connect(uisession(), &UISession::sigAdditionsStateActualChange,
1551 this, &UIMachine::sltHandleAdditionsActualChange);
1552 connect(uisession(), &UISession::sigClipboardModeChange,
1553 this, &UIMachine::sigClipboardModeChange);
1554 connect(uisession(), &UISession::sigCPUExecutionCapChange,
1555 this, &UIMachine::sigCPUExecutionCapChange);
1556 connect(uisession(), &UISession::sigDnDModeChange,
1557 this, &UIMachine::sigDnDModeChange);
1558 connect(uisession(), &UISession::sigGuestMonitorChange,
1559 this, &UIMachine::sltHandleGuestMonitorChange);
1560 connect(uisession(), &UISession::sigMachineStateChange,
1561 this, &UIMachine::sigMachineStateChange);
1562 connect(uisession(), &UISession::sigMediumChange,
1563 this, &UIMachine::sigMediumChange);
1564 connect(uisession(), &UISession::sigNetworkAdapterChange,
1565 this, &UIMachine::sigNetworkAdapterChange);
1566 connect(uisession(), &UISession::sigRecordingChange,
1567 this, &UIMachine::sltHandleRecordingChange);
1568 connect(uisession(), &UISession::sigSharedFolderChange,
1569 this, &UIMachine::sigSharedFolderChange);
1570 connect(uisession(), &UISession::sigStorageDeviceChange,
1571 this, &UIMachine::sltHandleStorageDeviceChange);
1572 connect(uisession(), &UISession::sigUSBControllerChange,
1573 this, &UIMachine::sigUSBControllerChange);
1574 connect(uisession(), &UISession::sigUSBDeviceStateChange,
1575 this, &UIMachine::sigUSBDeviceStateChange);
1576 connect(uisession(), &UISession::sigVRDEChange,
1577 this, &UIMachine::sltHandleVRDEChange);
1578 connect(uisession(), &UISession::sigRuntimeError,
1579 this, &UIMachine::sigRuntimeError);
1580#ifdef VBOX_WS_MAC
1581 connect(uisession(), &UISession::sigShowWindows,
1582 this, &UIMachine::sigShowWindows);
1583#endif
1584
1585 /* Keyboard stuff: */
1586 connect(uisession(), &UISession::sigKeyboardLedsChange,
1587 this, &UIMachine::sltHandleKeyboardLedsChange);
1588
1589 /* Mouse stuff: */
1590 connect(uisession(), &UISession::sigMousePointerShapeChange,
1591 this, &UIMachine::sltMousePointerShapeChange);
1592 connect(uisession(), &UISession::sigMouseCapabilityChange,
1593 this, &UIMachine::sltMouseCapabilityChange);
1594 connect(uisession(), &UISession::sigCursorPositionChange,
1595 this, &UIMachine::sltCursorPositionChange);
1596
1597 /* Make sure session prepared: */
1598 return uisession()->prepare();
1599}
1600
1601void UIMachine::prepareActions()
1602{
1603 /* Create action-pool: */
1604 m_pActionPool = UIActionPool::create(UIType_RuntimeUI);
1605 if (actionPool())
1606 {
1607 /* Make sure action-pool knows guest-screen count: */
1608 actionPool()->toRuntime()->setGuestScreenCount(uisession()->frameBuffers().size());
1609 /* Update action restrictions: */
1610 updateActionRestrictions();
1611
1612#ifdef VBOX_WS_MAC
1613 /* Create Mac OS X menu-bar: */
1614 m_pMenuBar = new QMenuBar;
1615 if (m_pMenuBar)
1616 {
1617 /* Configure Mac OS X menu-bar: */
1618 connect(gEDataManager, &UIExtraDataManager::sigMenuBarConfigurationChange,
1619 this, &UIMachine::sltHandleMenuBarConfigurationChange);
1620 /* Update Mac OS X menu-bar: */
1621 updateMenu();
1622 }
1623#endif /* VBOX_WS_MAC */
1624
1625 /* Get machine ID: */
1626 const QUuid uMachineID = uiCommon().managedVMUuid();
1627 Q_UNUSED(uMachineID);
1628
1629#ifdef VBOX_WS_MAC
1630 /* User-element (Menu-bar and Dock) options: */
1631 {
1632 const bool fDisabled = gEDataManager->guiFeatureEnabled(GUIFeatureType_NoUserElements);
1633 if (fDisabled)
1634 UICocoaApplication::instance()->hideUserElements();
1635 }
1636#else /* !VBOX_WS_MAC */
1637 /* Menu-bar options: */
1638 {
1639 const bool fEnabledGlobally = !gEDataManager->guiFeatureEnabled(GUIFeatureType_NoMenuBar);
1640 const bool fEnabledForMachine = gEDataManager->menuBarEnabled(uMachineID);
1641 const bool fEnabled = fEnabledGlobally && fEnabledForMachine;
1642 actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_S_Settings)->setEnabled(fEnabled);
1643 actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_T_Visibility)->blockSignals(true);
1644 actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_T_Visibility)->setChecked(fEnabled);
1645 actionPool()->action(UIActionIndexRT_M_View_M_MenuBar_T_Visibility)->blockSignals(false);
1646 }
1647#endif /* !VBOX_WS_MAC */
1648
1649 /* View options: */
1650 const bool fGuestScreenAutoresize = gEDataManager->guestScreenAutoResizeEnabled(uMachineID);
1651 actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize)->blockSignals(true);
1652 actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize)->setChecked(fGuestScreenAutoresize);
1653 actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize)->blockSignals(false);
1654
1655 /* Input options: */
1656 const bool fMouseIntegrated = isMouseIntegrated(); // no e-data for now ..
1657 actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration)->blockSignals(true);
1658 actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration)->setChecked(fMouseIntegrated);
1659 actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration)->blockSignals(false);
1660
1661 /* Device options: */
1662 actionPool()->action(UIActionIndexRT_M_Devices_S_UpgradeGuestAdditions)->setEnabled(false);
1663
1664 /* Status-bar options: */
1665 {
1666 const bool fEnabledGlobally = !gEDataManager->guiFeatureEnabled(GUIFeatureType_NoStatusBar);
1667 const bool fEnabledForMachine = gEDataManager->statusBarEnabled(uMachineID);
1668 const bool fEnabled = fEnabledGlobally && fEnabledForMachine;
1669 actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_S_Settings)->setEnabled(fEnabled);
1670 actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_T_Visibility)->blockSignals(true);
1671 actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_T_Visibility)->setChecked(fEnabled);
1672 actionPool()->action(UIActionIndexRT_M_View_M_StatusBar_T_Visibility)->blockSignals(false);
1673 }
1674 }
1675}
1676
1677void UIMachine::prepareHostScreenData()
1678{
1679 /* Recache display data: */
1680 updateHostScreenData();
1681
1682#ifdef VBOX_WS_MAC
1683 /* Prepare display-change watchdog: */
1684 m_pWatchdogDisplayChange = new QTimer(this);
1685 {
1686 m_pWatchdogDisplayChange->setInterval(500);
1687 m_pWatchdogDisplayChange->setSingleShot(true);
1688 connect(m_pWatchdogDisplayChange, &QTimer::timeout,
1689 this, &UIMachine::sltCheckIfHostDisplayChanged);
1690 }
1691 /* Install native display reconfiguration callback: */
1692 CGDisplayRegisterReconfigurationCallback(cgDisplayReconfigurationCallback, this);
1693#else /* !VBOX_WS_MAC */
1694 /* Install Qt display reconfiguration callbacks: */
1695 connect(gpDesktop, &UIDesktopWidgetWatchdog::sigHostScreenCountChanged,
1696 this, &UIMachine::sltHandleHostScreenCountChange);
1697 connect(gpDesktop, &UIDesktopWidgetWatchdog::sigHostScreenResized,
1698 this, &UIMachine::sltHandleHostScreenGeometryChange);
1699# if defined(VBOX_WS_NIX) && !defined(VBOX_GUI_WITH_CUSTOMIZATIONS1)
1700 connect(gpDesktop, &UIDesktopWidgetWatchdog::sigHostScreenWorkAreaRecalculated,
1701 this, &UIMachine::sltHandleHostScreenAvailableAreaChange);
1702# else /* !VBOX_WS_NIX || VBOX_GUI_WITH_CUSTOMIZATIONS1 */
1703 connect(gpDesktop, &UIDesktopWidgetWatchdog::sigHostScreenWorkAreaResized,
1704 this, &UIMachine::sltHandleHostScreenAvailableAreaChange);
1705# endif /* !VBOX_WS_NIX || VBOX_GUI_WITH_CUSTOMIZATIONS1 */
1706#endif /* !VBOX_WS_MAC */
1707}
1708
1709void UIMachine::prepareKeyboard()
1710{
1711#if defined(VBOX_WS_MAC) || defined(VBOX_WS_WIN)
1712 /* Load extra-data value: */
1713 m_fIsHidLedsSyncEnabled = gEDataManager->hidLedsSyncState(uiCommon().managedVMUuid());
1714 /* Connect to extra-data changes to be able to enable/disable feature dynamically: */
1715 connect(gEDataManager, &UIExtraDataManager::sigHidLedsSyncStateChange,
1716 this, &UIMachine::sltHidLedsSyncStateChanged);
1717#endif /* VBOX_WS_MAC || VBOX_WS_WIN */
1718}
1719
1720void UIMachine::prepareClose()
1721{
1722 /* What is the default close action and the restricted are? */
1723 const QUuid uMachineID = uiCommon().managedVMUuid();
1724 m_defaultCloseAction = gEDataManager->defaultMachineCloseAction(uMachineID);
1725 m_restrictedCloseActions = gEDataManager->restrictedMachineCloseActions(uMachineID);
1726}
1727
1728void UIMachine::prepareVisualState()
1729{
1730 /* Prepare async visual state type change handler: */
1731 qRegisterMetaType<UIVisualStateType>();
1732 connect(this, &UIMachine::sigRequestAsyncVisualStateChange,
1733 this, &UIMachine::sltChangeVisualState,
1734 Qt::QueuedConnection);
1735
1736 /* Load restricted visual states: */
1737 UIVisualStateType enmRestrictedVisualStates = gEDataManager->restrictedVisualStates(uiCommon().managedVMUuid());
1738 /* Acquire allowed visual states: */
1739 m_enmAllowedVisualStates = static_cast<UIVisualStateType>(UIVisualStateType_All ^ enmRestrictedVisualStates);
1740
1741 /* Load requested visual state, it can override initial one: */
1742 m_enmRequestedVisualState = gEDataManager->requestedVisualState(uiCommon().managedVMUuid());
1743 /* Check if requested visual state is allowed: */
1744 if (isVisualStateAllowed(m_enmRequestedVisualState))
1745 {
1746 switch (m_enmRequestedVisualState)
1747 {
1748 /* Direct transition allowed to scale/fullscreen modes only: */
1749 case UIVisualStateType_Scale:
1750 case UIVisualStateType_Fullscreen:
1751 m_enmInitialVisualState = m_enmRequestedVisualState;
1752 break;
1753 default:
1754 break;
1755 }
1756 }
1757}
1758
1759void UIMachine::updateBranding()
1760{
1761 /* Create the icon dynamically: */
1762 delete m_pMachineWindowIcon;
1763 m_pMachineWindowIcon = new QIcon;
1764 acquireUserMachineIcon(*m_pMachineWindowIcon);
1765
1766#ifndef VBOX_WS_MAC
1767 /* Load user's machine-window name postfix: */
1768 const QUuid uMachineID = uiCommon().managedVMUuid();
1769 m_strMachineWindowNamePostfix = gEDataManager->machineWindowNamePostfix(uMachineID);
1770#endif /* !VBOX_WS_MAC */
1771}
1772
1773void UIMachine::updateGuestScreenData()
1774{
1775 /* Accquire guest-screen count: */
1776 ulong cMonitorCount = 0;
1777 acquireMonitorCount(cMonitorCount);
1778
1779 /* Prepare initial screen visibility status: */
1780 m_guestScreenVisibilityVector.fill(false, cMonitorCount);
1781 m_guestScreenVisibilityVector[0] = true;
1782
1783 /* Prepare empty last full-screen size vector: */
1784 m_monitorLastFullScreenSizeVector.fill(QSize(-1, -1), cMonitorCount);
1785
1786 /* If machine is in 'saved' state: */
1787 if (uisession()->isSaved())
1788 {
1789 /* Update screen visibility status from saved-state: */
1790 for (int iScreenIndex = 0; iScreenIndex < m_guestScreenVisibilityVector.size(); ++iScreenIndex)
1791 {
1792 long iDummy = 0;
1793 ulong uDummy = 0;
1794 bool fEnabled = true;
1795 acquireSavedGuestScreenInfo(iScreenIndex, iDummy, iDummy, uDummy, uDummy, fEnabled);
1796 m_guestScreenVisibilityVector[iScreenIndex] = fEnabled;
1797 }
1798 /* And make sure at least one of them is visible (primary if others are hidden): */
1799 if (countOfVisibleWindows() < 1)
1800 m_guestScreenVisibilityVector[0] = true;
1801 }
1802 else if (uiCommon().isSeparateProcess())
1803 {
1804 /* Update screen visibility status from display directly: */
1805 for (int iScreenIndex = 0; iScreenIndex < m_guestScreenVisibilityVector.size(); ++iScreenIndex)
1806 {
1807 ulong uDummy = 0;
1808 long iDummy = 0;
1809 KGuestMonitorStatus enmMonitorStatus = KGuestMonitorStatus_Disabled;
1810 acquireGuestScreenParameters(iScreenIndex, uDummy, uDummy, uDummy, iDummy, iDummy, enmMonitorStatus);
1811 m_guestScreenVisibilityVector[iScreenIndex] = ( enmMonitorStatus == KGuestMonitorStatus_Enabled
1812 || enmMonitorStatus == KGuestMonitorStatus_Blank);
1813 }
1814 /* And make sure at least one of them is visible (primary if others are hidden): */
1815 if (countOfVisibleWindows() < 1)
1816 m_guestScreenVisibilityVector[0] = true;
1817 }
1818
1819 /* Prepare initial screen visibility status of host-desires (same as facts): */
1820 m_guestScreenVisibilityVectorHostDesires.resize(cMonitorCount);
1821 for (int iScreenIndex = 0; iScreenIndex < m_guestScreenVisibilityVector.size(); ++iScreenIndex)
1822 m_guestScreenVisibilityVectorHostDesires[iScreenIndex] = m_guestScreenVisibilityVector[iScreenIndex];
1823
1824 /* Make sure action-pool knows guest-screen visibility status: */
1825 for (int iScreenIndex = 0; iScreenIndex < m_guestScreenVisibilityVector.size(); ++iScreenIndex)
1826 actionPool()->toRuntime()->setGuestScreenVisible(iScreenIndex, m_guestScreenVisibilityVector.at(iScreenIndex));
1827}
1828
1829void UIMachine::enterInitialVisualState()
1830{
1831 sltChangeVisualState(m_enmInitialVisualState);
1832}
1833
1834void UIMachine::cleanupMachineLogic()
1835{
1836 /* Delete machine-logic if any: */
1837 UIMachineLogic::destroy(m_pMachineLogic);
1838}
1839
1840void UIMachine::cleanupBranding()
1841{
1842 /* Cleanup machine-window icon: */
1843 delete m_pMachineWindowIcon;
1844 m_pMachineWindowIcon = 0;
1845}
1846
1847void UIMachine::cleanupHostScreenData()
1848{
1849#ifdef VBOX_WS_MAC
1850 /* Remove display reconfiguration callback: */
1851 CGDisplayRemoveReconfigurationCallback(cgDisplayReconfigurationCallback, this);
1852#endif /* VBOX_WS_MAC */
1853}
1854
1855void UIMachine::cleanupActions()
1856{
1857#ifdef VBOX_WS_MAC
1858 /* Destroy Mac OS X menu-bar: */
1859 delete m_pMenuBar;
1860 m_pMenuBar = 0;
1861#endif /* VBOX_WS_MAC */
1862
1863 /* Destroy action-pool if necessary: */
1864 if (actionPool())
1865 UIActionPool::destroy(actionPool());
1866}
1867
1868void UIMachine::cleanupSession()
1869{
1870 /* Destroy session UI if exists: */
1871 delete m_pSession;
1872 m_pSession = 0;
1873}
1874
1875void UIMachine::cleanupNotificationCenter()
1876{
1877 UINotificationCenter::destroy();
1878}
1879
1880void UIMachine::cleanup()
1881{
1882 /* Preprocess all the meta-events: */
1883 QApplication::sendPostedEvents(0, QEvent::MetaCall);
1884
1885 /* Cleanup stuff: */
1886 cleanupMachineLogic();
1887 cleanupBranding();
1888 cleanupHostScreenData();
1889 cleanupActions();
1890 cleanupSession();
1891 cleanupNotificationCenter();
1892}
1893
1894void UIMachine::updateActionRestrictions()
1895{
1896 /* Get host and prepare restrictions: */
1897 UIExtraDataMetaDefs::RuntimeMenuMachineActionType restrictionForMachine =
1898 UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Invalid;
1899 UIExtraDataMetaDefs::RuntimeMenuViewActionType restrictionForView =
1900 UIExtraDataMetaDefs::RuntimeMenuViewActionType_Invalid;
1901 UIExtraDataMetaDefs::RuntimeMenuDevicesActionType restrictionForDevices =
1902 UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Invalid;
1903
1904 /* Separate process stuff: */
1905 {
1906 /* Initialize 'Machine' menu: */
1907 if (!uiCommon().isSeparateProcess())
1908 restrictionForMachine = (UIExtraDataMetaDefs::RuntimeMenuMachineActionType)
1909 (restrictionForMachine | UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Detach);
1910 }
1911
1912 /* VRDE server stuff: */
1913 {
1914 /* Initialize 'View' menu: */
1915 bool fServerPresent = false;
1916 acquireWhetherVRDEServerPresent(fServerPresent);
1917 if (!fServerPresent)
1918 restrictionForView = (UIExtraDataMetaDefs::RuntimeMenuViewActionType)
1919 (restrictionForView | UIExtraDataMetaDefs::RuntimeMenuViewActionType_VRDEServer);
1920 }
1921
1922 /* Storage stuff: */
1923 {
1924 /* Initialize CD/FD menus: */
1925 ulong cHardDisks = 0;
1926 ulong iOpticalDevices = 0;
1927 ulong cFloppyDevices = 0;
1928 acquireAmountOfStorageDevices(cHardDisks, iOpticalDevices, cFloppyDevices);
1929 QAction *pOpticalDevicesMenu = actionPool()->action(UIActionIndexRT_M_Devices_M_OpticalDevices);
1930 QAction *pFloppyDevicesMenu = actionPool()->action(UIActionIndexRT_M_Devices_M_FloppyDevices);
1931 pOpticalDevicesMenu->setData((int)iOpticalDevices);
1932 pFloppyDevicesMenu->setData((int)cFloppyDevices);
1933 if (!iOpticalDevices)
1934 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)
1935 (restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_OpticalDevices);
1936 if (!cFloppyDevices)
1937 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)
1938 (restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_FloppyDevices);
1939 }
1940
1941 /* Audio stuff: */
1942 {
1943 /* Do we need to restrict something? */
1944 bool fRestricted = false;
1945 /* Check whether audio adapter is present: */
1946 bool fAdapterPresent = false;
1947 acquireWhetherAudioAdapterPresent(fAdapterPresent);
1948 if (!fAdapterPresent)
1949 fRestricted = true;
1950 else
1951 {
1952 /* Check whether audio adapter is enabled: */
1953 bool fAdapterEnabled = false;
1954 acquireWhetherAudioAdapterEnabled(fAdapterEnabled);
1955 if (!fAdapterEnabled)
1956 fRestricted = true;
1957 }
1958 /* Apply restrictions: */
1959 if (fRestricted)
1960 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)
1961 (restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Audio);
1962 }
1963
1964 /* Network stuff: */
1965 {
1966 /* Initialize Network menu: */
1967 bool fAtLeastOneAdapterEnabled = false;
1968 acquireWhetherAtLeastOneNetworkAdapterEnabled(fAtLeastOneAdapterEnabled);
1969 if (!fAtLeastOneAdapterEnabled)
1970 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)
1971 (restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Network);
1972 }
1973
1974 /* USB stuff: */
1975 {
1976 /* Check whether there is at least one USB controller with an available proxy. */
1977 bool fUSBEnabled = false;
1978 acquireWhetherUSBControllerEnabled(fUSBEnabled);
1979 if (!fUSBEnabled)
1980 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)
1981 (restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_USBDevices);
1982 }
1983
1984 /* WebCams stuff: */
1985 {
1986 /* Check whether there is an accessible video input devices pool: */
1987 bool fWebCamsEnabled = false;
1988 acquireWhetherVideoInputDevicesEnabled(fWebCamsEnabled);
1989 if (!fWebCamsEnabled)
1990 restrictionForDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)
1991 (restrictionForDevices | UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_WebCams);
1992 }
1993
1994 /* Apply cumulative restriction for 'Machine' menu: */
1995 actionPool()->toRuntime()->setRestrictionForMenuMachine(UIActionRestrictionLevel_Session, restrictionForMachine);
1996 /* Apply cumulative restriction for 'View' menu: */
1997 actionPool()->toRuntime()->setRestrictionForMenuView(UIActionRestrictionLevel_Session, restrictionForView);
1998 /* Apply cumulative restriction for 'Devices' menu: */
1999 actionPool()->toRuntime()->setRestrictionForMenuDevices(UIActionRestrictionLevel_Session, restrictionForDevices);
2000}
2001
2002#ifdef VBOX_WS_MAC
2003void UIMachine::updateMenu()
2004{
2005 /* Rebuild Mac OS X menu-bar: */
2006 m_pMenuBar->clear();
2007 foreach (QMenu *pMenu, actionPool()->menus())
2008 {
2009 UIMenu *pMenuUI = qobject_cast<UIMenu*>(pMenu);
2010 if (!pMenuUI->isConsumable() || !pMenuUI->isConsumed())
2011 m_pMenuBar->addMenu(pMenuUI);
2012 if (pMenuUI->isConsumable() && !pMenuUI->isConsumed())
2013 pMenuUI->setConsumed(true);
2014 }
2015 /* Update the dock menu as well: */
2016 if (machineLogic())
2017 machineLogic()->updateDock();
2018}
2019#endif /* VBOX_WS_MAC */
2020
2021void UIMachine::updateHostScreenData()
2022{
2023 /* Rebuild host-screen data vector: */
2024 m_hostScreens.clear();
2025 for (int iScreenIndex = 0; iScreenIndex < UIDesktopWidgetWatchdog::screenCount(); ++iScreenIndex)
2026 m_hostScreens << gpDesktop->screenGeometry(iScreenIndex);
2027
2028 /* Make sure action-pool knows host-screen count: */
2029 actionPool()->toRuntime()->setHostScreenCount(m_hostScreens.size());
2030}
2031
2032void UIMachine::updateMousePointerShape()
2033{
2034 /* Fetch incoming shape data: */
2035 const bool fHasAlpha = m_shapeData.hasAlpha();
2036 const uint uWidth = m_shapeData.shapeSize().width();
2037 const uint uHeight = m_shapeData.shapeSize().height();
2038 const uchar *pShapeData = m_shapeData.shape().constData();
2039 AssertMsgReturnVoid(pShapeData, ("Shape data must not be NULL!\n"));
2040
2041 /* Invalidate mouse pointer shape initially: */
2042 m_fIsValidPointerShapePresent = false;
2043 m_cursorShapePixmap = QPixmap();
2044 m_cursorMaskPixmap = QPixmap();
2045
2046 /* Parse incoming shape data: */
2047 const uchar *pSrcAndMaskPtr = pShapeData;
2048 const uint uAndMaskSize = (uWidth + 7) / 8 * uHeight;
2049 const uchar *pSrcShapePtr = pShapeData + ((uAndMaskSize + 3) & ~3);
2050
2051#if defined (VBOX_WS_WIN)
2052
2053 /* Create an ARGB image out of the shape data: */
2054
2055 // WORKAROUND:
2056 // Qt5 QCursor recommends 32 x 32 cursor, therefore the original data is copied to
2057 // a larger QImage if necessary. Cursors like 10x16 did not work correctly (Solaris 10 guest).
2058 // Align the cursor dimensions to 32 bit pixels, because for example a 56x56 monochrome cursor
2059 // did not work correctly on Windows host.
2060 const uint uCursorWidth = RT_ALIGN_32(uWidth, 32);
2061 const uint uCursorHeight = RT_ALIGN_32(uHeight, 32);
2062
2063 if (fHasAlpha)
2064 {
2065 QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
2066 memset(image.bits(), 0, image.sizeInBytes());
2067
2068 const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
2069 for (uint y = 0; y < uHeight; ++y, pu32SrcShapeScanline += uWidth)
2070 memcpy(image.scanLine(y), pu32SrcShapeScanline, uWidth * sizeof(uint32_t));
2071
2072 m_cursorShapePixmap = QPixmap::fromImage(image);
2073 }
2074 else
2075 {
2076 if (isPointer1bpp(pSrcShapePtr, uWidth, uHeight))
2077 {
2078 // Incoming data consist of 32 bit BGR XOR mask and 1 bit AND mask.
2079 // XOR pixels contain either 0x00000000 or 0x00FFFFFF.
2080 //
2081 // Originally intended result (F denotes 0x00FFFFFF):
2082 // XOR AND
2083 // 0 0 black
2084 // F 0 white
2085 // 0 1 transparent
2086 // F 1 xor'd
2087 //
2088 // Actual Qt5 result for color table 0:0xFF000000, 1:0xFFFFFFFF
2089 // (tested on Windows 7 and 10 64 bit hosts):
2090 // Bitmap Mask
2091 // 0 0 black
2092 // 1 0 white
2093 // 0 1 xor
2094 // 1 1 transparent
2095
2096 QVector<QRgb> colors(2);
2097 colors[0] = UINT32_C(0xFF000000);
2098 colors[1] = UINT32_C(0xFFFFFFFF);
2099
2100 QImage bitmap(uCursorWidth, uCursorHeight, QImage::Format_Mono);
2101 bitmap.setColorTable(colors);
2102 memset(bitmap.bits(), 0xFF, bitmap.sizeInBytes());
2103
2104 QImage mask(uCursorWidth, uCursorHeight, QImage::Format_Mono);
2105 mask.setColorTable(colors);
2106 memset(mask.bits(), 0xFF, mask.sizeInBytes());
2107
2108 const uint8_t *pu8SrcAndScanline = pSrcAndMaskPtr;
2109 const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
2110 for (uint y = 0; y < uHeight; ++y)
2111 {
2112 for (uint x = 0; x < uWidth; ++x)
2113 {
2114 const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
2115
2116 const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
2117 const uint8_t u8SrcMaskBit = u8SrcMaskByte & u8Bit;
2118 const uint32_t u32SrcPixel = pu32SrcShapeScanline[x] & UINT32_C(0xFFFFFF);
2119
2120 uint8_t *pu8DstMaskByte = &mask.scanLine(y)[x / 8];
2121 uint8_t *pu8DstBitmapByte = &bitmap.scanLine(y)[x / 8];
2122
2123 if (u8SrcMaskBit == 0)
2124 {
2125 if (u32SrcPixel == 0)
2126 {
2127 /* Black: Qt Bitmap = 0, Mask = 0 */
2128 *pu8DstMaskByte &= ~u8Bit;
2129 *pu8DstBitmapByte &= ~u8Bit;
2130 }
2131 else
2132 {
2133 /* White: Qt Bitmap = 1, Mask = 0 */
2134 *pu8DstMaskByte &= ~u8Bit;
2135 *pu8DstBitmapByte |= u8Bit;
2136 }
2137 }
2138 else
2139 {
2140 if (u32SrcPixel == 0)
2141 {
2142 /* Transparent: Qt Bitmap = 1, Mask = 1 */
2143 *pu8DstMaskByte |= u8Bit;
2144 *pu8DstBitmapByte |= u8Bit;
2145 }
2146 else
2147 {
2148 /* Xor'ed: Qt Bitmap = 0, Mask = 1 */
2149 *pu8DstMaskByte |= u8Bit;
2150 *pu8DstBitmapByte &= ~u8Bit;
2151 }
2152 }
2153 }
2154
2155 pu8SrcAndScanline += (uWidth + 7) / 8;
2156 pu32SrcShapeScanline += uWidth;
2157 }
2158
2159 m_cursorShapePixmap = QBitmap::fromImage(bitmap);
2160 m_cursorMaskPixmap = QBitmap::fromImage(mask);
2161 }
2162 else
2163 {
2164 /* Assign alpha channel values according to the AND mask: 1 -> 0x00, 0 -> 0xFF: */
2165 QImage image(uCursorWidth, uCursorHeight, QImage::Format_ARGB32);
2166 memset(image.bits(), 0, image.sizeInBytes());
2167
2168 const uint8_t *pu8SrcAndScanline = pSrcAndMaskPtr;
2169 const uint32_t *pu32SrcShapeScanline = (uint32_t *)pSrcShapePtr;
2170
2171 for (uint y = 0; y < uHeight; ++y)
2172 {
2173 uint32_t *pu32DstPixel = (uint32_t *)image.scanLine(y);
2174
2175 for (uint x = 0; x < uWidth; ++x)
2176 {
2177 const uint8_t u8Bit = (uint8_t)(1 << (7 - x % 8));
2178 const uint8_t u8SrcMaskByte = pu8SrcAndScanline[x / 8];
2179
2180 if (u8SrcMaskByte & u8Bit)
2181 *pu32DstPixel++ = pu32SrcShapeScanline[x] & UINT32_C(0x00FFFFFF);
2182 else
2183 *pu32DstPixel++ = pu32SrcShapeScanline[x] | UINT32_C(0xFF000000);
2184 }
2185
2186 pu32SrcShapeScanline += uWidth;
2187 pu8SrcAndScanline += (uWidth + 7) / 8;
2188 }
2189
2190 m_cursorShapePixmap = QPixmap::fromImage(image);
2191 }
2192 }
2193
2194 /* Mark mouse pointer shape valid: */
2195 m_fIsValidPointerShapePresent = true;
2196
2197#elif defined(VBOX_WS_NIX) || defined(VBOX_WS_MAC)
2198
2199 /* Create an ARGB image out of the shape data: */
2200 QImage image(uWidth, uHeight, QImage::Format_ARGB32);
2201
2202 if (fHasAlpha)
2203 {
2204 memcpy(image.bits(), pSrcShapePtr, uHeight * uWidth * 4);
2205 }
2206 else
2207 {
2208 renderCursorPixels((uint32_t *)pSrcShapePtr, pSrcAndMaskPtr,
2209 uWidth, uHeight,
2210 (uint32_t *)image.bits(), uHeight * uWidth * 4);
2211 }
2212
2213 /* Create cursor-pixmap from the image: */
2214 m_cursorShapePixmap = QPixmap::fromImage(image);
2215
2216 /* Mark mouse pointer shape valid: */
2217 m_fIsValidPointerShapePresent = true;
2218
2219#else
2220
2221# warning "port me"
2222
2223#endif
2224
2225 /* Cache cursor pixmap size and hotspot: */
2226 m_cursorSize = m_cursorShapePixmap.size();
2227 m_cursorHotspot = m_shapeData.hotSpot();
2228}
2229
2230void UIMachine::updateMouseState()
2231{
2232 uisession()->acquireWhetherAbsoluteSupported(m_fIsMouseSupportsAbsolute);
2233 uisession()->acquireWhetherRelativeSupported(m_fIsMouseSupportsRelative);
2234 uisession()->acquireWhetherTouchScreenSupported(m_fIsMouseSupportsTouchScreen);
2235 uisession()->acquireWhetherTouchPadSupported(m_fIsMouseSupportsTouchPad);
2236 uisession()->acquireWhetherNeedsHostCursor(m_fIsMouseHostCursorNeeded);
2237}
2238
2239#if defined(VBOX_WS_NIX) || defined(VBOX_WS_MAC)
2240/* static */
2241void UIMachine::renderCursorPixels(const uint32_t *pu32XOR, const uint8_t *pu8AND,
2242 uint32_t u32Width, uint32_t u32Height,
2243 uint32_t *pu32Pixels, uint32_t cbPixels)
2244{
2245 /* Output pixels set to 0 which allow to not write transparent pixels anymore. */
2246 memset(pu32Pixels, 0, cbPixels);
2247
2248 const uint32_t *pu32XORSrc = pu32XOR; /* Iterator for source XOR pixels. */
2249 const uint8_t *pu8ANDSrcLine = pu8AND; /* The current AND mask scanline. */
2250 uint32_t *pu32Dst = pu32Pixels; /* Iterator for all destination BGRA pixels. */
2251
2252 /* Some useful constants. */
2253 const int cbANDLine = ((int)u32Width + 7) / 8;
2254
2255 int y;
2256 for (y = 0; y < (int)u32Height; ++y)
2257 {
2258 int x;
2259 for (x = 0; x < (int)u32Width; ++x)
2260 {
2261 const uint32_t u32Pixel = *pu32XORSrc; /* Current pixel at (x,y) */
2262 const uint8_t *pu8ANDSrc = pu8ANDSrcLine + x / 8; /* Byte which containt current AND bit. */
2263
2264 if ((*pu8ANDSrc << (x % 8)) & 0x80)
2265 {
2266 if (u32Pixel)
2267 {
2268 const uint32_t u32PixelInverted = ~u32Pixel;
2269
2270 /* Scan neighbor pixels and assign them if they are transparent. */
2271 int dy;
2272 for (dy = -1; dy <= 1; ++dy)
2273 {
2274 const int yn = y + dy;
2275 if (yn < 0 || yn >= (int)u32Height)
2276 continue; /* Do not cross the bounds. */
2277
2278 int dx;
2279 for (dx = -1; dx <= 1; ++dx)
2280 {
2281 const int xn = x + dx;
2282 if (xn < 0 || xn >= (int)u32Width)
2283 continue; /* Do not cross the bounds. */
2284
2285 if (dx != 0 || dy != 0)
2286 {
2287 /* Check if the neighbor pixel is transparent. */
2288 const uint32_t *pu32XORNeighborSrc = &pu32XORSrc[dy * (int)u32Width + dx];
2289 const uint8_t *pu8ANDNeighborSrc = pu8ANDSrcLine + dy * cbANDLine + xn / 8;
2290 if ( *pu32XORNeighborSrc == 0
2291 && ((*pu8ANDNeighborSrc << (xn % 8)) & 0x80) != 0)
2292 {
2293 /* Transparent neighbor pixels are replaced with the source pixel value. */
2294 uint32_t *pu32PixelNeighborDst = &pu32Dst[dy * (int)u32Width + dx];
2295 *pu32PixelNeighborDst = u32Pixel | 0xFF000000;
2296 }
2297 }
2298 else
2299 {
2300 /* The pixel itself is replaced with inverted value. */
2301 *pu32Dst = u32PixelInverted | 0xFF000000;
2302 }
2303 }
2304 }
2305 }
2306 else
2307 {
2308 /* The pixel does not affect the screen.
2309 * Do nothing. Do not touch destination which can already contain generated pixels.
2310 */
2311 }
2312 }
2313 else
2314 {
2315 /* AND bit is 0, the pixel will be just drawn. */
2316 *pu32Dst = u32Pixel | 0xFF000000;
2317 }
2318
2319 ++pu32XORSrc; /* Next source pixel. */
2320 ++pu32Dst; /* Next destination pixel. */
2321 }
2322
2323 /* Next AND scanline. */
2324 pu8ANDSrcLine += cbANDLine;
2325 }
2326}
2327#endif /* VBOX_WS_NIX || VBOX_WS_MAC */
2328
2329#ifdef VBOX_WS_WIN
2330/* static */
2331bool UIMachine::isPointer1bpp(const uint8_t *pu8XorMask,
2332 uint uWidth,
2333 uint uHeight)
2334{
2335 /* Check if the pointer has only 0 and 0xFFFFFF pixels, ignoring the alpha channel. */
2336 const uint32_t *pu32Src = (uint32_t *)pu8XorMask;
2337
2338 uint y;
2339 for (y = 0; y < uHeight ; ++y)
2340 {
2341 uint x;
2342 for (x = 0; x < uWidth; ++x)
2343 {
2344 const uint32_t u32Pixel = pu32Src[x] & UINT32_C(0xFFFFFF);
2345 if (u32Pixel != 0 && u32Pixel != UINT32_C(0xFFFFFF))
2346 return false;
2347 }
2348
2349 pu32Src += uWidth;
2350 }
2351
2352 return true;
2353}
2354#endif /* VBOX_WS_WIN */
2355
2356void UIMachine::updateVirtualizationState()
2357{
2358 uisession()->acquireExecutionEngineType(m_enmVMExecutionEngine);
2359 uisession()->acquireWhetherHwVirtExNestedPagingEnabled(m_fIsHWVirtExNestedPagingEnabled);
2360 uisession()->acquireWhetherHwVirtExUXEnabled(m_fIsHWVirtExUXEnabled);
2361 uisession()->acquireEffectiveParavirtProvider(m_enmParavirtProvider);
2362}
Note: See TracBrowser for help on using the repository browser.

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