VirtualBox

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

Last change on this file since 32930 was 32831, checked in by vboxsync, 14 years ago

VMMDev: renamed two capabilities

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