xref: /reactos/win32ss/reactx/dxg/ddraw.c (revision e034377b)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * PURPOSE:          Native driver for dxg implementation
5  * FILE:             win32ss/reactx/dxg/eng.c
6  * PROGRAMER:        Magnus olsen (magnus@greatlord.com)
7  *                   Sebastian Gasiorek (sebastian.gasiorek@reactos.org)
8  * REVISION HISTORY:
9  *       30/12-2007   Magnus Olsen
10  */
11 
12 #include <dxg_int.h>
13 
14 /*++
15 * @name intDdGetDriverInfo
16 * @implemented
17 *
18 * The function intDdGetDriverInfo is used internally in dxg.sys
19 * It retrieves driver information structures
20 *
21 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
22 * DirectDraw global structure
23 *
24 * @param GUID guid
25 * GUID of InfoData to read
26 *
27 * @param PVOID callbackStruct
28 * Callback structure pointer
29 *
30 * @param ULONG callbackSize
31 * Size of allocated callback structure
32 *
33 * @param ULONG *returnSize
34 * Desired structure size returned by driver
35 *
36 * @return
37 * Returns true on successful execution, false when error.
38 *
39 * @remarks.
40 * Only used internally in dxg.sys
41 *--*/
intDdGetDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl,GUID guid,PVOID callbackStruct,ULONG callbackSize,ULONG * returnSize)42 BOOL intDdGetDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl, GUID guid, PVOID callbackStruct, ULONG callbackSize, ULONG *returnSize)
43 {
44     DD_GETDRIVERINFODATA ddGetDriverInfoData;
45 
46     if (peDdGl->ddHalInfo.dwFlags & DDHALINFO_GETDRIVERINFOSET && peDdGl->ddHalInfo.GetDriverInfo)
47     {
48         memset(&ddGetDriverInfoData, 0, sizeof(DD_GETDRIVERINFODATA));
49         ddGetDriverInfoData.dwSize = sizeof(DD_GETDRIVERINFODATA);
50         ddGetDriverInfoData.dhpdev = peDdGl->dhpdev;
51         memcpy(&ddGetDriverInfoData.guidInfo, &guid, sizeof(GUID));
52         ddGetDriverInfoData.dwExpectedSize = callbackSize;
53         ddGetDriverInfoData.lpvData = callbackStruct;
54         ddGetDriverInfoData.ddRVal = DDERR_CURRENTLYNOTAVAIL;
55         if (peDdGl->ddHalInfo.GetDriverInfo(&ddGetDriverInfoData) && !ddGetDriverInfoData.ddRVal)
56         {
57             if (returnSize)
58                 *returnSize = ddGetDriverInfoData.dwActualSize;
59             return TRUE;
60         }
61 
62     }
63 
64     /* cleanup on error */
65     memset(callbackStruct, 0, callbackSize);
66     if (returnSize)
67         *returnSize = 0;
68     return FALSE;
69 }
70 
71 /*++
72 * @name intDdGetAllDriverInfo
73 * @implemented
74 *
75 * The function intDdGetAllDriverInfo is used internally in dxg.sys
76 * It retrieves all possible driver information structures
77 *
78 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
79 * Pointer to destination DirectDrawGlobal structure
80 *
81 * @remarks.
82 * Only used internally in dxg.sys
83 * Missing some callbacks (VideoPort, DxApi, AGP)
84 *--*/
intDdGetAllDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl)85 VOID intDdGetAllDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl)
86 {
87     if (peDdGl->ddHalInfo.GetDriverInfo && peDdGl->ddHalInfo.dwFlags & DDHALINFO_GETDRIVERINFOSET)
88     {
89         intDdGetDriverInfo(peDdGl, GUID_KernelCaps, &peDdGl->ddKernelCaps, sizeof(peDdGl->ddKernelCaps), 0);
90         intDdGetDriverInfo(peDdGl, GUID_KernelCallbacks, &peDdGl->ddKernelCallbacks, sizeof(peDdGl->ddKernelCallbacks), 0);
91 
92         if (intDdGetDriverInfo(peDdGl, GUID_D3DCallbacks3, &peDdGl->d3dNtHalCallbacks3, sizeof(peDdGl->d3dNtHalCallbacks3), 0))
93             peDdGl->dwCallbackFlags |= EDDDGBL_D3DCALLBACKS3;
94 
95         if (intDdGetDriverInfo(peDdGl, GUID_ColorControlCallbacks, &peDdGl->ddColorControlCallbacks, sizeof(peDdGl->ddColorControlCallbacks), 0))
96             peDdGl->dwCallbackFlags |= EDDDGBL_COLORCONTROLCALLBACKS;
97 
98         if (intDdGetDriverInfo(peDdGl, GUID_MiscellaneousCallbacks, &peDdGl->ddMiscellanousCallbacks, sizeof(peDdGl->ddMiscellanousCallbacks), 0))
99             peDdGl->dwCallbackFlags |= EDDDGBL_MISCCALLBACKS;
100 
101         if (intDdGetDriverInfo(peDdGl, GUID_Miscellaneous2Callbacks, &peDdGl->ddMiscellanous2Callbacks, sizeof(peDdGl->ddMiscellanous2Callbacks), 0))
102             peDdGl->dwCallbackFlags |= EDDDGBL_MISC2CALLBACKS;
103 
104         if (intDdGetDriverInfo(peDdGl, GUID_NTCallbacks, &peDdGl->ddNtCallbacks, sizeof(peDdGl->ddNtCallbacks), 0) )
105             peDdGl->dwCallbackFlags |= EDDDGBL_NTCALLBACKS;
106 
107         if (intDdGetDriverInfo(peDdGl, GUID_DDMoreCaps, &peDdGl->ddMoreCaps, sizeof(peDdGl->ddMoreCaps), 0) )
108             peDdGl->dwCallbackFlags |= EDDDGBL_DDMORECAPS;
109 
110         if (intDdGetDriverInfo(peDdGl, GUID_NTPrivateDriverCaps, &peDdGl->ddNtPrivateDriverCaps, sizeof(peDdGl->ddNtPrivateDriverCaps), 0) )
111             peDdGl->dwCallbackFlags |= EDDDGBL_PRIVATEDRIVERCAPS;
112 
113         if (intDdGetDriverInfo(peDdGl, GUID_MotionCompCallbacks, &peDdGl->ddMotionCompCallbacks, sizeof(peDdGl->ddMotionCompCallbacks), 0) )
114             peDdGl->dwCallbackFlags |= EDDDGBL_MOTIONCOMPCALLBACKS;
115     }
116 }
117 
118 /*++
119 * @name intDdEnableDriver
120 * @implemented
121 *
122 * The function intDdEnableDriver is used internally in dxg.sys
123 * Fills in all EDD_DIRECTDRAW_GLOBAL structures and enables DirectDraw acceleration when possible
124 *
125 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
126 * Pointer to destination DirectDrawGlobal structure
127 *
128 * @remarks.
129 * Only used internally in dxg.sys
130 *--*/
intDdEnableDriver(PEDD_DIRECTDRAW_GLOBAL peDdGl)131 VOID intDdEnableDriver(PEDD_DIRECTDRAW_GLOBAL peDdGl)
132 {
133     PDRIVER_FUNCTIONS  DriverFunctions;
134     LPD3DNTHAL_GLOBALDRIVERDATA GlobalDriverData;
135     LPD3DNTHAL_CALLBACKS HalCallbacks;
136     PDD_D3DBUFCALLBACKS D3DBufCallbacks;
137 
138 
139     gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
140     DriverFunctions = (PDRIVER_FUNCTIONS)gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_DrvFuncs);
141 
142     // check if driver has DirectDraw functions
143     if ((!DriverFunctions->GetDirectDrawInfo)||(!DriverFunctions->EnableDirectDraw)||(!DriverFunctions->DisableDirectDraw))
144         peDdGl->dhpdev = 0;
145 
146 
147     // reset acceleration flag
148     peDdGl->fl = peDdGl->fl & 0xFFFFFFFE;
149 
150     // ask for structure sizes
151     if ((peDdGl->dhpdev)&&(DriverFunctions->GetDirectDrawInfo(peDdGl->dhpdev, &peDdGl->ddHalInfo, &peDdGl->dwNumHeaps, NULL, &peDdGl->dwNumFourCC, NULL)))
152     {
153         // allocate memory for DX data
154         if (peDdGl->dwNumHeaps)
155             peDdGl->pvmList = EngAllocMem(FL_ZERO_MEMORY, peDdGl->dwNumHeaps*sizeof(VIDEOMEMORY), TAG_GDDV);
156         if (peDdGl->dwNumFourCC)
157             peDdGl->pdwFourCC = EngAllocMem(FL_ZERO_MEMORY, peDdGl->dwNumFourCC * 4, TAG_GDDF);
158 
159         // get data from driver
160         if (!DriverFunctions->GetDirectDrawInfo(peDdGl->dhpdev, &peDdGl->ddHalInfo, &peDdGl->dwNumHeaps, peDdGl->pvmList, &peDdGl->dwNumFourCC, peDdGl->pdwFourCC))
161         {
162             // failed - cleanup and exit
163             if (peDdGl->pvmList)
164                 EngFreeMem(peDdGl->pvmList);
165             if (peDdGl->pdwFourCC)
166                 EngFreeMem(peDdGl->pdwFourCC);
167             gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
168             return;
169         }
170 
171         // check if we can enable DirectDraw acceleration
172         if ((peDdGl->ddHalInfo.vmiData.pvPrimary) &&
173             (DriverFunctions->EnableDirectDraw(peDdGl->dhpdev, &peDdGl->ddCallbacks, &peDdGl->ddSurfaceCallbacks, &peDdGl->ddPaletteCallbacks))&&
174             !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dd_flags) & CapOver_DisableD3DAccel)&&
175             (peDdGl->ddHalInfo.dwSize == sizeof(DD_HALINFO)))
176         {
177             GlobalDriverData = peDdGl->ddHalInfo.lpD3DGlobalDriverData;
178             HalCallbacks = peDdGl->ddHalInfo.lpD3DHALCallbacks;
179             D3DBufCallbacks = peDdGl->ddHalInfo.lpD3DHALCallbacks;
180 
181             if (GlobalDriverData && GlobalDriverData->dwSize == sizeof(D3DNTHAL_GLOBALDRIVERDATA))
182                 memcpy(&peDdGl->d3dNtGlobalDriverData, GlobalDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
183 
184             if (HalCallbacks && HalCallbacks->dwSize == sizeof(D3DNTHAL_CALLBACKS))
185                 memcpy(&peDdGl->d3dNtHalCallbacks, HalCallbacks, sizeof(D3DNTHAL_CALLBACKS));
186 
187             if (D3DBufCallbacks && D3DBufCallbacks->dwSize == sizeof(DD_D3DBUFCALLBACKS))
188                 memcpy(&peDdGl->d3dBufCallbacks, D3DBufCallbacks, sizeof(DD_D3DBUFCALLBACKS));
189 
190             intDdGetAllDriverInfo(peDdGl);
191 
192             // enable DirectDraw acceleration
193             peDdGl->fl |= 1;
194         }
195         else
196         {
197             // failed - cleanup and exit
198             if (peDdGl->pvmList)
199                 EngFreeMem(peDdGl->pvmList);
200             if (peDdGl->pdwFourCC)
201                 EngFreeMem(peDdGl->pdwFourCC);
202         }
203     }
204 
205     gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
206 }
207 
208 PVOID
209 FASTCALL
intDdCreateDirectDrawLocal(HDEV hDev)210 intDdCreateDirectDrawLocal(HDEV hDev)
211 {
212     PEDD_DIRECTDRAW_GLOBAL peDdGl = NULL;
213     PEDD_DIRECTDRAW_LOCAL peDdL = NULL;
214     PDD_ENTRY AllocRet;
215 
216     peDdGl = (PEDD_DIRECTDRAW_GLOBAL)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_eddg);
217 
218     AllocRet = DdHmgAlloc(sizeof(EDD_DIRECTDRAW_LOCAL), ObjType_DDLOCAL_TYPE, TRUE);
219     if (!AllocRet)
220         return NULL;
221 
222     peDdL = (PEDD_DIRECTDRAW_LOCAL)AllocRet->pobj;
223 
224     /* initialize DIRECTDRAW_LOCAL */
225     peDdL->peDirectDrawLocal_prev = peDdGl->peDirectDrawLocalList;
226     peDdL->hCreatorProcess = PsGetCurrentThreadProcessId();
227     peDdL->Process = PsGetCurrentProcess();
228 
229     // link DirectDrawGlobal and DirectDrawLocal
230     peDdGl->peDirectDrawLocalList = peDdL;
231     peDdL->peDirectDrawGlobal = peDdGl;
232     peDdL->peDirectDrawGlobal2 = peDdGl;
233 
234     gpEngFuncs.DxEngReferenceHdev(hDev);
235 
236     InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
237 
238     return peDdL->pobj.hHmgr;
239 }
240 
241 /*++
242 * @name DxDdCreateDirectDrawObject
243 * @implemented
244 *
245 * Function creates new DirectDraw object
246 *
247 * @param HDC hDC
248 * Device context handle
249 *
250 * @return
251 * Newly created DirectDraw object handle.
252 *
253 * @remarks.
254 * Missing all AGP stuff
255 *--*/
256 DWORD
257 NTAPI
DxDdCreateDirectDrawObject(HDC hDC)258 DxDdCreateDirectDrawObject(
259     HDC hDC)
260 {
261     PDC pDC = NULL;
262     HDEV hDev = NULL;
263     DWORD_PTR retVal = 0;
264 
265     pDC = gpEngFuncs.DxEngLockDC(hDC);
266     if (!pDC)
267         return 0;
268 
269     // get driver hDev from DC
270     hDev = (HDEV)gpEngFuncs.DxEngGetDCState(hDC, 3);
271     if (!hDev) {
272         gpEngFuncs.DxEngUnlockDC(pDC);
273         return 0;
274     }
275 
276     // is this primary display?
277     if (!gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_display))
278     {
279         gpEngFuncs.DxEngUnlockDC(pDC);
280         return 0;
281     }
282 
283     gpEngFuncs.DxEngLockHdev(hDev);
284 
285     // create object only for 8BPP and more
286     if (gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_DitherFmt) >= BMF_8BPP)
287         retVal = (DWORD_PTR)intDdCreateDirectDrawLocal(hDev);
288 
289     gpEngFuncs.DxEngUnlockHdev(hDev);
290     gpEngFuncs.DxEngUnlockDC(pDC);
291     return retVal;
292 }
293 
294 
295 /*++
296 * @name DxDdGetDriverInfo
297 * @implemented
298 *
299 * Function queries the driver for DirectDraw and Direct3D functionality
300 *
301 * @param HANDLE DdHandle
302 * Handle to DirectDraw object
303 *
304 * @param PDD_GETDRIVERINFODATA drvInfoData
305 * Pointer to in/out driver info data structure
306 *--*/
307 DWORD
308 NTAPI
DxDdGetDriverInfo(HANDLE DdHandle,PDD_GETDRIVERINFODATA drvInfoData)309 DxDdGetDriverInfo(HANDLE DdHandle, PDD_GETDRIVERINFODATA drvInfoData)
310 {
311     PEDD_DIRECTDRAW_LOCAL peDdL;
312     PEDD_DIRECTDRAW_GLOBAL peDdGl;
313     PVOID pInfo = NULL;
314     DWORD dwInfoSize = 0;
315     BYTE callbackStruct[1024];
316     DWORD RetVal = FALSE;
317 
318     peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(DdHandle, ObjType_DDLOCAL_TYPE, FALSE);
319     if (!peDdL)
320         return RetVal;
321 
322     peDdGl = peDdL->peDirectDrawGlobal2;
323 
324     // check VideoPort related callbacks
325     if (peDdGl->dwCallbackFlags & EDDDGBL_VIDEOPORTCALLBACKS)
326     {
327         if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_VideoPortCallbacks))
328         {
329             dwInfoSize = sizeof(DD_VIDEOPORTCALLBACKS);
330             pInfo = (VOID*)&peDdGl->ddVideoPortCallback;
331         }
332         if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_VideoPortCaps))
333         {
334             pInfo = (VOID*)peDdGl->lpDDVideoPortCaps;
335             dwInfoSize = 72 * peDdGl->ddHalInfo.ddCaps.dwMaxVideoPorts;
336         }
337         if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_D3DCallbacks3))
338         {
339             dwInfoSize = sizeof(D3DNTHAL_CALLBACKS3);
340             pInfo = (VOID*)&peDdGl->d3dNtHalCallbacks3;
341         }
342     }
343 
344     // check ColorControl related callbacks
345     if (peDdGl->dwCallbackFlags & EDDDGBL_COLORCONTROLCALLBACKS)
346     {
347         if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_ColorControlCallbacks))
348         {
349             dwInfoSize = sizeof(DD_COLORCONTROLCALLBACKS);
350             pInfo = (VOID*)&peDdGl->ddColorControlCallbacks;
351         }
352         if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_NTCallbacks))
353         {
354             dwInfoSize = sizeof(DD_NTCALLBACKS);
355             pInfo = (VOID*)&peDdGl->ddNtCallbacks;
356         }
357     }
358 
359     // check Miscellaneous callbacks
360     if (peDdGl->dwCallbackFlags & EDDDGBL_MISCCALLBACKS)
361     {
362         if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_MiscellaneousCallbacks))
363         {
364             dwInfoSize = sizeof(DD_MISCELLANEOUSCALLBACKS);
365             pInfo = (VOID*)&peDdGl->ddMiscellanousCallbacks;
366         }
367         if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_DDMoreCaps))
368         {
369             dwInfoSize = sizeof(DD_MORECAPS);
370             pInfo = &peDdGl->ddMoreCaps;
371         }
372     }
373 
374     if (peDdGl->dwCallbackFlags & EDDDGBL_MISC2CALLBACKS &&
375         InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_Miscellaneous2Callbacks))
376     {
377         dwInfoSize = sizeof(DD_MISCELLANEOUS2CALLBACKS);
378         pInfo = (VOID*)&peDdGl->ddMiscellanous2Callbacks;
379     }
380 
381     if (peDdGl->dwCallbackFlags & EDDDGBL_MOTIONCOMPCALLBACKS &&
382         InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_MotionCompCallbacks))
383     {
384         dwInfoSize = sizeof(DD_MOTIONCOMPCALLBACKS);
385         pInfo = (VOID*)&peDdGl->ddMotionCompCallbacks;
386     }
387 
388     if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_KernelCaps) )
389     {
390         dwInfoSize = sizeof(DD_KERNELCALLBACKS);
391         pInfo = &peDdGl->ddKernelCaps;
392     }
393 
394     if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_DDMoreSurfaceCaps))
395     {
396         dwInfoSize = sizeof(DDMORESURFACECAPS);
397         pInfo = &peDdGl->ddMoreSurfaceCaps;
398     }
399 
400     if (dwInfoSize && pInfo)
401     {
402         gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
403         intDdGetDriverInfo(peDdGl, drvInfoData->guidInfo, &callbackStruct, dwInfoSize, &dwInfoSize);
404         gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
405         memcpy(drvInfoData->lpvData, callbackStruct, dwInfoSize);
406     }
407 
408     InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
409 
410     return TRUE;
411 }
412 
413 /*++
414 * @name DxDdQueryDirectDrawObject
415 * @implemented
416 *
417 * Function queries the DirectDraw object for its functionality
418 *
419 * @return
420 * TRUE on success.
421 *--*/
422 BOOL
423 NTAPI
DxDdQueryDirectDrawObject(HANDLE DdHandle,DD_HALINFO * pDdHalInfo,DWORD * pCallBackFlags,LPD3DNTHAL_CALLBACKS pd3dNtHalCallbacks,LPD3DNTHAL_GLOBALDRIVERDATA pd3dNtGlobalDriverData,PDD_D3DBUFCALLBACKS pd3dBufCallbacks,LPDDSURFACEDESC pTextureFormats,DWORD * p8,VIDEOMEMORY * p9,DWORD * pdwNumFourCC,DWORD * pdwFourCC)424 DxDdQueryDirectDrawObject(
425     HANDLE DdHandle,
426     DD_HALINFO* pDdHalInfo,
427     DWORD* pCallBackFlags,
428     LPD3DNTHAL_CALLBACKS pd3dNtHalCallbacks,
429     LPD3DNTHAL_GLOBALDRIVERDATA pd3dNtGlobalDriverData,
430     PDD_D3DBUFCALLBACKS pd3dBufCallbacks,
431     LPDDSURFACEDESC pTextureFormats,
432     DWORD* p8,
433     VIDEOMEMORY* p9,
434     DWORD* pdwNumFourCC,
435     DWORD* pdwFourCC)
436 {
437     PEDD_DIRECTDRAW_LOCAL peDdL;
438     PEDD_DIRECTDRAW_GLOBAL peDdGl;
439     BOOL RetVal = FALSE;
440 
441     if (!DdHandle)
442         return RetVal;
443 
444     if (!pDdHalInfo)
445         return RetVal;
446 
447     if (!gpEngFuncs.DxEngScreenAccessCheck())
448         return RetVal;
449 
450     peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(DdHandle, ObjType_DDLOCAL_TYPE, FALSE);
451     if (peDdL)
452     {
453         peDdGl = peDdL->peDirectDrawGlobal2;
454         gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
455 
456         memcpy(pDdHalInfo, &peDdGl->ddHalInfo, sizeof(DD_HALINFO));
457 
458         if (pCallBackFlags)
459         {
460             *(DWORD*)pCallBackFlags = peDdGl->ddCallbacks.dwFlags;
461             *(DWORD*)((ULONG_PTR)pCallBackFlags + 4) = peDdGl->ddSurfaceCallbacks.dwFlags;
462             *(DWORD*)((ULONG_PTR)pCallBackFlags + 8) = peDdGl->ddPaletteCallbacks.dwFlags;
463         }
464 
465         if (pd3dNtHalCallbacks)
466             memcpy(pd3dNtHalCallbacks, &peDdGl->d3dNtHalCallbacks, sizeof(peDdGl->d3dNtHalCallbacks));
467 
468         if (pd3dNtGlobalDriverData)
469             memcpy(pd3dNtGlobalDriverData, &peDdGl->d3dNtGlobalDriverData, sizeof(peDdGl->d3dNtGlobalDriverData));
470 
471         if (pd3dBufCallbacks)
472             memcpy(pd3dBufCallbacks, &peDdGl->d3dBufCallbacks, sizeof(peDdGl->d3dBufCallbacks));
473 
474         if (pTextureFormats)
475             memcpy(pTextureFormats, &peDdGl->d3dNtGlobalDriverData.lpTextureFormats, peDdGl->d3dNtGlobalDriverData.dwNumTextureFormats * sizeof(DDSURFACEDESC2));
476 
477         if (pdwNumFourCC)
478             *pdwNumFourCC = peDdGl->dwNumFourCC;
479 
480         if (pdwFourCC)
481             memcpy(pdwFourCC, &peDdGl->pdwFourCC, 4 * peDdGl->dwNumFourCC);
482 
483         RetVal = TRUE;
484 
485         gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
486 
487         InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
488     }
489 
490     return RetVal;
491 }
492 
493 /*++
494 * @name DxDdEnableDirectDraw
495 * @implemented
496 *
497 * Function enables DirectDraw
498 *
499 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
500 * Pointer to destination DirectDrawGlobal structure
501 *--*/
502 BOOL
503 NTAPI
DxDdEnableDirectDraw(HANDLE hDev,BOOL arg2)504 DxDdEnableDirectDraw(HANDLE hDev, BOOL arg2/*What for?*/)
505 {
506     PEDD_DIRECTDRAW_GLOBAL peDdGl = NULL;
507 
508     if (gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_display))
509     {
510         peDdGl = (PEDD_DIRECTDRAW_GLOBAL)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_eddg);
511         peDdGl->hDev = hDev;
512         peDdGl->bSuspended = FALSE;
513         peDdGl->dhpdev = (PVOID)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_dhpdev);
514         intDdEnableDriver(peDdGl);
515         return TRUE;
516     }
517 
518     return FALSE;
519 }
520 
521 /*++
522 * @name DxDdReenableDirectDrawObject
523 * @implemented
524 *
525 * Function re-enables DirectDraw object after mode switch
526 *
527 * @param HANDLE DdHandle
528 * DirectDraw object handle
529 *
530 * @param PVOID p2
531 * ???
532 *
533 * @return
534 * TRUE on success.
535 *
536 * @remarks
537 * Missing all AGP stuff and second parameter handling
538 *--*/
539 DWORD
540 NTAPI
DxDdReenableDirectDrawObject(HANDLE DdHandle,PVOID p2)541 DxDdReenableDirectDrawObject(
542     HANDLE DdHandle,
543     PVOID p2)
544 {
545     PEDD_DIRECTDRAW_LOCAL peDdL;
546     PEDD_DIRECTDRAW_GLOBAL peDdGl;
547     HDC hDC;
548     DWORD RetVal = FALSE;
549 
550     peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(DdHandle, ObjType_DDLOCAL_TYPE, FALSE);
551 
552     if (!peDdL)
553         return RetVal;
554 
555     peDdGl = peDdL->peDirectDrawGlobal2;
556 
557     hDC = gpEngFuncs.DxEngGetDesktopDC(0, FALSE, FALSE);
558 
559     gpEngFuncs.DxEngLockShareSem();
560     gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
561 
562     if (peDdGl->fl & 1 &&
563         gpEngFuncs.DxEngGetDCState(hDC, 2) != 1 &&
564         !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_OpenRefs)) &&
565         !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_disable)) &&
566         !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dd_locks)) &&
567         gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_DitherFmt) >= BMF_8BPP)
568     {
569         // reset acceleration and suspend flags
570         peDdGl->fl &= 0xFFFFFFFD;
571         peDdGl->bSuspended = 0;
572         peDdGl->dhpdev = (PVOID)gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dhpdev);
573 
574         RetVal = TRUE;
575         // FIXME AGP Stuff
576     }
577 
578     gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
579     gpEngFuncs.DxEngUnlockShareSem();
580 
581     InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
582 
583     return RetVal;
584 }
585 
586 PEDD_SURFACE
587 NTAPI
intDdCreateNewSurfaceObject(PEDD_DIRECTDRAW_LOCAL peDdL,HANDLE hDirectDrawLocal,PDD_SURFACE_GLOBAL pDdSurfGlob,PDD_SURFACE_LOCAL pDdSurfLoc,PDD_SURFACE_MORE pDdSurfMore)588 intDdCreateNewSurfaceObject(PEDD_DIRECTDRAW_LOCAL peDdL, HANDLE hDirectDrawLocal, PDD_SURFACE_GLOBAL pDdSurfGlob, PDD_SURFACE_LOCAL pDdSurfLoc, PDD_SURFACE_MORE pDdSurfMore)
589 {
590     PEDD_SURFACE pSurface = NULL;
591 
592     // first check if we can assign it from current ddHandle
593     if (hDirectDrawLocal)
594     {
595         pSurface = (PEDD_SURFACE)DdHmgLock(hDirectDrawLocal, ObjType_DDSURFACE_TYPE, FALSE);
596         // check if surface is locked and belongs to correct DirectDrawLocal
597         if ((pSurface)&&((pSurface->peDirectDrawLocal != peDdL)||(!pSurface->hSecure)))
598         {
599             InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
600             return NULL;
601         }
602     }
603 
604     // if surface not found from ddHandle or ddHandle not provided
605     if (!pSurface)
606     {
607         // create new surface object
608         pSurface = (PEDD_SURFACE)DdHmgAlloc(sizeof(EDD_SURFACE), ObjType_DDSURFACE_TYPE, TRUE);
609         if (pSurface)
610         {
611             pSurface->ddsSurfaceLocal.lpGbl = &pSurface->ddsSurfaceGlobal;
612             pSurface->ddsSurfaceLocal.lpSurfMore = &pSurface->ddsSurfaceMore;
613             pSurface->ddsSurfaceInt.lpLcl = &pSurface->ddsSurfaceLocal;
614             pSurface->peDirectDrawLocal = peDdL;
615             pSurface->peDirectDrawGlobalNext = peDdL->peDirectDrawGlobal2;
616             pSurface->ldev = gpEngFuncs.DxEngGetHdevData(pSurface->peDirectDrawGlobalNext->hDev, DxEGShDevData_ldev);
617             pSurface->gdev = gpEngFuncs.DxEngGetHdevData(pSurface->peDirectDrawGlobalNext->hDev, DxEGShDevData_GDev);
618             pSurface->hSecure = (VOID*)1;
619         }
620     }
621 
622     if (pSurface)
623     {
624         pSurface->ddsSurfaceGlobal.fpVidMem = pDdSurfGlob->fpVidMem;
625         pSurface->ddsSurfaceGlobal.lPitch = pDdSurfGlob->lPitch;
626         pSurface->ddsSurfaceGlobal.wWidth = pDdSurfGlob->wWidth;
627         pSurface->ddsSurfaceGlobal.wHeight = pDdSurfGlob->wHeight;
628         pSurface->wWidth = pDdSurfGlob->wWidth;
629         pSurface->wHeight = pDdSurfGlob->wHeight;
630         memcpy(&pSurface->ddsSurfaceGlobal.ddpfSurface, &pDdSurfGlob->ddpfSurface, sizeof(pSurface->ddsSurfaceGlobal.ddpfSurface));
631         pSurface->ddsSurfaceLocal.ddsCaps.dwCaps = pDdSurfLoc->ddsCaps.dwCaps;
632         pSurface->ddsSurfaceMore.ddsCapsEx.dwCaps2 = pDdSurfMore->ddsCapsEx.dwCaps2;
633         pSurface->ddsSurfaceMore.ddsCapsEx.dwCaps3 = pDdSurfMore->ddsCapsEx.dwCaps3;
634         pSurface->ddsSurfaceMore.ddsCapsEx.dwCaps4 = pDdSurfMore->ddsCapsEx.dwCaps4;
635         pSurface->ddsSurfaceMore.dwSurfaceHandle = pDdSurfMore->dwSurfaceHandle;
636         pSurface->hSecure = (VOID*)1;
637 
638         peDdL->peSurface_DdList = pSurface;
639         peDdL->hSurface = (ULONG_PTR)pSurface->pobj.hHmgr;
640     }
641 
642     return pSurface;
643 }
644 
645 HANDLE
646 NTAPI
DxDdCreateSurfaceObject(HANDLE hDirectDrawLocal,HANDLE hSurface,PDD_SURFACE_LOCAL puSurfaceLocal,PDD_SURFACE_MORE puSurfaceMore,PDD_SURFACE_GLOBAL puSurfaceGlobal,BOOL bComplete)647 DxDdCreateSurfaceObject(HANDLE hDirectDrawLocal,
648                         HANDLE hSurface,
649                         PDD_SURFACE_LOCAL puSurfaceLocal,
650                         PDD_SURFACE_MORE puSurfaceMore,
651                         PDD_SURFACE_GLOBAL puSurfaceGlobal,
652                         BOOL bComplete)
653 {
654     HANDLE RetVal = FALSE;
655     PEDD_DIRECTDRAW_LOCAL peDdL = NULL;
656     PEDD_SURFACE pDdSurface = NULL;
657 
658     peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(hDirectDrawLocal, ObjType_DDLOCAL_TYPE, FALSE);
659 
660     if (!peDdL)
661         return RetVal;
662 
663     pDdSurface = intDdCreateNewSurfaceObject(peDdL, hSurface, puSurfaceGlobal, puSurfaceLocal, puSurfaceMore);
664     if (!pDdSurface)
665     {
666         InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
667         return RetVal;
668     }
669 
670     RetVal = pDdSurface->pobj.hHmgr;
671 
672     InterlockedDecrement((VOID*)&pDdSurface->pobj.cExclusiveLock);
673     InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
674 
675     return RetVal;
676 }
677