VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h@ 100064

Last change on this file since 100064 was 100064, checked in by vboxsync, 12 months ago

FE/Qt: bugref:10421. Replacing VBOX_WS_X11 with VBOX_WS_NIX.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.9 KB
Line 
1/* $Id: UIMachineView.h 100064 2023-06-04 09:10:01Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineView class declaration.
4 */
5
6/*
7 * Copyright (C) 2010-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#ifndef FEQT_INCLUDED_SRC_runtime_UIMachineView_h
29#define FEQT_INCLUDED_SRC_runtime_UIMachineView_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34/* Qt includes: */
35#include <QAbstractScrollArea>
36#include <QEventLoop>
37
38/* GUI includes: */
39#include "UIExtraDataDefs.h"
40#include "UIFrameBuffer.h"
41#include "UIMachineDefs.h"
42#ifdef VBOX_WITH_DRAG_AND_DROP
43# include "UIDnDHandler.h"
44#endif /* VBOX_WITH_DRAG_AND_DROP */
45
46/* COM includes: */
47#include "COMEnums.h"
48
49/* Other VBox includes: */
50#include "VBox/com/ptr.h"
51#ifdef VBOX_WS_MAC
52# include <ApplicationServices/ApplicationServices.h>
53#endif /* VBOX_WS_MAC */
54
55/* External includes: */
56#ifdef VBOX_WS_MAC
57# include <CoreFoundation/CFBase.h>
58#endif /* VBOX_WS_MAC */
59
60/* Forward declarations: */
61class UIActionPool;
62class UIMachine;
63class UIMachineLogic;
64class UIMachineWindow;
65class UINativeEventFilter;
66class CGuest;
67class CSession;
68#ifdef VBOX_WITH_DRAG_AND_DROP
69class CDnDTarget;
70#endif
71
72
73class UIMachineView : public QAbstractScrollArea
74{
75 Q_OBJECT;
76
77signals:
78
79 /** Notifies about mouse pointer shape change. */
80 void sigMousePointerShapeChange();
81 /** Notifies about frame-buffer resize. */
82 void sigFrameBufferResize();
83
84public:
85
86 /* Factory function to create machine-view: */
87 static UIMachineView* create(UIMachineWindow *pMachineWindow, ulong uScreenId, UIVisualStateType visualStateType);
88 /* Factory function to destroy required machine-view: */
89 static void destroy(UIMachineView *pMachineView);
90
91 /** Returns whether the guest-screen auto-resize is enabled. */
92 virtual bool isGuestAutoresizeEnabled() const { return true; }
93 /** Defines whether the guest-screen auto-resize is @a fEnabled. */
94 virtual void setGuestAutoresizeEnabled(bool fEnabled) { Q_UNUSED(fEnabled); }
95
96 /** Send saved guest-screen size-hint to the guest.
97 * @note Reimplemented in sub-classes. Base implementation does nothing. */
98 virtual void resendSizeHint() {}
99
100 /** Adjusts guest-screen size to correspond current visual-style.
101 * @note Reimplemented in sub-classes. Base implementation does nothing. */
102 virtual void adjustGuestScreenSize() {}
103
104 /** Applies machine-view scale-factor. */
105 virtual void applyMachineViewScaleFactor();
106
107 /** Returns screen ID for this view. */
108 ulong screenId() const { return m_uScreenId; }
109
110 /** Returns the machine UI reference. */
111 UIMachine *uimachine() const;
112 /** Returns the machine-logic reference. */
113 UIMachineLogic *machineLogic() const;
114 /** Returns the machine-window reference. */
115 UIMachineWindow *machineWindow() const { return m_pMachineWindow; }
116 /** Returns view's frame-buffer reference. */
117 UIFrameBuffer *frameBuffer() const;
118
119 /** Returns actual contents width. */
120 int contentsWidth() const;
121 /** Returns actual contents height. */
122 int contentsHeight() const;
123 /** Returns actual contents x origin. */
124 int contentsX() const;
125 /** Returns actual contents y origin. */
126 int contentsY() const;
127 /** Returns visible contents width. */
128 int visibleWidth() const;
129 /** Returns visible contents height. */
130 int visibleHeight() const;
131 /** Translates viewport point to contents point. */
132 QPoint viewportToContents(const QPoint &viewportPoint) const;
133 /** Scrolls contents by @a iDx x iDy pixels. */
134 void scrollBy(int iDx, int iDy);
135
136 /** What view mode (normal, fullscreen etc.) are we in? */
137 UIVisualStateType visualStateType() const;
138
139 /** Returns cached mouse cursor. */
140 QCursor cursor() const { return m_cursor; }
141
142 /* Framebuffer aspect ratio: */
143 double aspectRatio() const;
144
145 /** Atomically store the maximum guest resolution which we currently wish
146 * to handle for @a maximumGuestSize() to read. Should be called if anything
147 * happens (e.g. a screen hotplug) which might cause the value to change.
148 * @sa m_u64MaximumGuestSize. */
149 void setMaximumGuestSize(const QSize &minimumSizeHint = QSize());
150 /** Atomically read the maximum guest resolution which we currently wish to
151 * handle. This may safely be called from another thread (called by
152 * UIFramebuffer on EMT).
153 * @sa m_u64MaximumGuestSize. */
154 QSize maximumGuestSize();
155
156 /** Updates console's display viewport.
157 * @remarks Used to update 3D-service overlay viewport as well. */
158 void updateViewport();
159
160#ifdef VBOX_WITH_DRAG_AND_DROP
161 /** Checks for a pending drag and drop event within the guest and
162 * (optionally) starts a drag and drop operation on the host. */
163 int dragCheckPending();
164 /** Starts a drag and drop operation from guest to the host.
165 * This internally either uses Qt's abstract QDrag methods
166 * or some other OS-dependent implementation. */
167 int dragStart();
168 /** Aborts (and resets) the current (pending)
169 * guest to host drag and drop operation. */
170 int dragStop();
171#endif /* VBOX_WITH_DRAG_AND_DROP */
172
173 /** Performs pre-processing of all the native events. */
174 virtual bool nativeEventPreprocessor(const QByteArray &eventType, void *pMessage);
175
176#ifdef VBOX_WS_MAC
177 /** Returns VM contents image. */
178 CGImageRef vmContentImage();
179#endif
180
181public slots:
182
183 /** Handles NotifyChange event received from frame-buffer.
184 * @todo To make it right, this have to be protected, but
185 * connection should be moved from frame-buffer to this class. */
186 virtual void sltHandleNotifyChange(int iWidth, int iHeight);
187
188 /** Handles NotifyUpdate event received from frame-buffer.
189 * @todo To make it right, this have to be protected, but
190 * connection should be moved from frame-buffer to this class. */
191 virtual void sltHandleNotifyUpdate(int iX, int iY, int iWidth, int iHeight);
192
193 /** Handles SetVisibleRegion event received from frame-buffer.
194 * @todo To make it right, this have to be protected, but
195 * connection should be moved from frame-buffer to this class. */
196 virtual void sltHandleSetVisibleRegion(QRegion region);
197
198protected slots:
199
200 /* Performs guest-screen resize to a size specified.
201 * @param toSize Brings the size guest-screen needs to be resized to.
202 * @note If toSize isn't valid or sane one, it will be replaced with actual
203 * size of centralWidget() containing this machine-view currently.
204 * @note Also, take into acount that since this method is also called to
205 * resize to centralWidget() size, the size passed is expected to be
206 * tranformed to internal coordinate system and thus to be restored to
207 * guest coordinate system (absolute one) before passing to guest. */
208 void sltPerformGuestResize(const QSize &toSize = QSize());
209
210 /** Handles guest-screen toggle request.
211 * @param iScreen Brings the number of screen being referred.
212 * @param fEnabled Brings whether this screen should be enabled. */
213 void sltHandleActionTriggerViewScreenToggle(int iScreen, bool fEnabled);
214 /** Handles guest-screen resize request.
215 * @param iScreen Brings the number of screen being referred.
216 * @param size Brings the size of screen to be applied. */
217 void sltHandleActionTriggerViewScreenResize(int iScreen, const QSize &size);
218
219 /* Watch dog for desktop resizes: */
220 void sltDesktopResized();
221
222 /** Handles the scale-factor change. */
223 void sltHandleScaleFactorChange(const QUuid &uMachineID);
224
225 /** Handles the scaling-optimization change. */
226 void sltHandleScalingOptimizationChange(const QUuid &uMachineID);
227
228 /* Console callback handlers: */
229 virtual void sltMachineStateChanged();
230 /** Handles guest request to change the mouse pointer shape. */
231 void sltMousePointerShapeChange();
232
233 /** Detaches COM. */
234 void sltDetachCOM();
235
236protected:
237
238 /* Machine-view constructor: */
239 UIMachineView(UIMachineWindow *pMachineWindow, ulong uScreenId);
240 /* Machine-view destructor: */
241 virtual ~UIMachineView() {}
242
243 /* Prepare routines: */
244 virtual void loadMachineViewSettings();
245 //virtual void prepareNativeFilters() {}
246 virtual void prepareViewport();
247 virtual void prepareFrameBuffer();
248 virtual void prepareCommon();
249#ifdef VBOX_WITH_DRAG_AND_DROP
250 virtual int prepareDnd();
251#endif
252 virtual void prepareFilters();
253 virtual void prepareConnections();
254 virtual void prepareConsoleConnections();
255
256 /* Cleanup routines: */
257 //virtual void cleanupConsoleConnections() {}
258 //virtual void cleanupConnections() {}
259 //virtual void cleanupFilters() {}
260#ifdef VBOX_WITH_DRAG_AND_DROP
261 virtual void cleanupDnd();
262#endif
263 //virtual void cleanupCommon() {}
264 virtual void cleanupFrameBuffer();
265 //virtual void cleanupViewport();
266 virtual void cleanupNativeFilters();
267 //virtual void saveMachineViewSettings() {}
268
269 /* Protected getters: */
270 UIActionPool* actionPool() const;
271 QSize sizeHint() const;
272
273 /** Retrieves the last guest-screen size-hint from extra-data. */
274 QSize storedGuestScreenSizeHint() const;
275 /** Stores a guest-screen @a sizeHint to extra-data. */
276 void setStoredGuestScreenSizeHint(const QSize &sizeHint);
277
278 /** Retrieves the sent guest-screen size-hint from display or frame-buffer. */
279 QSize requestedGuestScreenSizeHint() const;
280
281 /** Retrieves the last guest-screen visibility status from extra-data. */
282 bool guestScreenVisibilityStatus() const;
283
284 /** Handles machine-view scale changes. */
285 void handleScaleChange();
286
287 /** Returns the pause-pixmap: */
288 const QPixmap& pausePixmap() const { return m_pausePixmap; }
289 /** Returns the scaled pause-pixmap: */
290 const QPixmap& pausePixmapScaled() const { return m_pausePixmapScaled; }
291 /** Resets the pause-pixmap. */
292 void resetPausePixmap();
293 /** Acquires live pause-pixmap. */
294 void takePausePixmapLive();
295 /** Acquires snapshot pause-pixmap. */
296 void takePausePixmapSnapshot();
297 /** Updates the scaled pause-pixmap. */
298 void updateScaledPausePixmap();
299
300 /** The available area on the current screen for application windows. */
301 virtual QRect workingArea() const = 0;
302 /** Calculate how big the guest desktop can be while still fitting on one
303 * host screen. */
304 virtual QSize calculateMaxGuestSize() const = 0;
305 virtual void updateSliders();
306 static void dimImage(QImage &img);
307 void scrollContentsBy(int dx, int dy);
308#ifdef VBOX_WS_MAC
309 void updateDockIcon();
310 CGImageRef frameBuffertoCGImageRef(UIFrameBuffer *pFrameBuffer);
311#endif /* VBOX_WS_MAC */
312 /** Is this a fullscreen-type view? */
313 bool isFullscreenOrSeamless() const;
314
315 /* Cross-platforms event processors: */
316 bool event(QEvent *pEvent);
317 bool eventFilter(QObject *pWatched, QEvent *pEvent);
318 void resizeEvent(QResizeEvent *pEvent);
319 void moveEvent(QMoveEvent *pEvent);
320 void paintEvent(QPaintEvent *pEvent);
321
322 /** Handles focus-in @a pEvent. */
323 void focusInEvent(QFocusEvent *pEvent);
324 /** Handles focus-out @a pEvent. */
325 void focusOutEvent(QFocusEvent *pEvent);
326#ifdef VBOX_WS_NIX
327 virtual void keyPressEvent(QKeyEvent *pEvent) override;
328 virtual void keyReleaseEvent(QKeyEvent *pEvent) override;
329#endif
330
331#ifdef VBOX_WITH_DRAG_AND_DROP
332 /**
333 * Returns @true if the VM window can accept (start is, start) a drag and drop
334 * operation, @false if not.
335 */
336 bool dragAndDropCanAccept() const;
337
338 /**
339 * Returns @true if drag and drop for this machine is active
340 * (that is, host->guest, guest->host or bidirectional), @false if not.
341 */
342 bool dragAndDropIsActive() const;
343
344 /**
345 * Host -> Guest: Issued when the host cursor enters the guest (VM) window.
346 * The guest will receive the relative cursor coordinates of the
347 * appropriate screen ID.
348 *
349 * @param pEvent Related enter event.
350 */
351 void dragEnterEvent(QDragEnterEvent *pEvent);
352
353 /**
354 * Host -> Guest: Issued when the host cursor moves inside (over) the guest (VM) window.
355 * The guest will receive the relative cursor coordinates of the
356 * appropriate screen ID.
357 *
358 * @param pEvent Related move event.
359 */
360 void dragLeaveEvent(QDragLeaveEvent *pEvent);
361
362 /**
363 * Host -> Guest: Issued when the host cursor leaves the guest (VM) window again.
364 * This will ask the guest to stop any further drag'n drop operation.
365 *
366 * @param pEvent Related leave event.
367 */
368 void dragMoveEvent(QDragMoveEvent *pEvent);
369
370 /**
371 * Host -> Guest: Issued when the host drops data into the guest (VM) window.
372 *
373 * @param pEvent Related drop event.
374 */
375 void dropEvent(QDropEvent *pEvent);
376#endif /* VBOX_WITH_DRAG_AND_DROP */
377
378 /** Scales passed size forward. */
379 QSize scaledForward(QSize size) const;
380 /** Scales passed size backward. */
381 QSize scaledBackward(QSize size) const;
382
383 /** Updates mouse pointer @a pixmap, @a uXHot and @a uYHot according to scaling attributes. */
384 void updateMousePointerPixmapScaling(QPixmap &pixmap, uint &uXHot, uint &uYHot);
385
386 /* Protected members: */
387 UIMachineWindow *m_pMachineWindow;
388 ulong m_uScreenId;
389 KMachineState m_previousState;
390 /** HACK: when switching out of fullscreen or seamless we wish to override
391 * the default size hint to avoid short resizes back to fullscreen size.
392 * Not explicitly initialised (i.e. invalid by default). */
393 QSize m_sizeHintOverride;
394
395 /** Last size hint sent as a part of guest auto-resize feature.
396 * @note Useful to avoid spamming CDisplay with same hint before
397 * frame-buffer finally resized to requested size. */
398 QSize m_lastSizeHint;
399
400 /** Holds current host-screen number. */
401 int m_iHostScreenNumber;
402
403 /** Holds the maximum guest screen size policy. */
404 MaximumGuestScreenSizePolicy m_enmMaximumGuestScreenSizePolicy;
405 /** The maximum guest size for fixed size policy. */
406 QSize m_fixedMaxGuestSize;
407 /** Maximum guest resolution which we wish to handle. Must be accessed
408 * atomically.
409 * @note The background for this variable is that we need this value to be
410 * available to the EMT thread, but it can only be calculated by the
411 * GUI, and GUI code can only safely be called on the GUI thread due to
412 * (at least) X11 threading issues. So we calculate the value in advance,
413 * monitor things in case it changes and update it atomically when it does.
414 */
415 /** @todo This should be private. */
416 volatile uint64_t m_u64MaximumGuestSize;
417
418 /** Holds the pause-pixmap. */
419 QPixmap m_pausePixmap;
420 /** Holds the scaled pause-pixmap. */
421 QPixmap m_pausePixmapScaled;
422
423 /** Holds cached mouse cursor. */
424 QCursor m_cursor;
425
426#ifdef VBOX_WITH_DRAG_AND_DROP
427 /** Pointer to drag and drop handler instance. */
428 UIDnDHandler *m_pDnDHandler;
429# ifdef VBOX_WITH_DRAG_AND_DROP_GH
430 /** Flag indicating whether a guest->host drag currently is in
431 * progress or not. */
432 bool m_fIsDraggingFromGuest;
433# endif
434#endif
435
436 /** Holds the native event filter instance. */
437 UINativeEventFilter *m_pNativeEventFilter;
438};
439
440/* This maintenance class is a part of future roll-back mechanism.
441 * It allows to block main GUI thread until specific event received.
442 * Later it will become more abstract but now its just used to help
443 * fullscreen & seamless modes to restore normal guest size hint. */
444/** @todo This class is now unused - can it be removed altogether? */
445class UIMachineViewBlocker : public QEventLoop
446{
447 Q_OBJECT;
448
449public:
450
451 UIMachineViewBlocker()
452 : QEventLoop(0)
453 , m_iTimerId(0)
454 {
455 /* Also start timer to unlock pool in case of
456 * required condition doesn't happens by some reason: */
457 m_iTimerId = startTimer(3000);
458 }
459
460 virtual ~UIMachineViewBlocker()
461 {
462 /* Kill the timer: */
463 killTimer(m_iTimerId);
464 }
465
466protected:
467
468 void timerEvent(QTimerEvent *pEvent)
469 {
470 /* If that timer event occurs => it seems
471 * guest resize event doesn't comes in time,
472 * shame on it, but we just unlocking 'this': */
473 QEventLoop::timerEvent(pEvent);
474 exit();
475 }
476
477 int m_iTimerId;
478};
479
480#endif /* !FEQT_INCLUDED_SRC_runtime_UIMachineView_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use