VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferSDL.cpp@ 27107

Last change on this file since 27107 was 27107, checked in by vboxsync, 14 years ago

FE/Qt4: New running VM core: frame-buffer initial resize event leak.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/* $Id: UIFrameBufferSDL.cpp 27107 2010-03-05 15:50:00Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UIFrameBufferSDL class
6 */
7
8/*
9 * Copyright (C) 2010 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24#ifdef VBOX_GUI_USE_SDL
25
26#ifdef VBOX_WITH_PRECOMPILED_HEADERS
27# include "precomp.h"
28#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
29
30/* Local includes */
31# include "UIFrameBufferSDL.h"
32# include "UIMachineView.h"
33# include "VBoxX11Helper.h"
34
35/* Global includes */
36# include <QApplication>
37
38#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
39
40/** @class UIFrameBufferSDL
41 *
42 * The UIFrameBufferSDL class is a class that implements the IFrameBuffer
43 * interface and uses SDL to store and render VM display data.
44 */
45UIFrameBufferSDL::UIFrameBufferSDL(UIMachineView *pMachineView)
46 : UIFrameBuffer(pMachineView)
47{
48 m_pScreen = NULL;
49 m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
50 m_pSurfVRAM = NULL;
51
52 X11ScreenSaverSettingsInit();
53 UIResizeEvent event(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480);
54 resizeEvent(&event);
55}
56
57UIFrameBufferSDL::~UIFrameBufferSDL()
58{
59 if (m_pSurfVRAM)
60 {
61 SDL_FreeSurface(m_pSurfVRAM);
62 m_pSurfVRAM = NULL;
63 }
64 X11ScreenSaverSettingsSave();
65 SDL_QuitSubSystem(SDL_INIT_VIDEO);
66 X11ScreenSaverSettingsRestore();
67}
68
69/** @note This method is called on EMT from under this object's lock */
70STDMETHODIMP UIFrameBufferSDL::NotifyUpdate(ULONG uX, ULONG uY, ULONG uW, ULONG uH)
71{
72#if !defined (Q_WS_WIN) && !defined (Q_WS_PM)
73 /* we're not on the GUI thread and update() isn't thread safe in Qt 3.3.x
74 on the Mac (4.2.x is), on Linux (didn't check Qt 4.x there) and
75 probably on other non-DOS platforms, so post the event instead. */
76 QApplication::postEvent (m_pMachineView, new UIRepaintEvent(uX, uY, uW, uH));
77#else
78 /* we're not on the GUI thread, so update() instead of repaint()! */
79 m_pMachineView->viewport()->update(uX - m_pMachineView->contentsX(), uY - m_pMachineView->contentsY(), uW, uH);
80#endif
81 return S_OK;
82}
83
84void UIFrameBufferSDL::paintEvent(QPaintEvent *pEvent)
85{
86 if (m_pScreen)
87 {
88 if (m_pScreen->pixels)
89 {
90 QRect r = pEvent->rect();
91
92 if (m_pSurfVRAM)
93 {
94 SDL_Rect rect = { (Sint16)r.x(), (Sint16)r.y(), (Sint16)r.width(), (Sint16)r.height() };
95 SDL_BlitSurface(m_pSurfVRAM, &rect, m_pScreen, &rect);
96 /** @todo may be: if ((m_pScreen->flags & SDL_HWSURFACE) == 0) */
97 SDL_UpdateRect(m_pScreen, r.x(), r.y(), r.width(), r.height());
98 }
99 else
100 {
101 SDL_UpdateRect(m_pScreen, r.x(), r.y(), r.width(), r.height());
102 }
103 }
104 }
105}
106
107void UIFrameBufferSDL::resizeEvent(UIResizeEvent *pEvent)
108{
109 /* Check whether the guest resolution has not been changed. */
110 bool fSameResolutionRequested = (width() == pEvent->width() && height() == pEvent->height());
111
112 /* Check if the guest VRAM can be used as the source bitmap. */
113 bool bFallback = false;
114
115 Uint32 Rmask = 0;
116 Uint32 Gmask = 0;
117 Uint32 Bmask = 0;
118
119 if (pEvent->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
120 {
121 switch (pEvent->bitsPerPixel())
122 {
123 case 32:
124 Rmask = 0x00FF0000;
125 Gmask = 0x0000FF00;
126 Bmask = 0x000000FF;
127 break;
128 case 24:
129 Rmask = 0x00FF0000;
130 Gmask = 0x0000FF00;
131 Bmask = 0x000000FF;
132 break;
133 case 16:
134 Rmask = 0xF800;
135 Gmask = 0x07E0;
136 Bmask = 0x001F;
137 break;
138 default:
139 /* Unsupported format leads to the indirect buffer */
140 bFallback = true;
141 break;
142 }
143 }
144 else
145 {
146 /* Unsupported format leads to the indirect buffer */
147 bFallback = true;
148 }
149
150 m_width = pEvent->width();
151 m_height = pEvent->height();
152
153 /* Recreate the source surface. */
154 if (m_pSurfVRAM)
155 {
156 SDL_FreeSurface(m_pSurfVRAM);
157 m_pSurfVRAM = NULL;
158 }
159
160 if (!bFallback)
161 {
162 /* It is OK to create the source surface from the guest VRAM. */
163 m_pSurfVRAM = SDL_CreateRGBSurfaceFrom(pEvent->VRAM(), pEvent->width(), pEvent->height(),
164 pEvent->bitsPerPixel(),
165 pEvent->bytesPerLine(),
166 Rmask, Gmask, Bmask, 0);
167 LogFlowFunc(("Created VRAM surface %p\n", m_pSurfVRAM));
168 if (m_pSurfVRAM == NULL)
169 {
170 bFallback = true;
171 }
172 }
173
174 if (fSameResolutionRequested)
175 {
176 LogFlowFunc(("the same resolution requested, skipping the resize.\n"));
177 return;
178 }
179
180 /* close SDL so we can init it again */
181 if (m_pScreen)
182 {
183 X11ScreenSaverSettingsSave();
184 SDL_QuitSubSystem(SDL_INIT_VIDEO);
185 X11ScreenSaverSettingsRestore();
186 m_pScreen = NULL;
187 }
188
189 /*
190 * initialize the SDL library, use its super hack to integrate it with our client window
191 */
192 static char sdlHack[64];
193 LogFlowFunc(("Using client window 0x%08lX to initialize SDL\n", m_pMachineView->viewport()->winId()));
194 /* Note: SDL_WINDOWID must be decimal (not hex) to work on Win32 */
195 sprintf(sdlHack, "SDL_WINDOWID=%lu", m_pMachineView->viewport()->winId());
196 putenv(sdlHack);
197 X11ScreenSaverSettingsSave();
198 int rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
199 X11ScreenSaverSettingsRestore();
200 AssertMsg(rc == 0, ("SDL initialization failed: %s\n", SDL_GetError()));
201 NOREF(rc);
202
203#ifdef Q_WS_X11
204 /* undo signal redirections from SDL, it'd steal keyboard events from us! */
205 signal(SIGINT, SIG_DFL);
206 signal(SIGQUIT, SIG_DFL);
207#endif
208
209 LogFlowFunc(("Setting SDL video mode to %d x %d\n", m_width, m_height));
210
211 /* Pixel format is RGB in any case */
212 m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
213
214 m_pScreen = SDL_SetVideoMode(m_width, m_height, 0, SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL);
215 AssertMsg(m_pScreen, ("SDL video mode could not be set!\n"));
216}
217
218#endif /* VBOX_GUI_USE_SDL */
219
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use