VirtualBox

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

Last change on this file since 26069 was 23221, checked in by vboxsync, 15 years ago

VBoxVideo: Logging.

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