VirtualBox

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

Last change on this file since 16605 was 16605, checked in by vboxsync, 16 years ago

header updates

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