VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxHeadless/Framebuffer.cpp@ 51436

Last change on this file since 51436 was 51436, checked in by vboxsync, 11 years ago

Main,Frontends: IDisplay provides the guest screen bitmap to frontends.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/** @file
2 *
3 * VBox Remote Desktop Framebuffer
4 */
5
6/*
7 * Copyright (C) 2010 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#include "Framebuffer.h"
19
20#include <iprt/alloc.h>
21
22#define LOG_GROUP LOG_GROUP_GUI
23#include <VBox/log.h>
24
25/*
26 * VRDP server frame buffer
27 */
28
29#ifdef VBOX_WITH_XPCOM
30#include <nsMemory.h>
31NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VRDPFramebuffer, IFramebuffer)
32NS_DECL_CLASSINFO(VRDPFramebuffer)
33#endif
34
35VRDPFramebuffer::VRDPFramebuffer()
36{
37#if defined (RT_OS_WINDOWS)
38 refcnt = 0;
39#endif /* RT_OS_WINDOWS */
40
41 mBuffer = NULL;
42
43 RTCritSectInit (&m_CritSect);
44}
45
46VRDPFramebuffer::~VRDPFramebuffer()
47{
48 if (mBuffer)
49 {
50 RTMemFree (mBuffer);
51 }
52
53 RTCritSectDelete (&m_CritSect);
54}
55
56STDMETHODIMP VRDPFramebuffer::COMGETTER(Width)(ULONG *width)
57{
58 if (!width)
59 return E_INVALIDARG;
60 *width = mWidth;
61 return S_OK;
62}
63
64STDMETHODIMP VRDPFramebuffer::COMGETTER(Height)(ULONG *height)
65{
66 if (!height)
67 return E_INVALIDARG;
68 *height = mHeight;
69 return S_OK;
70}
71
72STDMETHODIMP VRDPFramebuffer::Lock()
73{
74 RTCritSectEnter (&m_CritSect);
75 return S_OK;
76}
77
78STDMETHODIMP VRDPFramebuffer::Unlock()
79{
80 RTCritSectLeave (&m_CritSect);
81 return S_OK;
82}
83
84STDMETHODIMP VRDPFramebuffer::COMGETTER(Address)(BYTE **address)
85{
86 if (!address)
87 return E_INVALIDARG;
88 *address = mScreen;
89 return S_OK;
90}
91
92STDMETHODIMP VRDPFramebuffer::COMGETTER(BitsPerPixel)(ULONG *bitsPerPixel)
93{
94 if (!bitsPerPixel)
95 return E_INVALIDARG;
96 *bitsPerPixel = mBitsPerPixel;
97 return S_OK;
98}
99
100STDMETHODIMP VRDPFramebuffer::COMGETTER(BytesPerLine)(ULONG *bytesPerLine)
101{
102 if (!bytesPerLine)
103 return E_INVALIDARG;
104 *bytesPerLine = mBytesPerLine;
105 return S_OK;
106}
107
108STDMETHODIMP VRDPFramebuffer::COMGETTER(PixelFormat) (ULONG *pixelFormat)
109{
110 if (!pixelFormat)
111 return E_POINTER;
112 *pixelFormat = mPixelFormat;
113 return S_OK;
114}
115
116STDMETHODIMP VRDPFramebuffer::COMGETTER(UsesGuestVRAM) (BOOL *usesGuestVRAM)
117{
118 if (!usesGuestVRAM)
119 return E_POINTER;
120 *usesGuestVRAM = mUsesGuestVRAM;
121 return S_OK;
122}
123
124STDMETHODIMP VRDPFramebuffer::COMGETTER(HeightReduction) (ULONG *heightReduction)
125{
126 if (!heightReduction)
127 return E_POINTER;
128 /* no reduction at all */
129 *heightReduction = 0;
130 return S_OK;
131}
132
133STDMETHODIMP VRDPFramebuffer::COMGETTER(Overlay) (IFramebufferOverlay **aOverlay)
134{
135 if (!aOverlay)
136 return E_POINTER;
137 /* overlays are not yet supported */
138 *aOverlay = 0;
139 return S_OK;
140}
141
142STDMETHODIMP VRDPFramebuffer::COMGETTER(WinId) (LONG64 *winId)
143{
144 if (!winId)
145 return E_POINTER;
146 *winId = 0;
147 return S_OK;
148}
149
150STDMETHODIMP VRDPFramebuffer::NotifyUpdate(ULONG x, ULONG y,
151 ULONG w, ULONG h)
152{
153 return S_OK;
154}
155
156STDMETHODIMP VRDPFramebuffer::RequestResize(ULONG aScreenId, ULONG pixelFormat, BYTE *vram,
157 ULONG bitsPerPixel, ULONG bytesPerLine,
158 ULONG w, ULONG h,
159 BOOL *finished)
160{
161 /* Agree to requested format for LFB modes and use guest VRAM directly, thus avoiding
162 * unnecessary memcpy in VGA device.
163 */
164
165 Log(("pixelFormat = %08X, vram = %p, bpp = %d, bpl = 0x%08X, %dx%d\n",
166 pixelFormat, vram, bitsPerPixel, bytesPerLine, w, h));
167
168 /* Free internal buffer. */
169 if (mBuffer)
170 {
171 RTMemFree (mBuffer);
172 mBuffer = NULL;
173 }
174
175 mUsesGuestVRAM = FALSE;
176
177 mWidth = w;
178 mHeight = h;
179
180 if (pixelFormat == FramebufferPixelFormat_FOURCC_RGB)
181 {
182 switch (bitsPerPixel)
183 {
184 case 32:
185 case 24:
186 case 16:
187 mUsesGuestVRAM = TRUE;
188 break;
189
190 default:
191 break;
192 }
193 }
194
195 if (mUsesGuestVRAM)
196 {
197 mScreen = vram;
198 mBitsPerPixel = bitsPerPixel;
199 mBytesPerLine = bytesPerLine;
200 mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
201
202 Log (("Using guest VRAM directly, %d BPP\n", mBitsPerPixel));
203 }
204 else
205 {
206 mBitsPerPixel = 32;
207 mBytesPerLine = w * 4; /* Here we have 32 BPP */
208
209 if (mBytesPerLine > 0 && h > 0) /* Check for nul dimensions. */
210 {
211 mBuffer = RTMemAllocZ(mBytesPerLine * h);
212 }
213
214 mScreen = (uint8_t *)mBuffer;
215
216 Log(("Using internal buffer, %d BPP\n", mBitsPerPixel));
217 }
218
219 if (!mScreen)
220 {
221 Log(("No screen. BPP = %d, w = %d, h = %d!!!\n", mBitsPerPixel, w, h));
222
223 /* Just reset everything. */
224 mPixelFormat = FramebufferPixelFormat_Opaque;
225
226 mWidth = 0;
227 mHeight = 0;
228 mBitsPerPixel = 0;
229 mBytesPerLine = 0;
230 mUsesGuestVRAM = FALSE;
231 }
232
233 /* Inform the caller that the operation was successful. */
234
235 if (finished)
236 *finished = TRUE;
237
238 return S_OK;
239}
240
241extern ComPtr<IDisplay> display;
242
243STDMETHODIMP VRDPFramebuffer::NotifyChange(ULONG aScreenId,
244 ULONG aXOrigin,
245 ULONG aYOrigin,
246 ULONG aWidth,
247 ULONG aHeight)
248{
249 LogRelFlow(("NotifyChange: %d %d,%d %dx%d\n",
250 aScreenId, aXOrigin, aYOrigin, aWidth, aHeight));
251
252 HRESULT hr = S_OK;
253
254 hr = display->QuerySourceBitmap(aScreenId, mpSourceBitmap.asOutParam());
255 if (SUCCEEDED(hr))
256 {
257 BYTE *pAddress = NULL;
258 ULONG ulWidth = 0;
259 ULONG ulHeight = 0;
260 ULONG ulBitsPerPixel = 0;
261 ULONG ulBytesPerLine = 0;
262 ULONG ulPixelFormat = 0;
263
264 hr = mpSourceBitmap->QueryBitmapInfo(&pAddress,
265 &ulWidth,
266 &ulHeight,
267 &ulBitsPerPixel,
268 &ulBytesPerLine,
269 &ulPixelFormat);
270
271 if (SUCCEEDED(hr))
272 {
273 mScreen = pAddress;
274 mWidth = ulWidth;
275 mHeight = ulHeight;
276 mBitsPerPixel = ulBitsPerPixel;
277 mBytesPerLine = ulBytesPerLine;
278 mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
279 mUsesGuestVRAM = TRUE;
280
281 Log(("Using screen bitmap, %d BPP\n", mBitsPerPixel));
282 }
283 }
284
285 if (FAILED(hr))
286 {
287 /* Just reset everything. */
288 mScreen = NULL;
289 mWidth = 0;
290 mHeight = 0;
291 mBitsPerPixel = 0;
292 mBytesPerLine = 0;
293 mPixelFormat = FramebufferPixelFormat_Opaque;
294 mUsesGuestVRAM = FALSE;
295
296 Log(("No screen w = %d, h = %d!!!\n", aWidth, aHeight));
297 }
298
299 return hr;
300}
301
302/**
303 * Returns whether we like the given video mode.
304 *
305 * @returns COM status code
306 * @param width video mode width in pixels
307 * @param height video mode height in pixels
308 * @param bpp video mode bit depth in bits per pixel
309 * @param supported pointer to result variable
310 */
311STDMETHODIMP VRDPFramebuffer::VideoModeSupported(ULONG width, ULONG height, ULONG bpp, BOOL *supported)
312{
313 if (!supported)
314 return E_POINTER;
315 *supported = TRUE;
316 return S_OK;
317}
318
319STDMETHODIMP VRDPFramebuffer::GetVisibleRegion(BYTE *aRectangles, ULONG aCount,
320 ULONG *aCountCopied)
321{
322 PRTRECT rects = (PRTRECT)aRectangles;
323
324 if (!rects)
325 return E_POINTER;
326
327 /// @todo
328
329 NOREF(aCount);
330 NOREF(aCountCopied);
331
332 return S_OK;
333}
334
335STDMETHODIMP VRDPFramebuffer::SetVisibleRegion(BYTE *aRectangles, ULONG aCount)
336{
337 PRTRECT rects = (PRTRECT)aRectangles;
338
339 if (!rects)
340 return E_POINTER;
341
342 /// @todo
343
344 NOREF(aCount);
345
346 return S_OK;
347}
348
349STDMETHODIMP VRDPFramebuffer::ProcessVHWACommand(BYTE *pCommand)
350{
351 return E_NOTIMPL;
352}
353
354STDMETHODIMP VRDPFramebuffer::Notify3DEvent(ULONG uType, BYTE *pReserved)
355{
356 return E_NOTIMPL;
357}
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