VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

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

© 2023 Oracle
ContactPrivacy policyTerms of Use