VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h@ 3674

Last change on this file since 3674 was 3674, checked in by vboxsync, 17 years ago

Seamless Mode beta version committed:

  1. Menu item "Seamless Mode" is added into VM menu and linked to "GUI/Seamless" xml-config parameter.
  2. This menu item could be toggled on/off (the starting value is loading from config at startup) but disabled at startup until the guest additions notifies the host about this feature is supported.
  3. After that this mode is activated automatically (in case it was set "on" in config) and can be toggled on/off by the user with Host+S key-shortcut.

Due to any callback to guest additions are not supported yet (afaik) the Seamless Mode's starting screen could be correct (only one guest status-bar displayed) and incorrect sometimes (whole guest desktop). It becomes correct after any guest region update (for example, in case of any guest window is created, moved or resized).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.8 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * VBoxFrameBuffer class and subclasses declarations
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23#ifndef __VBoxFrameBuffer_h__
24#define __VBoxFrameBuffer_h__
25
26#include "COMDefs.h"
27
28class VBoxConsoleView;
29
30#include <qmutex.h>
31#include <qevent.h>
32#include <qpixmap.h>
33#include <qimage.h>
34
35#if defined (VBOX_GUI_USE_SDL)
36#include <SDL.h>
37#include <signal.h>
38#endif
39
40#if defined (Q_WS_WIN) && defined (VBOX_GUI_USE_DDRAW)
41// VBox/cdefs.h defines these:
42#undef LOWORD
43#undef HIWORD
44#undef LOBYTE
45#undef HIBYTE
46#include <ddraw.h>
47#endif
48
49//#define VBOX_GUI_FRAMEBUF_STAT
50
51#if defined (VBOX_GUI_DEBUG) && defined (VBOX_GUI_FRAMEBUF_STAT)
52#define FRAMEBUF_DEBUG_START(prefix) \
53 uint64_t prefix##elapsed = VMCPUTimer::ticks();
54#define FRAMEBUF_DEBUG_STOP(prefix,w,h) { \
55 prefix##elapsed = VMCPUTimer::ticks() - prefix##elapsed; \
56 V_DEBUG(( "Last update: %04d x %04d px, %03.3f ms, %.0f ticks", \
57 (w), (h), \
58 (double) prefix##elapsed / (double) VMCPUTimer::ticksPerMsec(), \
59 (double) prefix##elapsed \
60 )); \
61 }
62#else
63#define FRAMEBUF_DEBUG_START(prefix) {}
64#define FRAMEBUF_DEBUG_STOP(prefix,w,h) {}
65#endif
66
67/////////////////////////////////////////////////////////////////////////////
68
69/**
70 * Frame buffer resize event.
71 */
72class VBoxResizeEvent : public QEvent
73{
74public:
75 VBoxResizeEvent (FramebufferPixelFormat_T f, uchar *v, unsigned l, int w, int h) :
76 QEvent ((QEvent::Type) VBoxDefs::ResizeEventType), fmt (f), vr (v), lsz (l), wdt (w), hgt (h) {}
77 FramebufferPixelFormat_T pixelFormat() { return fmt; }
78 uchar *vram() { return vr; }
79 unsigned lineSize() { return lsz; }
80 int width() { return wdt; }
81 int height() { return hgt; }
82private:
83 FramebufferPixelFormat_T fmt;
84 uchar *vr;
85 unsigned lsz;
86 int wdt;
87 int hgt;
88};
89
90/**
91 * Frame buffer repaint event.
92 */
93class VBoxRepaintEvent : public QEvent
94{
95public:
96 VBoxRepaintEvent (int x, int y, int w, int h) :
97 QEvent ((QEvent::Type) VBoxDefs::RepaintEventType),
98 ex (x), ey (y), ew (w), eh (h)
99 {}
100 int x() { return ex; }
101 int y() { return ey; }
102 int width() { return ew; }
103 int height() { return eh; }
104private:
105 int ex, ey, ew, eh;
106};
107
108/**
109 * Frame buffer set region event.
110 */
111class VBoxSetRegionEvent : public QEvent
112{
113public:
114 VBoxSetRegionEvent (const QRegion &aReg)
115 : QEvent ((QEvent::Type) VBoxDefs::SetRegionEventType)
116 , mReg (aReg) {}
117 QRegion region() { return mReg; }
118private:
119 QRegion mReg;
120};
121
122/////////////////////////////////////////////////////////////////////////////
123
124#if defined (VBOX_GUI_USE_REFRESH_TIMER)
125
126/**
127 * Copies the current VM video buffer contents to the pixmap referenced
128 * by the argument. The return value indicates whether the
129 * buffer has been updated since the last call to this method or not.
130 *
131 * The copy operation is atomic (guarded by a mutex).
132 *
133 * This method is intentionally inlined for faster execution and should be
134 * called only by VBoxConsoleView members.
135 *
136 * @return true if the pixmap is updated, and false otherwise.
137 */
138inline bool display_to_pixmap( const CConsole &c, QPixmap &pm )
139{
140 CDisplay display = c.GetDisplay();
141
142 uint8_t *addr = (uint8_t *) display.LockFramebuffer();
143 AssertMsg (addr, ("The buffer address must not be null"));
144
145 bool rc = pm.convertFromImage (QImage (addr,
146 display.GetWidth(), display.GetHeight(),
147 display.GetColorDepth(),
148 0, 0, QImage::LittleEndian));
149 AssertMsg (rc, ("convertFromImage() must always return true"));
150
151 display.UnlockFramebuffer();
152
153 return rc;
154}
155
156#endif
157
158/////////////////////////////////////////////////////////////////////////////
159
160/* Framebuffer render mode */
161typedef enum
162{
163 RenderModeNormal = 0,
164 RenderModeSeamless = 1,
165 RenderModeHostWindow = 2
166} FramebufferRenderMode;
167
168/**
169 * Common IFramebuffer implementation for all methods used by GUI to maintain
170 * the VM display video memory.
171 *
172 * Note that although this class can be called from multiple threads
173 * (in particular, the GUI thread and EMT) it doesn't protect access to every
174 * data field using its mutex lock. This is because all synchronization between
175 * the GUI and the EMT thread is supposed to be done using the
176 * IFramebuffer::NotifyUpdate() and IFramebuffer::RequestResize() methods
177 * (in particular, the \a aFinished parameter of these methods is responsible
178 * for the synchronization). These methods are always called on EMT and
179 * therefore always follow one another but never in parallel.
180 *
181 * Using this object's mutex lock (exposed also in IFramebuffer::Lock() and
182 * IFramebuffer::Unlock() implementations) usually makes sense only if some
183 * third-party thread (i.e. other than GUI or EMT) needs to make sure that
184 * *no* VM display update or resize event can occur while it is accessing
185 * IFramebuffer properties or the underlying display memory storage area.
186 *
187 * See IFramebuffer documentation for more info.
188 */
189
190class VBoxFrameBuffer : public IFramebuffer
191{
192public:
193
194 VBoxFrameBuffer (VBoxConsoleView *aView);
195 virtual ~VBoxFrameBuffer();
196
197 NS_DECL_ISUPPORTS
198
199#if defined (Q_OS_WIN32)
200 STDMETHOD_(ULONG, AddRef)() {
201 return ::InterlockedIncrement (&refcnt);
202 }
203 STDMETHOD_(ULONG, Release)()
204 {
205 long cnt = ::InterlockedDecrement (&refcnt);
206 if (cnt == 0)
207 delete this;
208 return cnt;
209 }
210 STDMETHOD(QueryInterface) (REFIID riid , void **ppObj)
211 {
212 if (riid == IID_IUnknown) {
213 *ppObj = this;
214 AddRef();
215 return S_OK;
216 }
217 if (riid == IID_IFramebuffer) {
218 *ppObj = this;
219 AddRef();
220 return S_OK;
221 }
222 *ppObj = NULL;
223 return E_NOINTERFACE;
224 }
225#endif
226
227 // IFramebuffer COM methods
228 STDMETHOD(COMGETTER(Address)) (BYTE **aAddress);
229 STDMETHOD(COMGETTER(Width)) (ULONG *aWidth);
230 STDMETHOD(COMGETTER(Height)) (ULONG *aHeight);
231 STDMETHOD(COMGETTER(ColorDepth)) (ULONG *aColorDepth);
232 STDMETHOD(COMGETTER(LineSize)) (ULONG *aLineSize);
233 STDMETHOD(COMGETTER(PixelFormat)) (FramebufferPixelFormat_T *aPixelFormat);
234 STDMETHOD(COMGETTER(HeightReduction)) (ULONG *aHeightReduction);
235 STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
236 STDMETHOD(COMGETTER(RenderMode)) (FramebufferRenderMode *renderMode);
237 STDMETHOD(COMSETTER(RenderMode)) (FramebufferRenderMode renderMode);
238
239 STDMETHOD(Lock)();
240 STDMETHOD(Unlock)();
241
242 STDMETHOD(RequestResize) (ULONG aScreenId, FramebufferPixelFormat_T aPixelFormat,
243 BYTE *aVRAM, ULONG aLineSize,
244 ULONG aWidth, ULONG aHeight,
245 BOOL *aFinished);
246
247 STDMETHOD(OperationSupported)(FramebufferAccelerationOperation_T aOperation,
248 BOOL *aSupported);
249 STDMETHOD(VideoModeSupported) (ULONG aWidth, ULONG aHeight, ULONG aBPP,
250 BOOL *aSupported);
251 STDMETHOD(SolidFill) (ULONG aX, ULONG aY, ULONG aWidth, ULONG aHeight,
252 ULONG aColor, BOOL *aHandled);
253 STDMETHOD(CopyScreenBits) (ULONG aXDst, ULONG aYDst, ULONG aXSrc, ULONG aYSrc,
254 ULONG aWidth, ULONG aHeight, BOOL *aHandled);
255
256 STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
257 STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
258
259 // Helper functions
260 int width() { return mWdt; }
261 int height() { return mHgt; }
262
263 virtual FramebufferPixelFormat_T pixelFormat()
264 {
265 return FramebufferPixelFormat_PixelFormatOpaque;
266 }
267
268 void lock() { mMutex->lock(); }
269 void unlock() { mMutex->unlock(); }
270
271 virtual uchar *address() = 0;
272 virtual int colorDepth() = 0;
273 virtual int lineSize() = 0;
274
275 /**
276 * Called on the GUI thread (from VBoxConsoleView) when some part of the
277 * VM display viewport needs to be repainted on the host screen.
278 */
279 virtual void paintEvent (QPaintEvent *pe) = 0;
280
281 /**
282 * Called on the GUI thread (from VBoxConsoleView) after it gets a
283 * VBoxResizeEvent posted from the RequestResize() method implementation.
284 */
285 virtual void resizeEvent (VBoxResizeEvent *re)
286 {
287 mWdt = re->width();
288 mHgt = re->height();
289 }
290
291 /**
292 * Called on the GUI thread (from VBoxConsoleView) when the VM console
293 * window is moved.
294 */
295 virtual void moveEvent (QMoveEvent * /*me*/ ) {}
296
297protected:
298
299 VBoxConsoleView *mView;
300 QMutex *mMutex;
301 int mWdt;
302 int mHgt;
303
304 /* Framebuffer render mode */
305 FramebufferRenderMode mRenderMode;
306
307#if defined (Q_OS_WIN32)
308private:
309 long refcnt;
310#endif
311};
312
313/////////////////////////////////////////////////////////////////////////////
314
315#if defined (VBOX_GUI_USE_QIMAGE)
316
317class VBoxQImageFrameBuffer : public VBoxFrameBuffer
318{
319public:
320
321 VBoxQImageFrameBuffer (VBoxConsoleView *aView);
322
323 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
324 ULONG aW, ULONG aH,
325 BOOL *aFinished);
326
327 uchar *address() { return mImg.bits(); }
328 int colorDepth() { return mImg.depth(); }
329 int lineSize() { return mImg.bytesPerLine(); }
330
331 void paintEvent (QPaintEvent *pe);
332 void resizeEvent (VBoxResizeEvent *re);
333
334private:
335
336 QPixmap mPM;
337 QImage mImg;
338};
339
340#endif
341
342/////////////////////////////////////////////////////////////////////////////
343
344#if defined (VBOX_GUI_USE_SDL)
345
346class VBoxSDLFrameBuffer : public VBoxFrameBuffer
347{
348public:
349
350 VBoxSDLFrameBuffer (VBoxConsoleView *aView);
351 virtual ~VBoxSDLFrameBuffer();
352
353 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
354 ULONG aW, ULONG aH,
355 BOOL *aFinished);
356
357 uchar *address()
358 {
359 if (mSurfVRAM)
360 {
361 return (uchar*) (mScreen ? (uintptr_t) mSurfVRAM->pixels : 0);
362 }
363 else
364 {
365 return (uchar*) (mScreen ? (uintptr_t) mScreen->pixels : 0);
366 }
367 }
368
369 int colorDepth()
370 {
371 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
372 return surf ? surf->format->BitsPerPixel : 0;
373 }
374
375 int lineSize()
376 {
377 SDL_Surface *surf = mSurfVRAM ? mSurfVRAM: mScreen;
378 return surf ? surf->pitch : 0;
379 }
380
381 FramebufferPixelFormat_T pixelFormat()
382 {
383 return mPixelFormat;
384 }
385
386 void paintEvent (QPaintEvent *pe);
387 void resizeEvent (VBoxResizeEvent *re);
388
389private:
390
391 SDL_Surface *mScreen;
392 SDL_Surface *mSurfVRAM;
393
394 uchar *mPtrVRAM;
395 ULONG mLineSize;
396 FramebufferPixelFormat_T mPixelFormat;
397};
398
399#endif
400
401/////////////////////////////////////////////////////////////////////////////
402
403#if defined (VBOX_GUI_USE_DDRAW)
404
405class VBoxDDRAWFrameBuffer : public VBoxFrameBuffer
406{
407public:
408
409 VBoxDDRAWFrameBuffer (VBoxConsoleView *aView);
410 virtual ~VBoxDDRAWFrameBuffer();
411
412 STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
413 ULONG aW, ULONG aH,
414 BOOL *aFinished);
415
416 uchar *address() { return (uchar *)mSurfaceDesc.lpSurface; }
417 int colorDepth() { return mSurfaceDesc.ddpfPixelFormat.dwRGBBitCount; }
418 int lineSize() { return mSurfaceDesc.lPitch; }
419
420 FramebufferPixelFormat_T pixelFormat() { return mPixelFormat; };
421
422 void paintEvent (QPaintEvent *pe);
423 void resizeEvent (VBoxResizeEvent *re);
424 void moveEvent (QMoveEvent *me);
425
426private:
427 void releaseObjects();
428
429 void setupSurface (FramebufferPixelFormat_T pixelFormat, uchar *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
430 void recreateSurface (FramebufferPixelFormat_T pixelFormat, uchar *pvVRAM, ULONG lineSize, ULONG w, ULONG h);
431 void deleteSurface ();
432 void drawRect (ULONG x, ULONG y, ULONG w, ULONG h);
433 void getWindowPosition (void);
434
435 LPDIRECTDRAW7 mDDRAW;
436 LPDIRECTDRAWCLIPPER mClipper;
437 LPDIRECTDRAWSURFACE7 mSurface;
438 DDSURFACEDESC2 mSurfaceDesc;
439 LPDIRECTDRAWSURFACE7 mPrimarySurface;
440
441 FramebufferPixelFormat_T mPixelFormat;
442
443 BOOL mGuestVRAMSurface;
444
445 int mWndX;
446 int mWndY;
447
448 BOOL mSynchronousUpdates;
449};
450
451#endif
452
453#endif // __VBoxFrameBuffer_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