VirtualBox

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

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

DdMapMemory must map the offscreen heap as well. Report DdLock updates only for the primary surface.

File size: 30.6 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
652 // We map down to the end of the frame buffer, including the offscreen heap.
653 ShareMemory.ViewSize = pDev->layout.offVBVABuffer;
654
655 DISPDBG((0, "ViewSize = %x\n", ShareMemory.ViewSize));
656
657 if (EngDeviceIoControl(pDev->hDriver,
658 IOCTL_VIDEO_SHARE_VIDEO_MEMORY,
659 &ShareMemory,
660 sizeof(VIDEO_SHARE_MEMORY),
661 &ShareMemoryInformation,
662 sizeof(VIDEO_SHARE_MEMORY_INFORMATION),
663 &ReturnedDataLength))
664 {
665 DISPDBG((0, "Failed IOCTL_VIDEO_SHARE_MEMORY\n"));
666
667 lpMapMemory->ddRVal = DDERR_GENERIC;
668
669 DISPDBG((0, "DdMapMemory: Exit GEN, DDHAL_DRIVER_HANDLED\n"));
670
671 return(DDHAL_DRIVER_HANDLED);
672 }
673
674 lpMapMemory->fpProcess =
675 (FLATPTR) ShareMemoryInformation.VirtualAddress;
676 }
677 else
678 {
679 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
680 ShareMemory.ViewOffset = 0;
681 ShareMemory.ViewSize = 0;
682 ShareMemory.RequestedVirtualAddress = (VOID*) lpMapMemory->fpProcess;
683
684 if (EngDeviceIoControl(pDev->hDriver,
685 IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY,
686 &ShareMemory,
687 sizeof(VIDEO_SHARE_MEMORY),
688 NULL,
689 0,
690 &ReturnedDataLength))
691 {
692 DISPDBG((0, "Failed IOCTL_VIDEO_UNSHARE_MEMORY\n"));
693 }
694 }
695
696 lpMapMemory->ddRVal = DD_OK;
697
698 return(DDHAL_DRIVER_HANDLED);
699}
700
701/**
702 * DdLock
703 *
704 * 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.
705 *
706 * Parameters
707 * lpLock
708 * Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.
709 *
710 * Return Value
711 *
712 * DdLock returns one of the following callback codes:
713 *
714 * DDHAL_DRIVER_HANDLED
715 * DDHAL_DRIVER_NOTHANDLED
716 *
717 */
718DWORD APIENTRY DdLock(PDD_LOCKDATA lpLock)
719{
720 PPDEV pDev = (PPDEV)lpLock->lpDD->dhpdev;
721
722 PDD_SURFACE_LOCAL lpSurfaceLocal = lpLock->lpDDSurface;
723
724 DISPDBG((0, "%s: %p bHasRect = %d fpProcess = %p\n", __FUNCTION__, pDev, lpLock->bHasRect, lpLock->fpProcess));
725
726 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
727 {
728 /* The updated rectangle must be reported only for the primary surface. */
729 pDev->ddLock.bLocked = TRUE;
730
731 if (lpLock->bHasRect)
732 {
733 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));
734 pDev->ddLock.rArea = lpLock->rArea;
735 }
736 else
737 {
738 pDev->ddLock.rArea.left = 0;
739 pDev->ddLock.rArea.top = 0;
740 pDev->ddLock.rArea.right = pDev->cxScreen;
741 pDev->ddLock.rArea.bottom = pDev->cyScreen;
742 }
743 }
744 else
745 {
746 DISPDBG((0, "%s: secondary surface.\n", __FUNCTION__));
747 }
748
749 // Because we correctly set 'fpVidMem' to be the offset into our frame
750 // buffer when we created the surface, DirectDraw will automatically take
751 // care of adding in the user-mode frame buffer address if we return
752 // DDHAL_DRIVER_NOTHANDLED:
753 lpLock->ddRVal = DD_OK;
754 return DDHAL_DRIVER_NOTHANDLED;
755}
756
757/**
758 * DdUnlock
759 *
760 * The DdUnLock callback function releases the lock held on the specified surface.
761 *
762 * Parameters
763 * lpUnlock
764 * Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release. *
765 *
766 * Return Value
767 *
768 * DdLock returns one of the following callback codes:
769 *
770 * DDHAL_DRIVER_HANDLED
771 * DDHAL_DRIVER_NOTHANDLED
772 *
773 */
774DWORD APIENTRY DdUnlock(PDD_UNLOCKDATA lpUnlock)
775{
776 PPDEV pDev = (PPDEV)lpUnlock->lpDD->dhpdev;
777 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
778
779 if (pDev->ddLock.bLocked)
780 {
781 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));
782
783 if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
784 {
785 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
786
787 if ( pDev->pInfo->hostEvents.fu32Events
788 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
789 {
790 vrdpReset (pDev);
791
792 pDev->pInfo->hostEvents.fu32Events &=
793 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
794 }
795
796 if (pDev->vbva.pVbvaMemory->fu32ModeFlags
797 & VBVA_F_MODE_VRDP)
798 {
799 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
800 }
801
802 vboxHwBufferEndUpdate (pDev);
803 }
804 pDev->ddLock.bLocked = FALSE;
805 }
806
807 lpUnlock->ddRVal = DD_OK;
808 return DDHAL_DRIVER_NOTHANDLED;
809}
810
811/**
812 * DdDestroySurface
813 *
814 * The DdDestroySurface callback function destroys a DirectDraw surface.
815 *
816 * Parameters
817 * lpDestroySurface
818 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
819 *
820 * Return Value
821 *
822 * DdDestroySurface returns one of the following callback codes:
823 *
824 * DDHAL_DRIVER_HANDLED
825 * DDHAL_DRIVER_NOTHANDLED
826 *
827 */
828DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
829{
830 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
831 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
832
833 lpDestroySurface->ddRVal = DD_OK;
834 return DDHAL_DRIVER_HANDLED;
835}
836
837
838//-----------------------------------------------------------------------------
839//
840// DdSetExclusiveMode
841//
842// This function is called by DirectDraw when we switch from the GDI surface,
843// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
844// You only need to implement this function when you are using the
845// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
846// and DirectDraw surfaces from the same heap.
847//
848// We use this call to disable GDI DeviceBitMaps when we are running in
849// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
850// DirectDraw allocate memory from the same heap.
851//
852// See also DdFlipToGDISurface.
853//
854//-----------------------------------------------------------------------------
855
856
857DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
858{
859 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
860 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
861
862 // remember setting of exclusive mode in pDev,
863 // so GDI can stop to promote DeviceBitmaps into
864 // video memory
865
866 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
867
868 lpSetExclusiveMode->ddRVal = DD_OK;
869
870 return DDHAL_DRIVER_HANDLED;
871}
872
873//-----------------------------------------------------------------------------
874//
875// DWORD DdFlipToGDISurface
876//
877// This function is called by DirectDraw when it flips to the surface on which
878// GDI can write to.
879//
880//-----------------------------------------------------------------------------
881
882DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
883{
884 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
885 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
886
887 pDev->dwNewDDSurfaceOffset = 0xffffffff;
888
889 lpFlipToGDISurface->ddRVal = DD_OK;
890
891 //
892 // we return NOTHANDLED, then the ddraw runtime takes
893 // care that we flip back to the primary...
894 //
895 return DDHAL_DRIVER_NOTHANDLED;
896}
897//-----------------------------------------------------------------------------
898//
899// DWORD DdFreeDriverMemory
900//
901// This function called by DirectDraw when it's running low on memory in
902// our heap. You only need to implement this function if you use the
903// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
904// can boot those allocations out of memory to make room for DirectDraw.
905//
906//-----------------------------------------------------------------------------
907
908DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
909{
910 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
911 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
912
913 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
914 return DDHAL_DRIVER_HANDLED;
915}
916
917
918#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