VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • 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 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineView class declaration.
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#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
236 /** Handles translation event. */
237 void sltRetranslateUI();
238
239protected:
240
241 /* Machine-view constructor: */
242 UIMachineView(UIMachineWindow *pMachineWindow, ulong uScreenId);
243 /* Machine-view destructor: */
244 virtual ~UIMachineView() {}
245
246 /* Prepare routines: */
247 virtual void loadMachineViewSettings();
248 //virtual void prepareNativeFilters() {}
249 virtual void prepareViewport();
250 virtual void prepareFrameBuffer();
251 virtual void prepareCommon();
252#ifdef VBOX_WITH_DRAG_AND_DROP
253 virtual int prepareDnd();
254#endif
255 virtual void prepareFilters();
256 virtual void prepareConnections();
257 virtual void prepareConsoleConnections();
258
259 /* Cleanup routines: */
260 //virtual void cleanupConsoleConnections() {}
261 //virtual void cleanupConnections() {}
262 //virtual void cleanupFilters() {}
263#ifdef VBOX_WITH_DRAG_AND_DROP
264 virtual void cleanupDnd();
265#endif
266 //virtual void cleanupCommon() {}
267 virtual void cleanupFrameBuffer();
268 //virtual void cleanupViewport();
269 virtual void cleanupNativeFilters();
270 //virtual void saveMachineViewSettings() {}
271
272 /* Protected getters: */
273 UIActionPool* actionPool() const;
274 QSize sizeHint() const RT_OVERRIDE;
275
276 /** Retrieves the last guest-screen size-hint from extra-data. */
277 QSize storedGuestScreenSizeHint() const;
278 /** Stores a guest-screen @a sizeHint to extra-data. */
279 void setStoredGuestScreenSizeHint(const QSize &sizeHint);
280
281 /** Retrieves the sent guest-screen size-hint from display or frame-buffer. */
282 QSize requestedGuestScreenSizeHint() const;
283
284 /** Retrieves the last guest-screen visibility status from extra-data. */
285 bool guestScreenVisibilityStatus() const;
286
287 /** Handles machine-view scale changes. */
288 void handleScaleChange();
289
290 /** Returns the pause-pixmap: */
291 const QPixmap& pausePixmap() const { return m_pausePixmap; }
292 /** Returns the scaled pause-pixmap: */
293 const QPixmap& pausePixmapScaled() const { return m_pausePixmapScaled; }
294 /** Resets the pause-pixmap. */
295 void resetPausePixmap();
296 /** Acquires live pause-pixmap. */
297 void takePausePixmapLive();
298 /** Acquires snapshot pause-pixmap. */
299 void takePausePixmapSnapshot();
300 /** Updates the scaled pause-pixmap. */
301 void updateScaledPausePixmap();
302
303 /** The available area on the current screen for application windows. */
304 virtual QRect workingArea() const = 0;
305 /** Calculate how big the guest desktop can be while still fitting on one
306 * host screen. */
307 virtual QSize calculateMaxGuestSize() const = 0;
308 virtual void updateSliders();
309 static void dimImage(QImage &img);
310 void scrollContentsBy(int dx, int dy) RT_OVERRIDE RT_FINAL;
311#ifdef VBOX_WS_MAC
312 void updateDockIcon();
313 CGImageRef frameBuffertoCGImageRef(UIFrameBuffer *pFrameBuffer);
314#endif /* VBOX_WS_MAC */
315 /** Is this a fullscreen-type view? */
316 bool isFullscreenOrSeamless() const;
317
318 /* Cross-platforms event processors: */
319 bool eventFilter(QObject *pWatched, QEvent *pEvent) RT_OVERRIDE;
320 void resizeEvent(QResizeEvent *pEvent) RT_OVERRIDE RT_FINAL;
321 void moveEvent(QMoveEvent *pEvent) RT_OVERRIDE RT_FINAL;
322 void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE RT_FINAL;
323
324 /** Handles focus-in @a pEvent. */
325 void focusInEvent(QFocusEvent *pEvent) RT_OVERRIDE RT_FINAL;
326 /** Handles focus-out @a pEvent. */
327 void focusOutEvent(QFocusEvent *pEvent) RT_OVERRIDE RT_FINAL;
328#ifdef VBOX_WS_NIX
329 virtual void keyPressEvent(QKeyEvent *pEvent) RT_OVERRIDE RT_FINAL;
330 virtual void keyReleaseEvent(QKeyEvent *pEvent) RT_OVERRIDE RT_FINAL;
331#endif
332
333#ifdef VBOX_WITH_DRAG_AND_DROP
334 /**
335 * Returns @true if the VM window can accept (start is, start) a drag and drop
336 * operation, @false if not.
337 */
338 bool dragAndDropCanAccept() const;
339
340 /**
341 * Returns @true if drag and drop for this machine is active
342 * (that is, host->guest, guest->host or bidirectional), @false if not.
343 */
344 bool dragAndDropIsActive() const;
345
346 /**
347 * Host -> Guest: Issued when the host cursor enters the guest (VM) window.
348 * The guest will receive the relative cursor coordinates of the
349 * appropriate screen ID.
350 *
351 * @param pEvent Related enter event.
352 */
353 void dragEnterEvent(QDragEnterEvent *pEvent) RT_OVERRIDE RT_FINAL;
354
355 /**
356 * Host -> Guest: Issued when the host cursor moves inside (over) the guest (VM) window.
357 * The guest will receive the relative cursor coordinates of the
358 * appropriate screen ID.
359 *
360 * @param pEvent Related move event.
361 */
362 void dragLeaveEvent(QDragLeaveEvent *pEvent) RT_OVERRIDE RT_FINAL;
363
364 /**
365 * Host -> Guest: Issued when the host cursor leaves the guest (VM) window again.
366 * This will ask the guest to stop any further drag'n drop operation.
367 *
368 * @param pEvent Related leave event.
369 */
370 void dragMoveEvent(QDragMoveEvent *pEvent) RT_OVERRIDE RT_FINAL;
371
372 /**
373 * Host -> Guest: Issued when the host drops data into the guest (VM) window.
374 *
375 * @param pEvent Related drop event.
376 */
377 void dropEvent(QDropEvent *pEvent) RT_OVERRIDE RT_FINAL;
378#endif /* VBOX_WITH_DRAG_AND_DROP */
379
380 /** Scales passed size forward. */
381 QSize scaledForward(QSize size) const;
382 /** Scales passed size backward. */
383 QSize scaledBackward(QSize size) const;
384
385 /** Updates mouse pointer @a pixmap, @a uXHot and @a uYHot according to scaling attributes. */
386 void updateMousePointerPixmapScaling(QPixmap &pixmap, uint &uXHot, uint &uYHot);
387
388 /* Protected members: */
389 UIMachineWindow *m_pMachineWindow;
390 ulong m_uScreenId;
391 KMachineState m_previousState;
392 /** HACK: when switching out of fullscreen or seamless we wish to override
393 * the default size hint to avoid short resizes back to fullscreen size.
394 * Not explicitly initialised (i.e. invalid by default). */
395 QSize m_sizeHintOverride;
396
397 /** Last size hint sent as a part of guest auto-resize feature.
398 * @note Useful to avoid spamming CDisplay with same hint before
399 * frame-buffer finally resized to requested size. */
400 QSize m_lastSizeHint;
401
402 /** Holds current host-screen number. */
403 int m_iHostScreenNumber;
404
405 /** Holds the maximum guest screen size policy. */
406 MaximumGuestScreenSizePolicy m_enmMaximumGuestScreenSizePolicy;
407 /** The maximum guest size for fixed size policy. */
408 QSize m_fixedMaxGuestSize;
409 /** Maximum guest resolution which we wish to handle. Must be accessed
410 * atomically.
411 * @note The background for this variable is that we need this value to be
412 * available to the EMT thread, but it can only be calculated by the
413 * GUI, and GUI code can only safely be called on the GUI thread due to
414 * (at least) X11 threading issues. So we calculate the value in advance,
415 * monitor things in case it changes and update it atomically when it does.
416 */
417 /** @todo This should be private. */
418 volatile uint64_t m_u64MaximumGuestSize;
419
420 /** Holds the pause-pixmap. */
421 QPixmap m_pausePixmap;
422 /** Holds the scaled pause-pixmap. */
423 QPixmap m_pausePixmapScaled;
424
425 /** Holds cached mouse cursor. */
426 QCursor m_cursor;
427
428#ifdef VBOX_WITH_DRAG_AND_DROP
429 /** Pointer to drag and drop handler instance. */
430 UIDnDHandler *m_pDnDHandler;
431# ifdef VBOX_WITH_DRAG_AND_DROP_GH
432 /** Flag indicating whether a guest->host drag currently is in
433 * progress or not. */
434 bool m_fIsDraggingFromGuest;
435# endif
436#endif
437
438 /** Holds the native event filter instance. */
439 UINativeEventFilter *m_pNativeEventFilter;
440};
441
442/* This maintenance class is a part of future roll-back mechanism.
443 * It allows to block main GUI thread until specific event received.
444 * Later it will become more abstract but now its just used to help
445 * fullscreen & seamless modes to restore normal guest size hint. */
446/** @todo This class is now unused - can it be removed altogether? */
447class UIMachineViewBlocker : public QEventLoop
448{
449 Q_OBJECT;
450
451public:
452
453 UIMachineViewBlocker()
454 : QEventLoop(0)
455 , m_iTimerId(0)
456 {
457 /* Also start timer to unlock pool in case of
458 * required condition doesn't happens by some reason: */
459 m_iTimerId = startTimer(3000);
460 }
461
462 virtual ~UIMachineViewBlocker()
463 {
464 /* Kill the timer: */
465 killTimer(m_iTimerId);
466 }
467
468protected:
469
470 void timerEvent(QTimerEvent *pEvent) RT_OVERRIDE RT_FINAL
471 {
472 /* If that timer event occurs => it seems
473 * guest resize event doesn't comes in time,
474 * shame on it, but we just unlocking 'this': */
475 QEventLoop::timerEvent(pEvent);
476 exit();
477 }
478
479 int m_iTimerId;
480};
481
482#endif /* !FEQT_INCLUDED_SRC_runtime_UIMachineView_h */
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