VirtualBox

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

Last change on this file was 103988, checked in by vboxsync, 2 months ago

FE/Qt. bugref:10624. Adding missing override keywords gcc has found.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.2 KB
Line 
1/* $Id: UIMachineView.h 103988 2024-03-21 13:49:47Z 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 "KMachineState.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 RT_OVERRIDE;
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) RT_OVERRIDE RT_FINAL;
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 eventFilter(QObject *pWatched, QEvent *pEvent) RT_OVERRIDE;
317 void resizeEvent(QResizeEvent *pEvent) RT_OVERRIDE RT_FINAL;
318 void moveEvent(QMoveEvent *pEvent) RT_OVERRIDE RT_FINAL;
319 void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE RT_FINAL;
320
321 /** Handles focus-in @a pEvent. */
322 void focusInEvent(QFocusEvent *pEvent) RT_OVERRIDE RT_FINAL;
323 /** Handles focus-out @a pEvent. */
324 void focusOutEvent(QFocusEvent *pEvent) RT_OVERRIDE RT_FINAL;
325#ifdef VBOX_WS_NIX
326 virtual void keyPressEvent(QKeyEvent *pEvent) RT_OVERRIDE RT_FINAL;
327 virtual void keyReleaseEvent(QKeyEvent *pEvent) RT_OVERRIDE RT_FINAL;
328#endif
329
330#ifdef VBOX_WITH_DRAG_AND_DROP
331 /**
332 * Returns @true if the VM window can accept (start is, start) a drag and drop
333 * operation, @false if not.
334 */
335 bool dragAndDropCanAccept() const;
336
337 /**
338 * Returns @true if drag and drop for this machine is active
339 * (that is, host->guest, guest->host or bidirectional), @false if not.
340 */
341 bool dragAndDropIsActive() const;
342
343 /**
344 * Host -> Guest: Issued when the host cursor enters the guest (VM) window.
345 * The guest will receive the relative cursor coordinates of the
346 * appropriate screen ID.
347 *
348 * @param pEvent Related enter event.
349 */
350 void dragEnterEvent(QDragEnterEvent *pEvent) RT_OVERRIDE RT_FINAL;
351
352 /**
353 * Host -> Guest: Issued when the host cursor moves inside (over) the guest (VM) window.
354 * The guest will receive the relative cursor coordinates of the
355 * appropriate screen ID.
356 *
357 * @param pEvent Related move event.
358 */
359 void dragLeaveEvent(QDragLeaveEvent *pEvent) RT_OVERRIDE RT_FINAL;
360
361 /**
362 * Host -> Guest: Issued when the host cursor leaves the guest (VM) window again.
363 * This will ask the guest to stop any further drag'n drop operation.
364 *
365 * @param pEvent Related leave event.
366 */
367 void dragMoveEvent(QDragMoveEvent *pEvent) RT_OVERRIDE RT_FINAL;
368
369 /**
370 * Host -> Guest: Issued when the host drops data into the guest (VM) window.
371 *
372 * @param pEvent Related drop event.
373 */
374 void dropEvent(QDropEvent *pEvent) RT_OVERRIDE RT_FINAL;
375#endif /* VBOX_WITH_DRAG_AND_DROP */
376
377 /** Scales passed size forward. */
378 QSize scaledForward(QSize size) const;
379 /** Scales passed size backward. */
380 QSize scaledBackward(QSize size) const;
381
382 /** Updates mouse pointer @a pixmap, @a uXHot and @a uYHot according to scaling attributes. */
383 void updateMousePointerPixmapScaling(QPixmap &pixmap, uint &uXHot, uint &uYHot);
384
385 /* Protected members: */
386 UIMachineWindow *m_pMachineWindow;
387 ulong m_uScreenId;
388 KMachineState m_previousState;
389 /** HACK: when switching out of fullscreen or seamless we wish to override
390 * the default size hint to avoid short resizes back to fullscreen size.
391 * Not explicitly initialised (i.e. invalid by default). */
392 QSize m_sizeHintOverride;
393
394 /** Last size hint sent as a part of guest auto-resize feature.
395 * @note Useful to avoid spamming CDisplay with same hint before
396 * frame-buffer finally resized to requested size. */
397 QSize m_lastSizeHint;
398
399 /** Holds current host-screen number. */
400 int m_iHostScreenNumber;
401
402 /** Holds the maximum guest screen size policy. */
403 MaximumGuestScreenSizePolicy m_enmMaximumGuestScreenSizePolicy;
404 /** The maximum guest size for fixed size policy. */
405 QSize m_fixedMaxGuestSize;
406 /** Maximum guest resolution which we wish to handle. Must be accessed
407 * atomically.
408 * @note The background for this variable is that we need this value to be
409 * available to the EMT thread, but it can only be calculated by the
410 * GUI, and GUI code can only safely be called on the GUI thread due to
411 * (at least) X11 threading issues. So we calculate the value in advance,
412 * monitor things in case it changes and update it atomically when it does.
413 */
414 /** @todo This should be private. */
415 volatile uint64_t m_u64MaximumGuestSize;
416
417 /** Holds the pause-pixmap. */
418 QPixmap m_pausePixmap;
419 /** Holds the scaled pause-pixmap. */
420 QPixmap m_pausePixmapScaled;
421
422 /** Holds cached mouse cursor. */
423 QCursor m_cursor;
424
425#ifdef VBOX_WITH_DRAG_AND_DROP
426 /** Pointer to drag and drop handler instance. */
427 UIDnDHandler *m_pDnDHandler;
428# ifdef VBOX_WITH_DRAG_AND_DROP_GH
429 /** Flag indicating whether a guest->host drag currently is in
430 * progress or not. */
431 bool m_fIsDraggingFromGuest;
432# endif
433#endif
434
435 /** Holds the native event filter instance. */
436 UINativeEventFilter *m_pNativeEventFilter;
437};
438
439/* This maintenance class is a part of future roll-back mechanism.
440 * It allows to block main GUI thread until specific event received.
441 * Later it will become more abstract but now its just used to help
442 * fullscreen & seamless modes to restore normal guest size hint. */
443/** @todo This class is now unused - can it be removed altogether? */
444class UIMachineViewBlocker : public QEventLoop
445{
446 Q_OBJECT;
447
448public:
449
450 UIMachineViewBlocker()
451 : QEventLoop(0)
452 , m_iTimerId(0)
453 {
454 /* Also start timer to unlock pool in case of
455 * required condition doesn't happens by some reason: */
456 m_iTimerId = startTimer(3000);
457 }
458
459 virtual ~UIMachineViewBlocker()
460 {
461 /* Kill the timer: */
462 killTimer(m_iTimerId);
463 }
464
465protected:
466
467 void timerEvent(QTimerEvent *pEvent) RT_OVERRIDE RT_FINAL
468 {
469 /* If that timer event occurs => it seems
470 * guest resize event doesn't comes in time,
471 * shame on it, but we just unlocking 'this': */
472 QEventLoop::timerEvent(pEvent);
473 exit();
474 }
475
476 int m_iTimerId;
477};
478
479#endif /* !FEQT_INCLUDED_SRC_runtime_UIMachineView_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use