VirtualBox

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

Last change on this file since 3539 was 2981, checked in by vboxsync, 17 years ago

InnoTek -> innotek: all the headers and comments.

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