VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Miniport/Helper.cpp@ 5159

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

Do not fail the video if VBoxGuest is not loaded.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1/** @file
2 *
3 * VBoxGuest -- VirtualBox Win 2000/XP guest video driver
4 *
5 * Copyright (C) 2006-2007 innotek GmbH
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License as published by the Free Software Foundation,
11 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
12 * distribution. VirtualBox OSE is distributed in the hope that it will
13 * be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15
16// enable backdoor logging
17//#define LOG_ENABLED
18
19extern "C"
20{
21#include <ntddk.h>
22}
23
24#include <VBox/err.h>
25
26#include <VBox/VBoxGuestLib.h>
27
28/* the video miniport headers not compatible with the NT DDK headers */
29typedef struct _VIDEO_POINTER_ATTRIBUTES
30{
31 ULONG Flags;
32 ULONG Width;
33 ULONG Height;
34 ULONG WidthInBytes;
35 ULONG Enable;
36 SHORT Column;
37 SHORT Row;
38 UCHAR Pixels[1];
39} VIDEO_POINTER_ATTRIBUTES, *PVIDEO_POINTER_ATTRIBUTES;
40#define VIDEO_MODE_COLOR_POINTER 0x04 // 1 if a color hardware pointer is
41 // supported.
42
43#include "Helper.h"
44
45/**
46 * Globals
47 */
48/* note: should not do that but we can't use these datatypes in the global header */
49
50#pragma alloc_text(PAGE, vboxQueryDisplayRequest)
51#pragma alloc_text(PAGE, vboxLikesVideoMode)
52#pragma alloc_text(PAGE, vboxGetHeightReduction)
53#pragma alloc_text(PAGE, vboxQueryPointerPos)
54#pragma alloc_text(PAGE, vboxQueryHostWantsAbsolute)
55#pragma alloc_text(PAGE, vboxQueryWinVersion)
56
57BOOLEAN vboxQueryDisplayRequest(uint32_t *xres, uint32_t *yres, uint32_t *bpp)
58{
59 BOOLEAN bRC = FALSE;
60
61 dprintf(("VBoxVideo::vboxQueryDisplayRequest: xres = %p, yres = %p bpp = %p\n", xres, yres, bpp));
62
63 VMMDevDisplayChangeRequest *req = NULL;
64
65 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevDisplayChangeRequest), VMMDevReq_GetDisplayChangeRequest);
66
67 if (VBOX_FAILURE(rc))
68 {
69 dprintf(("VBoxVideo::vboxQueryDisplayRequest: ERROR allocating request, rc = %Vrc\n", rc));
70 }
71 else
72 {
73 req->eventAck = 0;
74
75 rc = VbglGRPerform (&req->header);
76
77 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
78 {
79 if (xres)
80 *xres = req->xres;
81 if (yres)
82 *yres = req->yres;
83 if (bpp)
84 *bpp = req->bpp;
85 bRC = TRUE;
86 }
87 else
88 {
89 dprintf(("VBoxVideo::vboxQueryDisplayRequest: ERROR querying display request from VMMDev."
90 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
91 }
92
93 VbglGRFree (&req->header);
94 }
95
96 return bRC;
97}
98
99BOOLEAN vboxLikesVideoMode(uint32_t width, uint32_t height, uint32_t bpp)
100{
101 BOOLEAN bRC = FALSE;
102
103 dprintf(("VBoxVideo::vboxLikesVideoMode: width: %d, height: %d, bpp: %d\n", width, height, bpp));
104
105 VMMDevVideoModeSupportedRequest *req = NULL;
106
107 int rc = VbglGRAlloc((VMMDevRequestHeader**)&req, sizeof(VMMDevVideoModeSupportedRequest), VMMDevReq_VideoModeSupported);
108 if (VBOX_FAILURE(rc))
109 {
110 dprintf(("VBoxVideo::vboxLikesVideoMode: ERROR allocating request, rc = %Vrc\n", rc));
111 /* Most likely the VBoxGuest driver is not loaded.
112 * To get at least the video working, report the mode as supported.
113 */
114 bRC = TRUE;
115 }
116 else
117 {
118 req->width = width;
119 req->height = height;
120 req->bpp = bpp;
121 rc = VbglGRPerform(&req->header);
122 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
123 {
124 bRC = req->fSupported;
125 }
126 else
127 {
128 dprintf(("VBoxVideo::vboxLikesVideoMode: ERROR querying video mode supported status from VMMDev."
129 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
130 }
131 VbglGRFree(&req->header);
132 }
133
134 dprintf(("VBoxVideoMode::vboxLikesVideoMode: returning %d\n", bRC));
135 return bRC;
136}
137
138ULONG vboxGetHeightReduction()
139{
140 ULONG retHeight = 0;
141
142 dprintf(("VBoxVideo::vboxGetHeightReduction\n"));
143
144 VMMDevGetHeightReductionRequest *req = NULL;
145
146 int rc = VbglGRAlloc((VMMDevRequestHeader**)&req, sizeof(VMMDevGetHeightReductionRequest), VMMDevReq_GetHeightReduction);
147 if (VBOX_FAILURE(rc))
148 {
149 dprintf(("VBoxVideo::vboxGetHeightReduction: ERROR allocating request, rc = %Vrc\n", rc));
150 }
151 else
152 {
153 rc = VbglGRPerform(&req->header);
154 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
155 {
156 retHeight = (ULONG)req->heightReduction;
157 }
158 else
159 {
160 dprintf(("VBoxVideo::vboxGetHeightReduction: ERROR querying height reduction value from VMMDev."
161 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
162 }
163 VbglGRFree(&req->header);
164 }
165
166 dprintf(("VBoxVideoMode::vboxGetHeightReduction: returning %d\n", retHeight));
167 return retHeight;
168}
169
170static BOOLEAN vboxQueryPointerPosInternal (uint16_t *pointerXPos, uint16_t *pointerYPos)
171{
172 BOOLEAN bRC = FALSE;
173
174 dprintf(("VBoxVideo::vboxQueryPointerPosInternal: pointerXPos = %p, pointerYPos = %p\n", pointerXPos, pointerYPos));
175
176 VMMDevReqMouseStatus *req = NULL;
177
178 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);
179
180 if (VBOX_FAILURE(rc))
181 {
182 dprintf(("VBoxVideo::vboxQueryPointerPosInternal: ERROR allocating request, rc = %Vrc\n", rc));
183 }
184 else
185 {
186 rc = VbglGRPerform (&req->header);
187
188 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
189 {
190 if (req->mouseFeatures & VBOXGUEST_MOUSE_HOST_CAN_ABSOLUTE)
191 {
192 if (pointerXPos)
193 {
194 *pointerXPos = req->pointerXPos;
195 }
196
197 if (pointerYPos)
198 {
199 *pointerYPos = req->pointerYPos;
200 }
201
202 bRC = TRUE;
203 }
204 }
205 else
206 {
207 dprintf(("VBoxVideo::vboxQueryPointerPosInternal: ERROR querying mouse capabilities from VMMDev."
208 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
209 }
210
211 VbglGRFree (&req->header);
212 }
213
214 return bRC;
215}
216
217/**
218 * Return the current absolute mouse position in normalized format
219 * (between 0 and 0xFFFF).
220 *
221 * @returns BOOLEAN success indicator
222 * @param pointerXPos address of result variable for x pos
223 * @param pointerYPos address of result variable for y pos
224 */
225BOOLEAN vboxQueryPointerPos(uint16_t *pointerXPos, uint16_t *pointerYPos)
226{
227 if (!pointerXPos || !pointerYPos)
228 {
229 return FALSE;
230 }
231
232 return vboxQueryPointerPosInternal (pointerXPos, pointerYPos);
233}
234
235/**
236 * Returns whether the host wants us to take absolute coordinates.
237 *
238 * @returns BOOLEAN TRUE if the host wants to send absolute coordinates.
239 */
240BOOLEAN vboxQueryHostWantsAbsolute (void)
241{
242 return vboxQueryPointerPosInternal (NULL, NULL);
243}
244
245winVersion_t vboxQueryWinVersion()
246{
247 static winVersion_t winVersion = UNKNOWN_WINVERSION;
248 ULONG majorVersion;
249 ULONG minorVersion;
250 ULONG buildNumber;
251
252 if (winVersion != UNKNOWN_WINVERSION)
253 return winVersion;
254
255 PsGetVersion(&majorVersion, &minorVersion, &buildNumber, NULL);
256
257 dprintf(("VBoxVideo::vboxQueryWinVersion: running on Windows NT version %d.%d, build %d\n",
258 majorVersion, minorVersion, buildNumber));
259
260 if (majorVersion >= 5)
261 {
262 if (minorVersion >= 1)
263 {
264 winVersion = WINXP;
265 } else
266 {
267 winVersion = WIN2K;
268 }
269 } else
270 if (majorVersion == 4)
271 {
272 winVersion = WINNT4;
273 } else
274 {
275 dprintf(("VBoxVideo::vboxQueryWinVersion: NT4 required!\n"));
276 }
277 return winVersion;
278}
279
280/**
281 * Sends the pointer shape to the VMMDev
282 *
283 * @returns success indicator
284 * @param pointerAttr pointer description
285 */
286BOOLEAN vboxUpdatePointerShape(PVIDEO_POINTER_ATTRIBUTES pointerAttr, uint32_t cbLength)
287{
288 uint32_t cbData = 0;
289
290 if (pointerAttr->Enable & VBOX_MOUSE_POINTER_SHAPE)
291 {
292 cbData = ((((pointerAttr->Width + 7) / 8) * pointerAttr->Height + 3) & ~3)
293 + pointerAttr->Width * 4 * pointerAttr->Height;
294 }
295
296 if (cbData > cbLength - sizeof(VIDEO_POINTER_ATTRIBUTES))
297 {
298 dprintf(("vboxUpdatePointerShape: calculated pointer data size is too big (%d bytes, limit %d)\n",
299 cbData, cbLength - sizeof(VIDEO_POINTER_ATTRIBUTES)));
300 return FALSE;
301 }
302
303 BOOLEAN bRC = FALSE;
304
305 VMMDevReqMousePointer *req = NULL;
306
307 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMousePointer) + cbData, VMMDevReq_SetPointerShape);
308
309 if (VBOX_FAILURE(rc))
310 {
311 dprintf(("VBoxVideo::vboxUpdatePointerShape: ERROR allocating request, rc = %Vrc\n", rc));
312 }
313 else
314 {
315 dprintf(("VBoxVideo::vboxUpdatePointerShape: req->u32Version = %08X\n", req->header.version));
316
317 /* We have our custom flags in the field */
318 req->fFlags = pointerAttr->Enable & 0xFFFF;
319
320 /* Even if pointer is invisible, we have to pass following data,
321 * so host could create the pointer with initial status - invisible
322 */
323 req->xHot = (pointerAttr->Enable >> 16) & 0xFF;
324 req->yHot = (pointerAttr->Enable >> 24) & 0xFF;
325 req->width = pointerAttr->Width;
326 req->height = pointerAttr->Height;
327
328 if (req->fFlags & VBOX_MOUSE_POINTER_SHAPE)
329 {
330 /* copy the actual pointer data */
331 memcpy (req->pointerData, pointerAttr->Pixels, cbData);
332 }
333
334 rc = VbglGRPerform (&req->header);
335
336 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
337 {
338 bRC = TRUE;
339 }
340 else
341 {
342 dprintf(("VBoxVideo::vboxUpdatePointerShape: ERROR querying mouse capabilities from VMMDev."
343 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
344 }
345
346 dprintf(("VBoxVideo::vboxUpdatePointerShape: req->u32Version = %08X\n", req->header.version));
347
348 VbglGRFree (&req->header);
349 }
350
351 return bRC;
352}
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