VirtualBox

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

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

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 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 }
112 else
113 {
114 req->width = width;
115 req->height = height;
116 req->bpp = bpp;
117 rc = VbglGRPerform(&req->header);
118 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
119 {
120 bRC = req->fSupported;
121 }
122 else
123 {
124 dprintf(("VBoxVideo::vboxLikesVideoMode: ERROR querying video mode supported status from VMMDev."
125 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
126 }
127 VbglGRFree(&req->header);
128 }
129
130 dprintf(("VBoxVideoMode::vboxLikesVideoMode: returning %d\n", bRC));
131 return bRC;
132}
133
134ULONG vboxGetHeightReduction()
135{
136 ULONG retHeight = 0;
137
138 dprintf(("VBoxVideo::vboxGetHeightReduction\n"));
139
140 VMMDevGetHeightReductionRequest *req = NULL;
141
142 int rc = VbglGRAlloc((VMMDevRequestHeader**)&req, sizeof(VMMDevGetHeightReductionRequest), VMMDevReq_GetHeightReduction);
143 if (VBOX_FAILURE(rc))
144 {
145 dprintf(("VBoxVideo::vboxGetHeightReduction: ERROR allocating request, rc = %Vrc\n", rc));
146 }
147 else
148 {
149 rc = VbglGRPerform(&req->header);
150 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
151 {
152 retHeight = (ULONG)req->heightReduction;
153 }
154 else
155 {
156 dprintf(("VBoxVideo::vboxGetHeightReduction: ERROR querying height reduction value from VMMDev."
157 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
158 }
159 VbglGRFree(&req->header);
160 }
161
162 dprintf(("VBoxVideoMode::vboxGetHeightReduction: returning %d\n", retHeight));
163 return retHeight;
164}
165
166static BOOLEAN vboxQueryPointerPosInternal (uint16_t *pointerXPos, uint16_t *pointerYPos)
167{
168 BOOLEAN bRC = FALSE;
169
170 dprintf(("VBoxVideo::vboxQueryPointerPosInternal: pointerXPos = %p, pointerYPos = %p\n", pointerXPos, pointerYPos));
171
172 VMMDevReqMouseStatus *req = NULL;
173
174 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);
175
176 if (VBOX_FAILURE(rc))
177 {
178 dprintf(("VBoxVideo::vboxQueryPointerPosInternal: ERROR allocating request, rc = %Vrc\n", rc));
179 }
180 else
181 {
182 rc = VbglGRPerform (&req->header);
183
184 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
185 {
186 if (req->mouseFeatures & VBOXGUEST_MOUSE_HOST_CAN_ABSOLUTE)
187 {
188 if (pointerXPos)
189 {
190 *pointerXPos = req->pointerXPos;
191 }
192
193 if (pointerYPos)
194 {
195 *pointerYPos = req->pointerYPos;
196 }
197
198 bRC = TRUE;
199 }
200 }
201 else
202 {
203 dprintf(("VBoxVideo::vboxQueryPointerPosInternal: ERROR querying mouse capabilities from VMMDev."
204 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
205 }
206
207 VbglGRFree (&req->header);
208 }
209
210 return bRC;
211}
212
213/**
214 * Return the current absolute mouse position in normalized format
215 * (between 0 and 0xFFFF).
216 *
217 * @returns BOOLEAN success indicator
218 * @param pointerXPos address of result variable for x pos
219 * @param pointerYPos address of result variable for y pos
220 */
221BOOLEAN vboxQueryPointerPos(uint16_t *pointerXPos, uint16_t *pointerYPos)
222{
223 if (!pointerXPos || !pointerYPos)
224 {
225 return FALSE;
226 }
227
228 return vboxQueryPointerPosInternal (pointerXPos, pointerYPos);
229}
230
231/**
232 * Returns whether the host wants us to take absolute coordinates.
233 *
234 * @returns BOOLEAN TRUE if the host wants to send absolute coordinates.
235 */
236BOOLEAN vboxQueryHostWantsAbsolute (void)
237{
238 return vboxQueryPointerPosInternal (NULL, NULL);
239}
240
241winVersion_t vboxQueryWinVersion()
242{
243 static winVersion_t winVersion = UNKNOWN_WINVERSION;
244 ULONG majorVersion;
245 ULONG minorVersion;
246 ULONG buildNumber;
247
248 if (winVersion != UNKNOWN_WINVERSION)
249 return winVersion;
250
251 PsGetVersion(&majorVersion, &minorVersion, &buildNumber, NULL);
252
253 dprintf(("VBoxVideo::vboxQueryWinVersion: running on Windows NT version %d.%d, build %d\n",
254 majorVersion, minorVersion, buildNumber));
255
256 if (majorVersion >= 5)
257 {
258 if (minorVersion >= 1)
259 {
260 winVersion = WINXP;
261 } else
262 {
263 winVersion = WIN2K;
264 }
265 } else
266 if (majorVersion == 4)
267 {
268 winVersion = WINNT4;
269 } else
270 {
271 dprintf(("VBoxVideo::vboxQueryWinVersion: NT4 required!\n"));
272 }
273 return winVersion;
274}
275
276/**
277 * Sends the pointer shape to the VMMDev
278 *
279 * @returns success indicator
280 * @param pointerAttr pointer description
281 */
282BOOLEAN vboxUpdatePointerShape(PVIDEO_POINTER_ATTRIBUTES pointerAttr, uint32_t cbLength)
283{
284 uint32_t cbData = 0;
285
286 if (pointerAttr->Enable & VBOX_MOUSE_POINTER_SHAPE)
287 {
288 cbData = ((((pointerAttr->Width + 7) / 8) * pointerAttr->Height + 3) & ~3)
289 + pointerAttr->Width * 4 * pointerAttr->Height;
290 }
291
292 if (cbData > cbLength - sizeof(VIDEO_POINTER_ATTRIBUTES))
293 {
294 dprintf(("vboxUpdatePointerShape: calculated pointer data size is too big (%d bytes, limit %d)\n",
295 cbData, cbLength - sizeof(VIDEO_POINTER_ATTRIBUTES)));
296 return FALSE;
297 }
298
299 BOOLEAN bRC = FALSE;
300
301 VMMDevReqMousePointer *req = NULL;
302
303 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMousePointer) + cbData, VMMDevReq_SetPointerShape);
304
305 if (VBOX_FAILURE(rc))
306 {
307 dprintf(("VBoxVideo::vboxUpdatePointerShape: ERROR allocating request, rc = %Vrc\n", rc));
308 }
309 else
310 {
311 dprintf(("VBoxVideo::vboxUpdatePointerShape: req->u32Version = %08X\n", req->header.version));
312
313 /* We have our custom flags in the field */
314 req->fFlags = pointerAttr->Enable & 0xFFFF;
315
316 /* Even if pointer is invisible, we have to pass following data,
317 * so host could create the pointer with initial status - invisible
318 */
319 req->xHot = (pointerAttr->Enable >> 16) & 0xFF;
320 req->yHot = (pointerAttr->Enable >> 24) & 0xFF;
321 req->width = pointerAttr->Width;
322 req->height = pointerAttr->Height;
323
324 if (req->fFlags & VBOX_MOUSE_POINTER_SHAPE)
325 {
326 /* copy the actual pointer data */
327 memcpy (req->pointerData, pointerAttr->Pixels, cbData);
328 }
329
330 rc = VbglGRPerform (&req->header);
331
332 if (VBOX_SUCCESS(rc) && VBOX_SUCCESS(req->header.rc))
333 {
334 bRC = TRUE;
335 }
336 else
337 {
338 dprintf(("VBoxVideo::vboxUpdatePointerShape: ERROR querying mouse capabilities from VMMDev."
339 "rc = %Vrc, VMMDev rc = %Vrc\n", rc, req->header.rc));
340 }
341
342 dprintf(("VBoxVideo::vboxUpdatePointerShape: req->u32Version = %08X\n", req->header.version));
343
344 VbglGRFree (&req->header);
345 }
346
347 return bRC;
348}
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