VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxFB/Framebuffer.cpp@ 24777

Last change on this file since 24777 was 21771, checked in by vboxsync, 15 years ago

Frontends/VBoxFB: make it build again and clean up the obvious parts which are not using the current conventions. Still untested.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/** @file
2 *
3 * VBox frontends: Framebuffer (FB, DirectFB):
4 * Implementation of VBoxDirectFB class
5 */
6
7/*
8 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
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 (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#include "VBoxFB.h"
24#include "Framebuffer.h"
25
26NS_IMPL_ISUPPORTS1_CI(VBoxDirectFB, IFramebuffer)
27NS_DECL_CLASSINFO(VBoxDirectFB)
28
29VBoxDirectFB::VBoxDirectFB(IDirectFB *aDFB, IDirectFBSurface *aSurface)
30{
31 dfb = aDFB;
32 surface = aSurface;
33 fbInternalSurface = NULL;
34 fbBufferAddress = NULL;
35 // initialize screen dimensions
36 DFBCHECK(surface->GetSize(surface, (int*)&screenWidth, (int*)&screenHeight));
37 fbWidth = 640;
38 fbHeight = 480;
39 if ((screenWidth != fbWidth) || (screenHeight != fbHeight))
40 {
41 createSurface(fbWidth, fbHeight);
42 }
43 fbSurfaceLocked = 0;
44 PRUint32 bitsPerPixel;
45 GetBitsPerPixel(&bitsPerPixel);
46 fbPitch = fbWidth * (bitsPerPixel / 8);
47}
48
49VBoxDirectFB::~VBoxDirectFB()
50{
51 // free our internal surface
52 if (fbInternalSurface)
53 {
54 DFBCHECK(fbInternalSurface->Release(fbInternalSurface));
55 fbInternalSurface = NULL;
56 }
57}
58
59NS_IMETHODIMP VBoxDirectFB::GetWidth(uint32 *width)
60{
61 if (!width)
62 return NS_ERROR_INVALID_POINTER;
63 *width = fbWidth;
64 return NS_OK;
65}
66
67NS_IMETHODIMP VBoxDirectFB::GetHeight(PRUint32 *height)
68{
69 if (!height)
70 return NS_ERROR_INVALID_POINTER;
71 *height = fbHeight;
72 return NS_OK;
73}
74
75NS_IMETHODIMP VBoxDirectFB::Lock()
76{
77 // do we have an internal framebuffer?
78 if (fbInternalSurface)
79 {
80 if (fbSurfaceLocked)
81 {
82 printf("internal surface already locked!\n");
83 } else
84 {
85 DFBCHECK(fbInternalSurface->Lock(fbInternalSurface,
86 (DFBSurfaceLockFlags)(DSLF_WRITE | DSLF_READ),
87 &fbBufferAddress, (int*)&fbPitch));
88 fbSurfaceLocked = 1;
89 }
90 } else
91 {
92 if (fbSurfaceLocked)
93 {
94 printf("surface already locked!\n");
95 } else
96 {
97 DFBCHECK(surface->Lock(surface, (DFBSurfaceLockFlags)(DSLF_WRITE | DSLF_READ),
98 &fbBufferAddress, (int*)&fbPitch));
99 fbSurfaceLocked = 1;
100 }
101 }
102 return NS_OK;
103}
104
105NS_IMETHODIMP VBoxDirectFB::Unlock()
106{
107 // do we have an internal framebuffer?
108 if (fbInternalSurface)
109 {
110 if (!fbSurfaceLocked)
111 {
112 printf("internal surface not locked!\n");
113 } else
114 {
115 DFBCHECK(fbInternalSurface->Unlock(fbInternalSurface));
116 fbSurfaceLocked = 0;
117 }
118 } else
119 {
120 if (!fbSurfaceLocked)
121 {
122 printf("surface not locked!\n");
123 } else
124 {
125 DFBCHECK(surface->Unlock(surface));
126 fbSurfaceLocked = 0;
127 }
128 }
129 return NS_OK;
130}
131
132NS_IMETHODIMP VBoxDirectFB::GetAddress(PRUint8 **address)
133{
134 if (!address)
135 return NS_ERROR_INVALID_POINTER;
136 *address = (PRUint8 *)fbBufferAddress;
137 return NS_OK;
138}
139
140NS_IMETHODIMP VBoxDirectFB::GetBitsPerPixel(PRUint32 *bitsPerPixel)
141{
142 if (!bitsPerPixel)
143 return NS_ERROR_INVALID_POINTER;
144 DFBSurfacePixelFormat pixelFormat;
145 DFBCHECK(surface->GetPixelFormat(surface, &pixelFormat));
146 switch (pixelFormat)
147 {
148 case DSPF_RGB16:
149 *bitsPerPixel = 16;
150 break;
151 case DSPF_RGB24:
152 *bitsPerPixel = 24;
153 break;
154 case DSPF_RGB32:
155 *bitsPerPixel = 32;
156 break;
157 default:
158 // not good! @@@AH do something!
159 *bitsPerPixel = 16;
160 }
161 return NS_OK;
162}
163
164NS_IMETHODIMP VBoxDirectFB::GetBytesPerLine(PRUint32 *bytesPerLine)
165{
166 if (!bytesPerLine)
167 return NS_ERROR_INVALID_POINTER;
168 *bytesPerLine = fbPitch;
169 return NS_OK;
170}
171
172NS_IMETHODIMP VBoxDirectFB::GetPixelFormat (PRUint32 *pixelFormat)
173{
174 if (!pixelFormat)
175 return NS_ERROR_INVALID_POINTER;
176 *pixelFormat = FramebufferPixelFormat_FOURCC_RGB;
177 return NS_OK;
178}
179
180NS_IMETHODIMP VBoxDirectFB::GetUsesGuestVRAM (PRBool *usesGuestVRAM)
181{
182 if (!usesGuestVRAM)
183 return NS_ERROR_INVALID_POINTER;
184 *usesGuestVRAM = false;
185 return NS_OK;
186}
187
188NS_IMETHODIMP VBoxDirectFB::GetHeightReduction(PRUint32 *heightReduction)
189{
190 if (!heightReduction)
191 return NS_ERROR_INVALID_POINTER;
192 *heightReduction = 0;
193 return NS_OK;
194}
195
196NS_IMETHODIMP VBoxDirectFB::GetOverlay(IFramebufferOverlay **overlay)
197{
198 if (!overlay)
199 return NS_ERROR_INVALID_POINTER;
200 /* Not yet implemented */
201 *overlay = 0;
202 return NS_OK;
203}
204
205NS_IMETHODIMP VBoxDirectFB::GetWinId(PRUint64 *winId)
206{
207 if (!winId)
208 return NS_ERROR_INVALID_POINTER;
209 *winId = 0;
210 return NS_OK;
211}
212
213NS_IMETHODIMP VBoxDirectFB::NotifyUpdate(PRUint32 x, PRUint32 y,
214 PRUint32 w, PRUint32 h)
215{
216 // we only need to take action if we have a memory framebuffer
217 if (fbInternalSurface)
218 {
219 //printf("blitting %u %u %u %u...\n", x, y, w, h);
220 DFBRectangle blitRectangle;
221 blitRectangle.x = x;
222 blitRectangle.y = y;
223 blitRectangle.w = w;
224 blitRectangle.h = h;
225 if (scaleGuest)
226 {
227 DFBRectangle hostRectangle;
228 float factorX = (float)screenWidth / (float)fbWidth;
229 float factorY = (float)screenHeight / (float)fbHeight;
230 hostRectangle.x = (int)((float)blitRectangle.x * factorX);
231 hostRectangle.y = (int)((float)blitRectangle.y * factorY);
232 hostRectangle.w = (int)((float)blitRectangle.w * factorX);
233 hostRectangle.h = (int)((float)blitRectangle.h * factorY);
234 DFBCHECK(surface->StretchBlit(surface, fbInternalSurface,
235 &blitRectangle, &hostRectangle));
236 }
237 else
238 {
239 DFBCHECK(surface->Blit(surface, fbInternalSurface, &blitRectangle,
240 x + ((screenWidth - fbWidth) / 2),
241 y + (screenHeight - fbHeight) / 2));
242 }
243 }
244 return NS_OK;
245}
246
247NS_IMETHODIMP VBoxDirectFB::RequestResize(PRUint32 aScreenId, PRUint32 pixelFormat, PRUint8 *vram,
248 PRUint32 bitsPerPixel, PRUint32 bytesPerLine,
249 PRUint32 w, PRUint32 h,
250 PRBool *finished)
251{
252 uint32_t needsLocking = fbSurfaceLocked;
253
254 printf("RequestResize: aScreenId = %d, pixelFormat = %d, vram = %p, bitsPerPixel = %d, bytesPerLine = %d, w = %d, h = %d, fbSurfaceLocked = %d\n", aScreenId, pixelFormat, vram, bitsPerPixel, bytesPerLine, w, h, fbSurfaceLocked);
255
256 // we can't work with a locked surface
257 if (needsLocking)
258 {
259 Unlock();
260 }
261
262 // in any case we gotta free a possible internal framebuffer
263 if (fbInternalSurface)
264 {
265 printf("freeing internal surface\n");
266 fbInternalSurface->Release(fbInternalSurface);
267 fbInternalSurface = NULL;
268 }
269
270 // check if we have a fixed host video mode
271 if (useFixedVideoMode)
272 {
273 // does the current video mode differ from what the guest wants?
274 if ((screenWidth == w) && (screenHeight == h))
275 {
276 printf("requested guest mode matches current host mode!\n");
277 } else
278 {
279 createSurface(w, h);
280 }
281 } else
282 {
283 // we adopt to the guest resolution or the next higher that is available
284 int32_t bestMode = getBestVideoMode(w, h, bitsPerPixel);
285 if (bestMode == -1)
286 {
287 // oh oh oh oh
288 printf("RequestResize: no suitable mode found!\n");
289 return NS_OK;
290 }
291
292 // does the mode differ from what we wanted?
293 if ((videoModes[bestMode].width != w) || (videoModes[bestMode].height != h) ||
294 (videoModes[bestMode].bpp != bitsPerPixel))
295 {
296 printf("The mode does not fit exactly!\n");
297 createSurface(w, h);
298 } else
299 {
300 printf("The mode fits exactly!\n");
301 }
302 // switch to this mode
303 DFBCHECK(dfb->SetVideoMode(dfb, videoModes[bestMode].width, videoModes[bestMode].height,
304 videoModes[bestMode].bpp));
305 }
306
307 // update dimensions to the new size
308 fbWidth = w;
309 fbHeight = h;
310
311 // clear the screen
312 DFBCHECK(surface->Clear(surface, 0, 0, 0, 0));
313
314 // if it was locked before the resize, obtain the lock again
315 if (needsLocking)
316 {
317 Lock();
318 }
319
320 if (finished)
321 *finished = true;
322 return NS_OK;
323}
324
325NS_IMETHODIMP VBoxDirectFB::VideoModeSupported(PRUint32 w, PRUint32 h, PRUint32 bpp, PRBool *supported)
326{
327 if (!supported)
328 return NS_ERROR_INVALID_POINTER;
329 *supported = true;
330 return NS_OK;
331}
332
333NS_IMETHODIMP VBoxDirectFB::GetVisibleRegion(PRUint8 *rectangles, PRUint32 count, PRUint32 *countCopied)
334{
335 PRTRECT rects = (PRTRECT)rectangles;
336
337 if (!rects || !countCopied)
338 return NS_ERROR_INVALID_POINTER;
339 /** @todo */
340 *countCopied = 0;
341 return NS_OK;
342}
343
344NS_IMETHODIMP VBoxDirectFB::SetVisibleRegion(PRUint8 *rectangles, PRUint32 count)
345{
346 PRTRECT rects = (PRTRECT)rectangles;
347
348 if (!rects)
349 return NS_ERROR_INVALID_POINTER;
350 /** @todo */
351 return NS_OK;
352}
353
354NS_IMETHODIMP VBoxDirectFB::ProcessVHWACommand(PRUint8 *command)
355{
356 return NS_ERROR_NOT_IMPLEMENTED;
357}
358
359int VBoxDirectFB::createSurface(uint32_t w, uint32_t h)
360{
361 printf("creating a new internal surface, w = %u, h = %u...\n", w, h);
362 // create a surface
363 DFBSurfaceDescription dsc;
364 DFBSurfacePixelFormat pixelFormat;
365 dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
366 dsc.width = w;
367 dsc.height = h;
368 DFBCHECK(surface->GetPixelFormat(surface, &pixelFormat));
369 dsc.pixelformat = pixelFormat;
370 DFBCHECK(dfb->CreateSurface(dfb, &dsc, &fbInternalSurface));
371 return 0;
372}
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