VirtualBox

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

Last change on this file since 82781 was 82032, checked in by vboxsync, 5 years ago

FE/Qt: bugref:9598: UISession, UIMachineView and UIMouseHandler: Now the curious one, mouse pointer shape scaling should be done on per-screen basis, so we had to move corresponding functionality from session to particular machine-view and keep proper signal order hierarchy accordingly; This will probably break frame-buffer cursor functionality.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use