VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/dd.c@ 5144

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

Report fullscreen DdLock/DdUnlock updates in the Windows guest graphics driver.

File size: 30.1 KB
Line 
1#ifdef VBOX_WITH_DDRAW
2
3/******************************Module*Header**********************************\
4*
5* **************************
6* * DirectDraw SAMPLE CODE *
7* **************************
8*
9* Module Name: ddenable.c
10*
11* Content:
12*
13* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
14* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
15\*****************************************************************************/
16
17#include "driver.h"
18#include "dd.h"
19#undef CO_E_NOTINITIALIZED
20#include <winerror.h>
21
22
23#if 0
24static DWORD APIENTRY DdCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface);
25#endif
26
27
28/**
29 * DrvGetDirectDrawInfo
30 *
31 * The DrvGetDirectDrawInfo function returns the capabilities of the graphics hardware.
32 *
33 * Parameters:
34 *
35 * dhpdev
36 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
37 * pHalInfo
38 * Points to a DD_HALINFO structure in which the driver should return the hardware capabilities that it supports.
39 * pdwNumHeaps
40 * Points to the location in which the driver should return the number of VIDEOMEMORY structures pointed to by pvmList.
41 * pvmList
42 * Points to an array of VIDEOMEMORY structures in which the driver should return information about each display memory chunk that it controls. The driver should ignore this parameter when it is NULL.
43 * pdwNumFourCCCodes
44 * Points to the location in which the driver should return the number of DWORDs pointed to by pdwFourCC.
45 * pdwFourCC
46 * Points to an array of DWORDs in which the driver should return information about each FOURCC that it supports. The driver should ignore this parameter when it is NULL.
47 *
48 * Return Value:
49 *
50 * DrvGetDirectDrawInfo returns TRUE if it succeeds; otherwise, it returns FALSE.
51 *
52 */
53BOOL APIENTRY DrvGetDirectDrawInfo(
54 DHPDEV dhpdev,
55 DD_HALINFO *pHalInfo,
56 DWORD *pdwNumHeaps,
57 VIDEOMEMORY *pvmList,
58 DWORD *pdwNumFourCCCodes,
59 DWORD *pdwFourCC
60 )
61{
62 PPDEV pDev = (PPDEV)dhpdev;
63 BOOL bDefineDDrawHeap = FALSE;
64 DWORD cHeaps = 0;
65 VIDEOMEMORY *pVm = NULL;
66
67 DISPDBG((0, "%s: %p, %p, %p, %p, %p. %p\n", __FUNCTION__, dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC));
68
69 *pdwNumFourCCCodes = 0;
70 *pdwNumHeaps = 0;
71
72 /* Setup the HAL driver caps. */
73 pHalInfo->dwSize = sizeof(DD_HALINFO);
74 pHalInfo->dwFlags = 0;
75
76 if (!(pvmList && pdwFourCC))
77 {
78 memset(&pHalInfo->ddCaps, 0, sizeof(DDNTCORECAPS));
79 pHalInfo->ddCaps.dwSize = sizeof(DDNTCORECAPS);
80 pHalInfo->ddCaps.dwVidMemTotal = pDev->layout.cbDDRAWHeap;
81 pHalInfo->ddCaps.dwVidMemFree = pHalInfo->ddCaps.dwVidMemTotal;
82
83 pHalInfo->ddCaps.dwCaps = 0;
84 pHalInfo->ddCaps.dwCaps2 = 0;
85
86 /* Declare we can handle textures wider than the primary */
87 pHalInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
88
89 pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
90
91 /* Create primary surface attributes */
92 pHalInfo->vmiData.pvPrimary = pDev->pjScreen;
93 pHalInfo->vmiData.fpPrimary = 0;
94 pHalInfo->vmiData.dwDisplayWidth = pDev->cxScreen;
95 pHalInfo->vmiData.dwDisplayHeight = pDev->cyScreen;
96 pHalInfo->vmiData.lDisplayPitch = pDev->lDeltaScreen;
97
98 pHalInfo->vmiData.ddpfDisplay.dwSize = sizeof(DDPIXELFORMAT);
99 pHalInfo->vmiData.ddpfDisplay.dwFlags = DDPF_RGB;
100 pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount = pDev->ulBitCount;
101 DISPDBG((0, "pvPrimary %x\n", pHalInfo->vmiData.pvPrimary));
102 DISPDBG((0, "fpPrimary %x\n", pHalInfo->vmiData.fpPrimary));
103 DISPDBG((0, "dwDisplayWidth %d\n", pHalInfo->vmiData.dwDisplayWidth));
104 DISPDBG((0, "dwDisplayHeight %d\n", pHalInfo->vmiData.dwDisplayHeight));
105 DISPDBG((0, "lDisplayPitch %d\n", pHalInfo->vmiData.lDisplayPitch));
106 DISPDBG((0, "dwRGBBitCount %d\n", pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount));
107
108 if (pDev->ulBitmapType == BMF_8BPP)
109 {
110 pHalInfo->vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8;
111 DISPDBG((0, "DDPF_PALETTEINDEXED8\n"));
112 }
113
114 pHalInfo->vmiData.ddpfDisplay.dwRBitMask = pDev->flRed;
115 pHalInfo->vmiData.ddpfDisplay.dwGBitMask = pDev->flGreen;
116 pHalInfo->vmiData.ddpfDisplay.dwBBitMask = pDev->flBlue;
117
118 pHalInfo->vmiData.dwOffscreenAlign = 4;
119 pHalInfo->vmiData.dwZBufferAlign = 4;
120 pHalInfo->vmiData.dwTextureAlign = 4;
121 }
122
123 cHeaps = 0;
124
125 /* Do we have sufficient videomemory to create an off-screen heap for DDraw? */
126 if (pDev->layout.cbDDRAWHeap > 0)
127 {
128 bDefineDDrawHeap = TRUE;
129 cHeaps++;
130 }
131
132 pDev->cHeaps = cHeaps;
133 *pdwNumHeaps = cHeaps;
134
135 // If pvmList is not NULL then we can go ahead and fill out the VIDEOMEMORY
136 // structures which define our requested heaps.
137
138 if(pvmList) {
139
140 pVm=pvmList;
141
142 //
143 // Snag a pointer to the video-memory list so that we can use it to
144 // call back to DirectDraw to allocate video memory:
145 //
146 pDev->pvmList = pVm;
147
148 //
149 // Define the heap for DirectDraw
150 //
151 if ( bDefineDDrawHeap )
152 {
153 pVm->dwFlags = VIDMEM_ISLINEAR ;
154 pVm->fpStart = pDev->layout.offDDRAWHeap;
155 pVm->fpEnd = pDev->layout.offDDRAWHeap + pDev->layout.cbDDRAWHeap - 1; /* inclusive */
156
157 pVm->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
158 DISPDBG((0, "fpStart %x fpEnd %x\n", pVm->fpStart, pVm->fpEnd));
159
160 pVm++;
161 }
162 }
163
164#if 0 /* not mandatory */
165 /* DX5 and up */
166 pHalInfo->GetDriverInfo = DdGetDriverInfo;
167 pHalInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
168#endif
169
170#if 0
171 /* No 3D capabilities */
172 if (pHalInfo->lpD3DGlobalDriverData)
173 {
174 LPD3DHAL_GLOBALDRIVERDATA lpD3DGlobalDriverData = (LPD3DHAL_GLOBALDRIVERDATA)pHalInfo->lpD3DGlobalDriverData;
175 lpD3DGlobalDriverData->dwSize = sizeof(D3DHAL_GLOBALDRIVERDATA);
176 }
177#endif
178 return TRUE;
179}
180
181/**
182 * DrvEnableDirectDraw
183 *
184 * The DrvEnableDirectDraw function enables hardware for DirectDraw use.
185 *
186 * Parameters
187 *
188 * dhpdev
189 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
190 * pCallBacks
191 * Points to the DD_CALLBACKS structure to be initialized by the driver.
192 * pSurfaceCallBacks
193 * Points to the DD_SURFACECALLBACKS structure to be initialized by the driver.
194 * pPaletteCallBacks
195 * Points to the DD_PALETTECALLBACKS structure to be initialized by the driver.
196 *
197 * Return Value
198 *
199 * DrvEnableDirectDraw returns TRUE if it succeeds; otherwise, it returns FALSE.
200 *
201 */
202BOOL APIENTRY DrvEnableDirectDraw(
203 DHPDEV dhpdev,
204 DD_CALLBACKS *pCallBacks,
205 DD_SURFACECALLBACKS *pSurfaceCallBacks,
206 DD_PALETTECALLBACKS *pPaletteCallBacks
207 )
208{
209 DISPDBG((0, "%s: %p, %p, %p, %p\n", __FUNCTION__, dhpdev, pCallBacks, pSurfaceCallBacks, pPaletteCallBacks));
210
211 /* Fill in the HAL Callback pointers */
212 pCallBacks->dwSize = sizeof(DD_CALLBACKS);
213 pCallBacks->dwFlags = 0;
214
215 pCallBacks->dwFlags = DDHAL_CB32_CREATESURFACE | DDHAL_CB32_CANCREATESURFACE | DDHAL_CB32_MAPMEMORY;
216 pCallBacks->CreateSurface = DdCreateSurface;
217 pCallBacks->CanCreateSurface = DdCanCreateSurface;
218 pCallBacks->MapMemory = DdMapMemory;
219 // pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank;
220 // pCallBacks->GetScanLine = DdGetScanLine;
221 // DDHAL_CB32_WAITFORVERTICALBLANK | DDHAL_CB32_GETSCANLINE
222 /* Note: pCallBacks->SetMode & pCallBacks->DestroyDriver are unused in Windows 2000 and up */
223
224 /* Fill in the Surface Callback pointers */
225 pSurfaceCallBacks->dwSize = sizeof(DD_SURFACECALLBACKS);
226 pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_LOCK | DDHAL_SURFCB32_UNLOCK;
227 pSurfaceCallBacks->Lock = DdLock;
228 pSurfaceCallBacks->Unlock = DdUnlock;
229
230 /*
231 pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_DESTROYSURFACE | DDHAL_SURFCB32_LOCK; // DDHAL_SURFCB32_UNLOCK;
232 pSurfaceCallBacks->DestroySurface = DdDestroySurface;
233 pSurfaceCallBacks->Flip = DdFlip;
234 pSurfaceCallBacks->GetBltStatus = DdGetBltStatus;
235 pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus;
236 pSurfaceCallBacks->Blt = DdBlt;
237 DDHAL_SURFCB32_FLIP | DDHAL_SURFCB32_BLT | DDHAL_SURFCB32_GETBLTSTATUS | DDHAL_SURFCB32_GETFLIPSTATUS;
238 */
239
240// pSurfaceCallBacks.SetColorKey = DdSetColorKey;
241// pSurfaceCallBacks.dwFlags |= DDHAL_SURFCB32_SETCOLORKEY;
242
243 /* Fill in the Palette Callback pointers */
244 pPaletteCallBacks->dwSize = sizeof(DD_PALETTECALLBACKS);
245 pPaletteCallBacks->dwFlags = 0;
246
247 return TRUE;
248}
249
250/**
251 * DrvDisableDirectDraw
252 *
253 * The DrvDisableDirectDraw function disables hardware for DirectDraw use.
254 *
255 * Parameters
256 *
257 * dhpdev
258 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
259 *
260 */
261VOID APIENTRY DrvDisableDirectDraw( DHPDEV dhpdev)
262{
263 DISPDBG((0, "%s: %p\n", __FUNCTION__, dhpdev));
264}
265
266/**
267 * DdGetDriverInfo
268 *
269 * The DdGetDriverInfo function queries the driver for additional DirectDraw and Direct3D functionality that the driver supports.
270 *
271 * Parameters
272 * lpGetDriverInfo
273 * Points to a DD_GETDRIVERINFODATA structure that contains the information required to perform the query.
274 *
275 * Return Value
276 *
277 * DdGetDriverInfo must return DDHAL_DRIVER_HANDLED.
278 *
279 */
280DWORD CALLBACK DdGetDriverInfo(DD_GETDRIVERINFODATA *lpData)
281{
282 PPDEV pDev = (PPDEV)lpData->dhpdev;
283 DWORD dwSize;
284
285 DISPDBG((0, "%s: %p\n", __FUNCTION__, lpData->dhpdev));
286
287 /* Default to 'not supported' */
288 lpData->ddRVal = DDERR_CURRENTLYNOTAVAIL;
289
290 /* Fill in supported stuff */
291 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks3))
292 {
293 DISPDBG((0, " -> GUID_D3DCallbacks3\n"));
294 }
295 else
296 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DExtendedCaps))
297 {
298 DISPDBG((0, " -> GUID_D3DExtendedCaps\n"));
299 }
300 else
301 if (IsEqualIID(&lpData->guidInfo, &GUID_ZPixelFormats))
302 {
303 DISPDBG((0, " -> GUID_ZPixelFormats\n"));
304 }
305 else
306 if (IsEqualIID(&(lpData->guidInfo), &GUID_D3DParseUnknownCommandCallback))
307 {
308 DISPDBG((0, " -> GUID_D3DParseUnknownCommandCallback\n"));
309 }
310 else
311 if (IsEqualIID(&(lpData->guidInfo), &GUID_Miscellaneous2Callbacks))
312 {
313 DISPDBG((0, " -> GUID_Miscellaneous2Callbacks\n"));
314 }
315 else
316 if (IsEqualIID(&(lpData->guidInfo), &GUID_UpdateNonLocalHeap))
317 {
318 DISPDBG((0, " -> GUID_UpdateNonLocalHeap\n"));
319 }
320 else
321 if (IsEqualIID(&(lpData->guidInfo), &GUID_GetHeapAlignment))
322 {
323 DISPDBG((0, " -> GUID_GetHeapAlignment\n"));
324 }
325 else
326 if (IsEqualIID(&(lpData->guidInfo), &GUID_NTPrivateDriverCaps))
327 {
328 DD_NTPRIVATEDRIVERCAPS DDPrivateDriverCaps;
329
330 DISPDBG((0, " -> GUID_NTPrivateDriverCaps\n"));
331
332 memset(&DDPrivateDriverCaps, 0, sizeof(DDPrivateDriverCaps));
333 DDPrivateDriverCaps.dwSize=sizeof(DDPrivateDriverCaps);
334
335 DDPrivateDriverCaps.dwPrivateCaps = 0; /* DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION -> call CreateSurface for the primary surface */
336
337 lpData->dwActualSize =sizeof(DDPrivateDriverCaps);
338
339 dwSize = min(sizeof(DDPrivateDriverCaps),lpData->dwExpectedSize);
340 memcpy(lpData->lpvData, &DDPrivateDriverCaps, dwSize);
341 lpData->ddRVal = DD_OK;
342 }
343 else
344 if (IsEqualIID(&(lpData->guidInfo), &GUID_DDMoreSurfaceCaps))
345 {
346 DD_MORESURFACECAPS DDMoreSurfaceCaps;
347 DDSCAPSEX ddsCapsEx, ddsCapsExAlt;
348
349 DISPDBG((0, " -> GUID_DDMoreSurfaceCaps\n"));
350
351 // fill in everything until expectedsize...
352 memset(&DDMoreSurfaceCaps, 0, sizeof(DDMoreSurfaceCaps));
353
354 // Caps for heaps 2..n
355 memset(&ddsCapsEx, 0, sizeof(ddsCapsEx));
356 memset(&ddsCapsExAlt, 0, sizeof(ddsCapsEx));
357
358 DDMoreSurfaceCaps.dwSize=lpData->dwExpectedSize;
359
360 lpData->dwActualSize = lpData->dwExpectedSize;
361
362 dwSize = min(sizeof(DDMoreSurfaceCaps),lpData->dwExpectedSize);
363 memcpy(lpData->lpvData, &DDMoreSurfaceCaps, dwSize);
364
365 // now fill in other heaps...
366 while (dwSize < lpData->dwExpectedSize)
367 {
368 memcpy( (PBYTE)lpData->lpvData+dwSize,
369 &ddsCapsEx,
370 sizeof(DDSCAPSEX));
371 dwSize += sizeof(DDSCAPSEX);
372 memcpy( (PBYTE)lpData->lpvData+dwSize,
373 &ddsCapsExAlt,
374 sizeof(DDSCAPSEX));
375 dwSize += sizeof(DDSCAPSEX);
376 }
377
378 lpData->ddRVal = DD_OK;
379 }
380 else
381 if (IsEqualIID(&(lpData->guidInfo), &GUID_DDStereoMode))
382 {
383 DISPDBG((0, " -> GUID_DDStereoMode\n"));
384 }
385 else
386 if (IsEqualIID(&(lpData->guidInfo), &GUID_NonLocalVidMemCaps))
387 {
388 DISPDBG((0, " -> GUID_NonLocalVidMemCaps\n"));
389 }
390 else
391 if (IsEqualIID(&lpData->guidInfo, &GUID_NTCallbacks))
392 {
393 DD_NTCALLBACKS NtCallbacks;
394
395 DISPDBG((0, " -> GUID_NTCallbacks\n"));
396 memset(&NtCallbacks, 0, sizeof(NtCallbacks));
397
398 dwSize = min(lpData->dwExpectedSize, sizeof(DD_NTCALLBACKS));
399
400 NtCallbacks.dwSize = dwSize;
401 NtCallbacks.dwFlags = DDHAL_NTCB32_FREEDRIVERMEMORY
402 | DDHAL_NTCB32_SETEXCLUSIVEMODE
403 | DDHAL_NTCB32_FLIPTOGDISURFACE
404 ;
405 NtCallbacks.FreeDriverMemory = DdFreeDriverMemory;
406 NtCallbacks.SetExclusiveMode = DdSetExclusiveMode;
407 NtCallbacks.FlipToGDISurface = DdFlipToGDISurface;
408
409 memcpy(lpData->lpvData, &NtCallbacks, dwSize);
410
411 lpData->ddRVal = DD_OK;
412 }
413 else
414 if (IsEqualIID(&lpData->guidInfo, &GUID_KernelCaps))
415 {
416 DISPDBG((0, " -> GUID_KernelCaps\n"));
417 }
418 else
419 if (IsEqualIID(&lpData->guidInfo, &GUID_KernelCallbacks))
420 {
421 DISPDBG((0, " -> GUID_KernelCallbacks\n"));
422 }
423 else
424 if (IsEqualIID(&lpData->guidInfo, &GUID_MotionCompCallbacks))
425 {
426 DISPDBG((0, " -> GUID_MotionCompCallbacks\n"));
427 }
428 else
429 if (IsEqualIID(&lpData->guidInfo, &GUID_VideoPortCallbacks))
430 {
431 DISPDBG((0, " -> GUID_VideoPortCallbacks\n"));
432 }
433 else
434 if (IsEqualIID(&lpData->guidInfo, &GUID_ColorControlCallbacks))
435 {
436 DISPDBG((0, " -> GUID_ColorControlCallbacks\n"));
437 }
438 else
439 if (IsEqualIID(&lpData->guidInfo, &GUID_VideoPortCaps))
440 {
441 DISPDBG((0, " -> GUID_VideoPortCaps\n"));
442 }
443 else
444 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks2))
445 {
446 DISPDBG((0, " -> GUID_D3DCallbacks2\n"));
447 }
448 else
449 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks3))
450 {
451 DISPDBG((0, " -> GUID_D3DCallbacks3\n"));
452 }
453
454 /* Always return this */
455 return DDHAL_DRIVER_HANDLED;
456}
457
458/**
459 * DdCreateSurface
460 *
461 * The DdCreateSurface callback function creates a DirectDraw surface.
462 *
463 * lpCreateSurface
464 * Points to a DD_CREATESURFACEDATA structure that contains the information required to create a surface.
465 *
466 * Return Value
467 *
468 * DdCreateSurface returns one of the following callback codes:
469 * DDHAL_DRIVER_HANDLED
470 * DDHAL_DRIVER_NOTHANDLED
471 *
472 */
473DWORD APIENTRY DdCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface)
474{
475 PPDEV pDev = (PPDEV)lpCreateSurface->lpDD->dhpdev;
476 DD_SURFACE_LOCAL* lpSurfaceLocal;
477 DD_SURFACE_GLOBAL* lpSurfaceGlobal;
478 LPDDSURFACEDESC lpSurfaceDesc;
479 LONG lPitch, lBpp;
480
481 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
482
483 lpSurfaceLocal = lpCreateSurface->lplpSList[0];
484 lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
485 lpSurfaceDesc = lpCreateSurface->lpDDSurfaceDesc;
486
487 lpSurfaceGlobal->dwReserved1 = 0;
488
489 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
490 {
491 lBpp = 4;
492 lPitch = lpSurfaceGlobal->wWidth/2;
493 lPitch = (lPitch + 31) & ~31;
494 }
495 else
496 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
497 {
498 lBpp = 8;
499 lPitch = lpSurfaceGlobal->wWidth;
500 lPitch = (lPitch + 31) & ~31;
501 }
502 else
503 {
504 lBpp = lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
505 lPitch = lpSurfaceGlobal->wWidth*(lBpp/8);
506 }
507 DISPDBG((0, "New surface (%d,%d)\n", lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
508 DISPDBG((0, "BPP %d lPitch=%d\n", lBpp, lPitch));
509
510 lpSurfaceGlobal->dwBlockSizeX = lPitch;
511 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
512 lpSurfaceGlobal->lPitch = lPitch;
513
514 //
515 // Modify surface descriptions as appropriate and let Direct
516 // Draw perform the allocation if the surface was not the primary
517 //
518 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
519 {
520 DISPDBG((0, "-> primary surface\n"));
521 lpSurfaceGlobal->fpVidMem = 0;
522 }
523 else
524 {
525 DISPDBG((0, "-> secondary surface\n"));
526 lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
527 }
528
529 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
530 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
531
532
533 return DDHAL_DRIVER_NOTHANDLED;
534}
535
536/**
537 * DdCanCreateSurface
538 *
539 * The DdCanCreateSurface callback function indicates whether the driver can create a surface of the specified surface description.
540 *
541 *
542 * Parameters
543 * lpCanCreateSurface
544 * Points to the DD_CANCREATESURFACEDATA structure containing the information required for the driver to determine whether a surface can be created.
545 *
546 * Return Value
547 *
548 * DdCanCreateSurface returns one of the following callback codes:
549 *
550 * DDHAL_DRIVER_HANDLED
551 * DDHAL_DRIVER_NOTHANDLED
552 *
553 */
554DWORD APIENTRY DdCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSurface)
555{
556 PPDEV pDev = (PPDEV)lpCanCreateSurface->lpDD->dhpdev;
557
558 PDD_SURFACEDESC lpDDS = lpCanCreateSurface->lpDDSurfaceDesc;
559
560 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
561
562 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
563 {
564 DISPDBG((0, "No Z-Bufer support\n"));
565 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
566 return DDHAL_DRIVER_HANDLED;
567 }
568 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
569 {
570 DISPDBG((0, "No texture support\n"));
571 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
572 return DDHAL_DRIVER_HANDLED;
573 }
574
575 if (lpCanCreateSurface->bIsDifferentPixelFormat && (lpDDS->ddpfPixelFormat.dwFlags & DDPF_FOURCC))
576 {
577 DISPDBG((0, "FOURCC not supported\n"));
578 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
579 return DDHAL_DRIVER_HANDLED;
580 }
581
582 lpCanCreateSurface->ddRVal = DD_OK;
583 return DDHAL_DRIVER_HANDLED;
584}
585
586// ***************************WIN NT ONLY**********************************
587//
588// DdMapMemory
589//
590// Maps application-modifiable portions of the frame buffer into the
591// user-mode address space of the specified process, or unmaps memory.
592//
593// DdMapMemory is called to perform memory mapping before the first call to
594// DdLock. The handle returned by the driver in fpProcess will be passed to
595// every DdLock call made on the driver.
596//
597// DdMapMemory is also called to unmap memory after the last DdUnLock call is
598// made.
599//
600// To prevent driver crashes, the driver must not map any portion of the frame
601// buffer that must not be modified by an application.
602//
603// Parameters
604// lpMapMemory
605// Points to a DD_MAPMEMORYDATA structure that contains details for
606// the memory mapping or unmapping operation.
607//
608// .lpDD
609// Points to a DD_DIRECTDRAW_GLOBAL structure that represents
610// the driver.
611// .bMap
612// Specifies the memory operation that the driver should perform.
613// A value of TRUE indicates that the driver should map memory;
614// FALSE means that the driver should unmap memory.
615// .hProcess
616// Specifies a handle to the process whose address space is
617// affected.
618// .fpProcess
619// Specifies the location in which the driver should return the
620// base address of the process's memory mapped space when bMap
621// is TRUE. When bMap is FALSE, fpProcess contains the base
622// address of the memory to be unmapped by the driver.
623// .ddRVal
624// Specifies the location in which the driver writes the return
625// value of the DdMapMemory callback. A return code of DD_OK
626// indicates success.
627//
628//-----------------------------------------------------------------------------
629
630DWORD CALLBACK DdMapMemory(PDD_MAPMEMORYDATA lpMapMemory)
631{
632 PPDEV pDev = (PPDEV)lpMapMemory->lpDD->dhpdev;
633
634 VIDEO_SHARE_MEMORY ShareMemory;
635 VIDEO_SHARE_MEMORY_INFORMATION ShareMemoryInformation;
636 DWORD ReturnedDataLength;
637
638 DISPDBG((0, "%s: %p bMap %d\n", __FUNCTION__, pDev, lpMapMemory->bMap));
639
640 if (lpMapMemory->bMap)
641 {
642 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
643
644 // 'RequestedVirtualAddress' isn't actually used for the SHARE IOCTL:
645
646 ShareMemory.RequestedVirtualAddress = 0;
647
648 // We map in starting at the top of the frame buffer:
649
650 ShareMemory.ViewOffset = 0;
651 ShareMemory.ViewSize = pDev->cyScreen * pDev->lDeltaScreen;
652
653 DISPDBG((0, "ViewSize = %x\n", ShareMemory.ViewSize));
654
655 if (EngDeviceIoControl(pDev->hDriver,
656 IOCTL_VIDEO_SHARE_VIDEO_MEMORY,
657 &ShareMemory,
658 sizeof(VIDEO_SHARE_MEMORY),
659 &ShareMemoryInformation,
660 sizeof(VIDEO_SHARE_MEMORY_INFORMATION),
661 &ReturnedDataLength))
662 {
663 DISPDBG((0, "Failed IOCTL_VIDEO_SHARE_MEMORY"));
664
665 lpMapMemory->ddRVal = DDERR_GENERIC;
666
667 DISPDBG((0, "DdMapMemory: Exit GEN, DDHAL_DRIVER_HANDLED\n"));
668
669 return(DDHAL_DRIVER_HANDLED);
670 }
671
672 lpMapMemory->fpProcess =
673 (FLATPTR) ShareMemoryInformation.VirtualAddress;
674 }
675 else
676 {
677 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
678 ShareMemory.ViewOffset = 0;
679 ShareMemory.ViewSize = 0;
680 ShareMemory.RequestedVirtualAddress = (VOID*) lpMapMemory->fpProcess;
681
682 if (EngDeviceIoControl(pDev->hDriver,
683 IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY,
684 &ShareMemory,
685 sizeof(VIDEO_SHARE_MEMORY),
686 NULL,
687 0,
688 &ReturnedDataLength))
689 {
690 DISPDBG((0, "Failed IOCTL_VIDEO_UNSHARE_MEMORY\n"));
691 }
692 }
693
694 lpMapMemory->ddRVal = DD_OK;
695
696 return(DDHAL_DRIVER_HANDLED);
697}
698
699/**
700 * DdLock
701 *
702 * The DdLock callback function locks a specified area of surface memory and provides a valid pointer to a block of memory associated with a surface.
703 *
704 * Parameters
705 * lpLock
706 * Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.
707 *
708 * Return Value
709 *
710 * DdLock returns one of the following callback codes:
711 *
712 * DDHAL_DRIVER_HANDLED
713 * DDHAL_DRIVER_NOTHANDLED
714 *
715 */
716DWORD APIENTRY DdLock(PDD_LOCKDATA lpLock)
717{
718 PPDEV pDev = (PPDEV)lpLock->lpDD->dhpdev;
719
720 DISPDBG((0, "%s: %p bHasRect = %d\n", __FUNCTION__, pDev, lpLock->bHasRect));
721
722 pDev->ddLock.bLocked = TRUE;
723
724 if (lpLock->bHasRect)
725 {
726 DISPDBG((0, "%d,%d %dx%d\n", lpLock->rArea.left, lpLock->rArea.top, lpLock->rArea.right - lpLock->rArea.left, lpLock->rArea.bottom - lpLock->rArea.top));
727 pDev->ddLock.rArea = lpLock->rArea;
728 }
729 else
730 {
731 pDev->ddLock.rArea.left = 0;
732 pDev->ddLock.rArea.top = 0;
733 pDev->ddLock.rArea.right = pDev->cxScreen;
734 pDev->ddLock.rArea.bottom = pDev->cyScreen;
735 }
736
737 // Because we correctly set 'fpVidMem' to be the offset into our frame
738 // buffer when we created the surface, DirectDraw will automatically take
739 // care of adding in the user-mode frame buffer address if we return
740 // DDHAL_DRIVER_NOTHANDLED:
741 lpLock->ddRVal = DD_OK;
742 return DDHAL_DRIVER_NOTHANDLED;
743}
744
745/**
746 * DdUnlock
747 *
748 * The DdUnLock callback function releases the lock held on the specified surface.
749 *
750 * Parameters
751 * lpUnlock
752 * Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release. *
753 *
754 * Return Value
755 *
756 * DdLock returns one of the following callback codes:
757 *
758 * DDHAL_DRIVER_HANDLED
759 * DDHAL_DRIVER_NOTHANDLED
760 *
761 */
762DWORD APIENTRY DdUnlock(PDD_UNLOCKDATA lpUnlock)
763{
764 PPDEV pDev = (PPDEV)lpUnlock->lpDD->dhpdev;
765 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
766
767 if (pDev->ddLock.bLocked)
768 {
769 DISPDBG((0, "%d,%d %dx%d\n", pDev->ddLock.rArea.left, pDev->ddLock.rArea.top, pDev->ddLock.rArea.right - pDev->ddLock.rArea.left, pDev->ddLock.rArea.bottom - pDev->ddLock.rArea.top));
770
771 if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
772 {
773 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
774
775 if ( pDev->pInfo->hostEvents.fu32Events
776 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
777 {
778 vrdpReset (pDev);
779
780 pDev->pInfo->hostEvents.fu32Events &=
781 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
782 }
783
784 if (pDev->vbva.pVbvaMemory->fu32ModeFlags
785 & VBVA_F_MODE_VRDP)
786 {
787 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
788 }
789
790 vboxHwBufferEndUpdate (pDev);
791 }
792 pDev->ddLock.bLocked = FALSE;
793 }
794
795 lpUnlock->ddRVal = DD_OK;
796 return DDHAL_DRIVER_NOTHANDLED;
797}
798
799/**
800 * DdDestroySurface
801 *
802 * The DdDestroySurface callback function destroys a DirectDraw surface.
803 *
804 * Parameters
805 * lpDestroySurface
806 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
807 *
808 * Return Value
809 *
810 * DdDestroySurface returns one of the following callback codes:
811 *
812 * DDHAL_DRIVER_HANDLED
813 * DDHAL_DRIVER_NOTHANDLED
814 *
815 */
816DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
817{
818 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
819 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
820
821 lpDestroySurface->ddRVal = DD_OK;
822 return DDHAL_DRIVER_HANDLED;
823}
824
825
826//-----------------------------------------------------------------------------
827//
828// DdSetExclusiveMode
829//
830// This function is called by DirectDraw when we switch from the GDI surface,
831// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
832// You only need to implement this function when you are using the
833// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
834// and DirectDraw surfaces from the same heap.
835//
836// We use this call to disable GDI DeviceBitMaps when we are running in
837// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
838// DirectDraw allocate memory from the same heap.
839//
840// See also DdFlipToGDISurface.
841//
842//-----------------------------------------------------------------------------
843
844
845DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
846{
847 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
848 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
849
850 // remember setting of exclusive mode in pDev,
851 // so GDI can stop to promote DeviceBitmaps into
852 // video memory
853
854 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
855
856 lpSetExclusiveMode->ddRVal = DD_OK;
857
858 return DDHAL_DRIVER_HANDLED;
859}
860
861//-----------------------------------------------------------------------------
862//
863// DWORD DdFlipToGDISurface
864//
865// This function is called by DirectDraw when it flips to the surface on which
866// GDI can write to.
867//
868//-----------------------------------------------------------------------------
869
870DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
871{
872 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
873 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
874
875 pDev->dwNewDDSurfaceOffset = 0xffffffff;
876
877 lpFlipToGDISurface->ddRVal = DD_OK;
878
879 //
880 // we return NOTHANDLED, then the ddraw runtime takes
881 // care that we flip back to the primary...
882 //
883 return DDHAL_DRIVER_NOTHANDLED;
884}
885//-----------------------------------------------------------------------------
886//
887// DWORD DdFreeDriverMemory
888//
889// This function called by DirectDraw when it's running low on memory in
890// our heap. You only need to implement this function if you use the
891// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
892// can boot those allocations out of memory to make room for DirectDraw.
893//
894//-----------------------------------------------------------------------------
895
896DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
897{
898 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
899 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
900
901 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
902 return DDHAL_DRIVER_HANDLED;
903}
904
905
906#endif /* VBOX_WITH_DDRAW */
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