VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp@ 39870

Last change on this file since 39870 was 37423, checked in by vboxsync, 14 years ago

Ran the source code massager (scm).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1/* $Id: VBoxDispMini.cpp 37423 2011-06-12 18:37:56Z vboxsync $ */
2
3/** @file
4 * VBox XPDM Display driver, helper functions which interacts with our miniport driver
5 */
6
7/*
8 * Copyright (C) 2011 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxDisp.h"
20#include "VBoxDispMini.h"
21#include <iprt/asm.h>
22
23/* Returns if given video mode is supported by display driver */
24static BOOL VBoxDispVideoModeSupported(const PVIDEO_MODE_INFORMATION pMode)
25{
26 if ((pMode->NumberOfPlanes==1)
27 && (pMode->AttributeFlags & VIDEO_MODE_GRAPHICS)
28 && !(pMode->AttributeFlags & VIDEO_MODE_BANKED)
29 && (pMode->BitsPerPlane==8 || pMode->BitsPerPlane==16 || pMode->BitsPerPlane==24 || pMode->BitsPerPlane==32))
30 {
31 return TRUE;
32 }
33 return FALSE;
34}
35
36/* Returns list video modes supported by both miniport and display driver.
37 * Note: caller is resposible to free up ppModesTable.
38 */
39int VBoxDispMPGetVideoModes(HANDLE hDriver, PVIDEO_MODE_INFORMATION *ppModesTable, ULONG *pcModes)
40{
41 DWORD dwrc;
42 VIDEO_NUM_MODES numModes;
43 ULONG cbReturned, i, j, cSupportedModes;
44 PVIDEO_MODE_INFORMATION pMiniportModes, pMode;
45
46 LOGF_ENTER();
47
48 /* Get number of video modes supported by miniport */
49 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES, NULL, 0,
50 &numModes, sizeof(VIDEO_NUM_MODES), &cbReturned);
51 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
52
53 if (numModes.ModeInformationLength != sizeof(VIDEO_MODE_INFORMATION))
54 {
55 WARN(("sizeof(VIDEO_MODE_INFORMATION) differs for miniport and display drivers. "
56 "Check that both are compiled with same ddk version!"));
57 }
58
59 /* Allocate temp buffer */
60 pMiniportModes = (PVIDEO_MODE_INFORMATION)
61 EngAllocMem(0, numModes.NumModes*numModes.ModeInformationLength, MEM_ALLOC_TAG);
62
63 if (!pMiniportModes)
64 {
65 WARN(("not enough memory!"));
66 return VERR_NO_MEMORY;
67 }
68
69 /* Get video modes supported by miniport */
70 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_AVAIL_MODES, NULL, 0,
71 pMiniportModes, numModes.NumModes*numModes.ModeInformationLength, &cbReturned);
72 if (dwrc != NO_ERROR)
73 {
74 EngFreeMem(pMiniportModes);
75 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
76 }
77
78 /* Check which of miniport modes are supprted by display driver.
79 * Note: size of VIDEO_MODE_INFORMATION is returned by miniport driver in numModes.ModeInformationLength,
80 * it might be different from the one we have here.
81 */
82 cSupportedModes = 0;
83 pMode = pMiniportModes;
84 for (i=0; i<numModes.NumModes; ++i)
85 {
86 /*sanity check*/
87 if (pMode->Length != sizeof(VIDEO_MODE_INFORMATION))
88 {
89 WARN(("Unexpected mode len %i expected %i!", pMode->Length, sizeof(VIDEO_MODE_INFORMATION)));
90 }
91
92 if (VBoxDispVideoModeSupported(pMode))
93 {
94 cSupportedModes++;
95 }
96 else
97 {
98 pMode->Length = 0;
99 }
100
101 pMode = (PVIDEO_MODE_INFORMATION) (((PUCHAR)pMode)+numModes.ModeInformationLength);
102 }
103 *pcModes = cSupportedModes;
104
105 if (0==cSupportedModes)
106 {
107 WARN(("0 video modes supported!"));
108 EngFreeMem(pMiniportModes);
109 return VERR_NOT_SUPPORTED;
110 }
111
112 /* Allocate and zero output buffer */
113 *ppModesTable = (PVIDEO_MODE_INFORMATION)
114 EngAllocMem(FL_ZERO_MEMORY, cSupportedModes*sizeof(VIDEO_MODE_INFORMATION), MEM_ALLOC_TAG);
115
116 if (!*ppModesTable)
117 {
118 WARN(("not enough memory!"));
119 EngFreeMem(pMiniportModes);
120 return VERR_NO_MEMORY;
121 }
122
123 /* Copy supported modes to output buffer */
124 pMode = pMiniportModes;
125 for (j=0, i=0; i<numModes.NumModes; ++i)
126 {
127 if (pMode->Length != 0)
128 {
129 memcpy(&(*ppModesTable)[j], pMode, numModes.ModeInformationLength);
130 ++j;
131 }
132
133 pMode = (PVIDEO_MODE_INFORMATION) (((PUCHAR)pMode)+numModes.ModeInformationLength);
134 }
135 Assert(j==cSupportedModes);
136
137 /* Free temp buffer */
138 EngFreeMem(pMiniportModes);
139
140 LOGF_LEAVE();
141 return VINF_SUCCESS;
142}
143
144/* Query miniport for mouse pointer caps */
145int VBoxDispMPGetPointerCaps(HANDLE hDriver, PVIDEO_POINTER_CAPABILITIES pCaps)
146{
147 DWORD dwrc;
148 ULONG cbReturned;
149
150 LOGF_ENTER();
151
152 memset(pCaps, 0, sizeof(VIDEO_POINTER_CAPABILITIES));
153 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES, NULL, 0,
154 pCaps, sizeof(VIDEO_POINTER_CAPABILITIES), &cbReturned);
155 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
156 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES", cbReturned, sizeof(VIDEO_POINTER_CAPABILITIES), VERR_DEV_IO_ERROR);
157
158 LOGF_LEAVE();
159 return VINF_SUCCESS;
160}
161
162/* Set device mode */
163int VBoxDispMPSetCurrentMode(HANDLE hDriver, ULONG ulMode)
164{
165 DWORD dwrc;
166 ULONG cbReturned;
167 VIDEO_MODE mode;
168 LOGF_ENTER();
169
170 mode.RequestedMode = ulMode;
171 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_SET_CURRENT_MODE, &mode, sizeof(VIDEO_MODE), NULL, 0, &cbReturned);
172 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
173
174 LOGF_LEAVE();
175 return VINF_SUCCESS;
176}
177
178/* Map device framebuffer and VRAM to our virtual address space */
179int VBoxDispMPMapMemory(PVBOXDISPDEV pDev, PVIDEO_MEMORY_INFORMATION pMemInfo)
180{
181 DWORD dwrc;
182 ULONG cbReturned;
183 VIDEO_MEMORY vMem;
184 VIDEO_MEMORY_INFORMATION vMemInfo;
185 LOGF_ENTER();
186
187 Assert(!pDev->memInfo.FrameBufferBase && !pDev->memInfo.VideoRamBase);
188
189 vMem.RequestedVirtualAddress = NULL;
190 dwrc = EngDeviceIoControl(pDev->hDriver, IOCTL_VIDEO_MAP_VIDEO_MEMORY, &vMem, sizeof(vMem), &vMemInfo, sizeof(vMemInfo), &cbReturned);
191 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
192 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_MAP_VIDEO_MEMORY", cbReturned, sizeof(vMemInfo), VERR_DEV_IO_ERROR);
193
194 if (vMemInfo.FrameBufferBase != vMemInfo.VideoRamBase)
195 {
196 WARN(("FrameBufferBase!=VideoRamBase."));
197 return VERR_GENERAL_FAILURE;
198 }
199
200 /* Check if we can access mapped memory */
201 uint32_t magic = (*(ULONG *)vMemInfo.FrameBufferBase == 0xDEADF00D) ? 0xBAADF00D : 0xDEADF00D;
202
203 ASMAtomicWriteU32((uint32_t *)vMemInfo.FrameBufferBase, magic);
204 if (ASMAtomicReadU32((uint32_t *)vMemInfo.FrameBufferBase) != magic)
205 {
206 WARN(("can't write to framebuffer memory!"));
207 return VERR_GENERAL_FAILURE;
208 }
209
210 memcpy(pMemInfo, &vMemInfo, sizeof(vMemInfo));
211
212 LOGF_LEAVE();
213 return VINF_SUCCESS;
214}
215
216int VBoxDispMPUnmapMemory(PVBOXDISPDEV pDev)
217{
218 DWORD dwrc;
219 ULONG cbReturned;
220 VIDEO_MEMORY vMem;
221 LOGF_ENTER();
222
223 vMem.RequestedVirtualAddress = pDev->memInfo.VideoRamBase;
224 dwrc = EngDeviceIoControl(pDev->hDriver, IOCTL_VIDEO_UNMAP_VIDEO_MEMORY, &vMem, sizeof(vMem), NULL, 0, &cbReturned);
225 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
226
227 memset(&pDev->memInfo, 0, sizeof(VIDEO_MEMORY_INFORMATION));
228
229 LOGF_LEAVE();
230 return VINF_SUCCESS;
231}
232
233int VBoxDispMPQueryHGSMIInfo(HANDLE hDriver, QUERYHGSMIRESULT *pInfo)
234{
235 DWORD dwrc;
236 ULONG cbReturned;
237 LOGF_ENTER();
238
239 memset(pInfo, 0, sizeof(QUERYHGSMIRESULT));
240 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_HGSMI_INFO, NULL, 0,
241 pInfo, sizeof(QUERYHGSMIRESULT), &cbReturned);
242 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
243 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_QUERY_HGSMI_INFO", cbReturned, sizeof(QUERYHGSMIRESULT), VERR_DEV_IO_ERROR);
244
245 LOGF_LEAVE();
246 return VINF_SUCCESS;
247}
248
249int VBoxDispMPQueryHGSMICallbacks(HANDLE hDriver, HGSMIQUERYCALLBACKS *pCallbacks)
250{
251 DWORD dwrc;
252 ULONG cbReturned;
253 LOGF_ENTER();
254
255 memset(pCallbacks, 0, sizeof(HGSMIQUERYCALLBACKS));
256 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS, NULL, 0,
257 pCallbacks, sizeof(HGSMIQUERYCALLBACKS), &cbReturned);
258 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
259 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS", cbReturned, sizeof(HGSMIQUERYCALLBACKS), VERR_DEV_IO_ERROR);
260
261 LOGF_LEAVE();
262 return VINF_SUCCESS;
263}
264
265int VBoxDispMPHGSMIQueryPortProcs(HANDLE hDriver, HGSMIQUERYCPORTPROCS *pPortProcs)
266{
267 DWORD dwrc;
268 ULONG cbReturned;
269 LOGF_ENTER();
270
271 memset(pPortProcs, 0, sizeof(HGSMIQUERYCPORTPROCS));
272 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_HGSMI_QUERY_PORTPROCS, NULL, 0,
273 pPortProcs, sizeof(HGSMIQUERYCPORTPROCS), &cbReturned);
274 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
275 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_HGSMI_QUERY_PORTPROCS", cbReturned, sizeof(HGSMIQUERYCPORTPROCS), VERR_DEV_IO_ERROR);
276
277 LOGF_LEAVE();
278 return VINF_SUCCESS;
279}
280
281int VBoxDispMPVHWAQueryInfo(HANDLE hDriver, VHWAQUERYINFO *pInfo)
282{
283 DWORD dwrc;
284 ULONG cbReturned;
285 LOGF_ENTER();
286
287 memset(pInfo, 0, sizeof(VHWAQUERYINFO));
288 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_VHWA_QUERY_INFO, NULL, 0,
289 pInfo, sizeof(VHWAQUERYINFO), &cbReturned);
290 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
291 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_VHWA_QUERY_INFO", cbReturned, sizeof(VHWAQUERYINFO), VERR_DEV_IO_ERROR);
292
293 LOGF_LEAVE();
294 return VINF_SUCCESS;
295}
296
297int VBoxDispMPSetColorRegisters(HANDLE hDriver, PVIDEO_CLUT pClut, DWORD cbClut)
298{
299 DWORD dwrc;
300 ULONG cbReturned;
301 LOGF_ENTER();
302
303 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_SET_COLOR_REGISTERS, pClut, cbClut, NULL, 0, &cbReturned);
304 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
305
306 LOGF_LEAVE();
307 return VINF_SUCCESS;
308}
309
310int VBoxDispMPDisablePointer(HANDLE hDriver)
311{
312 DWORD dwrc;
313 ULONG cbReturned;
314 LOGF_ENTER();
315
316 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_DISABLE_POINTER, NULL, 0, NULL, 0, &cbReturned);
317 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
318
319 LOGF_LEAVE();
320 return VINF_SUCCESS;
321}
322
323int VBoxDispMPSetPointerPosition(HANDLE hDriver, PVIDEO_POINTER_POSITION pPos)
324{
325 DWORD dwrc;
326 ULONG cbReturned;
327 LOGF_ENTER();
328
329 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_SET_POINTER_POSITION, pPos, sizeof(VIDEO_POINTER_POSITION),
330 NULL, 0, &cbReturned);
331 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
332
333 LOGF_LEAVE();
334 return VINF_SUCCESS;
335}
336
337int VBoxDispMPSetPointerAttrs(PVBOXDISPDEV pDev)
338{
339 DWORD dwrc;
340 ULONG cbReturned;
341 LOGF_ENTER();
342
343 Assert(pDev->pointer.pAttrs);
344
345 dwrc = EngDeviceIoControl(pDev->hDriver, IOCTL_VIDEO_SET_POINTER_ATTR, pDev->pointer.pAttrs, pDev->pointer.cbAttrs,
346 NULL, 0, &cbReturned);
347 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
348
349 LOGF_LEAVE();
350 return VINF_SUCCESS;
351}
352
353int VBoxDispMPSetVisibleRegion(HANDLE hDriver, PRTRECT pRects, DWORD cRects)
354{
355 DWORD dwrc;
356 ULONG cbReturned;
357 LOGF_ENTER();
358
359 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_VBOX_SETVISIBLEREGION, pRects, cRects*sizeof(RTRECT),
360 NULL, 0, &cbReturned);
361 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
362
363 LOGF_LEAVE();
364 return VINF_SUCCESS;
365}
366
367int VBoxDispMPResetDevice(HANDLE hDriver)
368{
369 DWORD dwrc;
370 ULONG cbReturned;
371 LOGF_ENTER();
372
373 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_RESET_DEVICE, NULL, 0, NULL, 0, &cbReturned);
374 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
375
376 LOGF_LEAVE();
377 return VINF_SUCCESS;
378}
379
380int VBoxDispMPShareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem, PVIDEO_SHARE_MEMORY_INFORMATION pSMemInfo)
381{
382 DWORD dwrc;
383 ULONG cbReturned;
384 LOGF_ENTER();
385
386 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_SHARE_VIDEO_MEMORY, pSMem, sizeof(VIDEO_SHARE_MEMORY),
387 pSMemInfo, sizeof(VIDEO_SHARE_MEMORY_INFORMATION), &cbReturned);
388 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
389 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_SHARE_VIDEO_MEMORY", cbReturned,
390 sizeof(VIDEO_SHARE_MEMORY_INFORMATION), VERR_DEV_IO_ERROR);
391
392 LOGF_LEAVE();
393 return VINF_SUCCESS;
394}
395
396int VBoxDispMPUnshareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem)
397{
398 DWORD dwrc;
399 ULONG cbReturned;
400 LOGF_ENTER();
401
402 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY, pSMem, sizeof(VIDEO_SHARE_MEMORY),
403 NULL, 0, &cbReturned);
404 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
405
406 LOGF_LEAVE();
407 return VINF_SUCCESS;
408}
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