VirtualBox

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

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

Additions/win: no need to check the rc of the request header after VbglGRPerform()

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