xref: /reactos/win32ss/gdi/gdi32/misc/gdientry.c (revision 84344399)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS GDI32
4  * PURPOSE:          GDI DirectX interface
5  * FILE:             win32ss/gdi/gdi32/misc/gdientry.c
6  * PROGRAMERS:       Alex Ionescu (alex@relsoft.net)
7  *                   Magnus Olsen (magnus@greatlord.com)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <precomp.h>
13 
14 #include <stdio.h>
15 #include <d3dhal.h>
16 
17 /* DATA **********************************************************************/
18 
19 HANDLE ghDirectDraw;
20 ULONG gcDirectDraw;
21 
22 #define GetDdHandle(Handle) ((HANDLE)Handle ? (HANDLE)Handle : ghDirectDraw)
23 
24 
25 
26 /* CALLBACKS *****************************************************************/
27 
28 /*
29  * @implemented
30  *
31  * DdAddAttachedSurface
32  */
33 DWORD
34 WINAPI
35 DdAddAttachedSurface(LPDDHAL_ADDATTACHEDSURFACEDATA Attach)
36 {
37     /* Call win32k */
38     return NtGdiDdAddAttachedSurface((HANDLE)Attach->lpDDSurface->hDDSurface,
39                                      (HANDLE)Attach->lpSurfAttached->hDDSurface,
40                                      (PDD_ADDATTACHEDSURFACEDATA)Attach);
41 }
42 
43 /*
44  * @implemented
45  *
46  * DdBlt
47  */
48 DWORD
49 WINAPI
50 DdBlt(LPDDHAL_BLTDATA Blt)
51 {
52     HANDLE Surface = 0;
53 
54     /* Use the right surface */
55     if (Blt->lpDDSrcSurface)
56     {
57         Surface = (HANDLE)Blt->lpDDSrcSurface->hDDSurface;
58     }
59 
60     /* Call win32k */
61     return NtGdiDdBlt((HANDLE)Blt->lpDDDestSurface->hDDSurface, Surface, (PDD_BLTDATA)Blt);
62 }
63 
64 /*
65  * @implemented
66  *
67  * DdDestroySurface
68  */
69 DWORD
70 WINAPI
71 DdDestroySurface(LPDDHAL_DESTROYSURFACEDATA pDestroySurface)
72 {
73     DWORD Return = DDHAL_DRIVER_NOTHANDLED;
74     BOOL RealDestroy;
75 
76     if (pDestroySurface->lpDDSurface->hDDSurface)
77     {
78         /* Check if we shoudl really destroy it */
79         RealDestroy = !(pDestroySurface->lpDDSurface->dwFlags & DDRAWISURF_DRIVERMANAGED) ||
80                       !(pDestroySurface->lpDDSurface->dwFlags & DDRAWISURF_INVALID);
81 
82         /* Call win32k */
83         Return = NtGdiDdDestroySurface((HANDLE)pDestroySurface->lpDDSurface->hDDSurface, RealDestroy);
84     }
85 
86     return Return;
87 }
88 
89 /*
90  * @implemented
91  *
92  * DdFlip
93  */
94 DWORD
95 WINAPI
96 DdFlip(LPDDHAL_FLIPDATA Flip)
97 {
98     /* Note :
99     * See http://msdn2.microsoft.com/en-us/library/ms794213.aspx and
100     * http://msdn2.microsoft.com/en-us/library/ms792675.aspx
101     */
102 
103     HANDLE hSurfaceCurrentLeft = NULL;
104     HANDLE hSurfaceTargetLeft = NULL;
105 
106     /* Auto flip off or on */
107     if (Flip->dwFlags & DDFLIP_STEREO )
108     {
109         if ( (Flip->lpSurfTargLeft) &&
110                 (Flip->lpSurfCurrLeft))
111         {
112             /* Auto flip on */
113             hSurfaceTargetLeft = (HANDLE) Flip->lpSurfTargLeft->hDDSurface;
114             hSurfaceCurrentLeft = (HANDLE) Flip->lpSurfCurrLeft->hDDSurface;
115         }
116     }
117 
118     /* Call win32k */
119     return NtGdiDdFlip( (HANDLE) Flip->lpSurfCurr->hDDSurface,
120                         (HANDLE) Flip->lpSurfTarg->hDDSurface,
121                         hSurfaceCurrentLeft,
122                         hSurfaceTargetLeft,
123                         (PDD_FLIPDATA) Flip);
124 }
125 
126 /*
127  * @implemented
128  *
129  * DdLock
130  */
131 DWORD
132 WINAPI
133 DdLock(LPDDHAL_LOCKDATA Lock)
134 {
135 
136     /* Call win32k */
137     return NtGdiDdLock((HANDLE)Lock->lpDDSurface->hDDSurface,
138                        (PDD_LOCKDATA)Lock,
139                        (HANDLE)Lock->lpDDSurface->hDC);
140 }
141 
142 /*
143  * @implemented
144  *
145  * DdUnlock
146  */
147 DWORD
148 WINAPI
149 DdUnlock(LPDDHAL_UNLOCKDATA Unlock)
150 {
151     /* Call win32k */
152     return NtGdiDdUnlock((HANDLE)Unlock->lpDDSurface->hDDSurface,
153                          (PDD_UNLOCKDATA)Unlock);
154 }
155 
156 /*
157  * @implemented
158  *
159  * DdGetBltStatus
160  */
161 DWORD
162 WINAPI
163 DdGetBltStatus(LPDDHAL_GETBLTSTATUSDATA GetBltStatus)
164 {
165     /* Call win32k */
166     return NtGdiDdGetBltStatus((HANDLE)GetBltStatus->lpDDSurface->hDDSurface,
167                                (PDD_GETBLTSTATUSDATA)GetBltStatus);
168 }
169 
170 /*
171  * @implemented
172  *
173  * DdGetBltStatus
174  */
175 DWORD
176 WINAPI
177 DdGetFlipStatus(LPDDHAL_GETFLIPSTATUSDATA GetFlipStatus)
178 {
179     /* Call win32k */
180     return NtGdiDdGetFlipStatus((HANDLE)GetFlipStatus->lpDDSurface->hDDSurface,
181                                 (PDD_GETFLIPSTATUSDATA)GetFlipStatus);
182 }
183 
184 /*
185  * @implemented
186  *
187  * DdUpdateOverlay
188  */
189 DWORD
190 WINAPI
191 DdUpdateOverlay(LPDDHAL_UPDATEOVERLAYDATA UpdateOverlay)
192 {
193 
194     /* We have to handle this manually here */
195     if (UpdateOverlay->dwFlags & DDOVER_KEYDEST)
196     {
197         /* Use the override */
198         UpdateOverlay->dwFlags &= ~DDOVER_KEYDEST;
199         UpdateOverlay->dwFlags |=  DDOVER_KEYDESTOVERRIDE;
200 
201         /* Set the overlay */
202         UpdateOverlay->overlayFX.dckDestColorkey =
203             UpdateOverlay->lpDDDestSurface->ddckCKDestOverlay;
204     }
205     if (UpdateOverlay->dwFlags & DDOVER_KEYSRC)
206     {
207         /* Use the override */
208         UpdateOverlay->dwFlags &= ~DDOVER_KEYSRC;
209         UpdateOverlay->dwFlags |=  DDOVER_KEYSRCOVERRIDE;
210 
211         /* Set the overlay */
212         UpdateOverlay->overlayFX.dckSrcColorkey =
213             UpdateOverlay->lpDDSrcSurface->ddckCKSrcOverlay;
214     }
215 
216     /* Call win32k */
217     return NtGdiDdUpdateOverlay((HANDLE)UpdateOverlay->lpDDDestSurface->hDDSurface,
218                                 (HANDLE)UpdateOverlay->lpDDSrcSurface->hDDSurface,
219                                 (PDD_UPDATEOVERLAYDATA)UpdateOverlay);
220 }
221 
222 /*
223  * @implemented
224  *
225  * DdSetOverlayPosition
226  */
227 DWORD
228 WINAPI
229 DdSetOverlayPosition(LPDDHAL_SETOVERLAYPOSITIONDATA SetOverlayPosition)
230 {
231     /* Call win32k */
232     return NtGdiDdSetOverlayPosition( (HANDLE)SetOverlayPosition->lpDDSrcSurface->hDDSurface,
233                                       (HANDLE)SetOverlayPosition->lpDDDestSurface->hDDSurface,
234                                       (PDD_SETOVERLAYPOSITIONDATA) SetOverlayPosition);
235 }
236 
237 /*
238  * @implemented
239  *
240  * DdWaitForVerticalBlank
241  */
242 DWORD
243 WINAPI
244 DdWaitForVerticalBlank(LPDDHAL_WAITFORVERTICALBLANKDATA WaitForVerticalBlank)
245 {
246     /* Call win32k */
247     return NtGdiDdWaitForVerticalBlank(GetDdHandle(
248                                            WaitForVerticalBlank->lpDD->hDD),
249                                        (PDD_WAITFORVERTICALBLANKDATA)
250                                        WaitForVerticalBlank);
251 }
252 
253 /*
254  * @implemented
255  *
256  * DdCanCreateSurface
257  */
258 DWORD
259 WINAPI
260 DdCanCreateSurface(LPDDHAL_CANCREATESURFACEDATA CanCreateSurface)
261 {
262     /*
263      * Note : This functions are basic same, in win32k
264      * NtGdiDdCanCreateD3DBuffer and  NtGdiDdCanCreateSurface are mergs
265      * toghter in win32k at end and retrurn same data, it is still sepreated
266      * at user mode but in kmode it is not.
267      */
268 
269     /* Call win32k */
270     return NtGdiDdCanCreateSurface(GetDdHandle(CanCreateSurface->lpDD->hDD),
271                                    (PDD_CANCREATESURFACEDATA)CanCreateSurface);
272 }
273 
274 /*
275  * @implemented
276  *
277  * DdCreateSurface
278  */
279 DWORD
280 WINAPI
281 DdCreateSurface(LPDDHAL_CREATESURFACEDATA pCreateSurface)
282 {
283     DWORD Return = DDHAL_DRIVER_NOTHANDLED;
284     ULONG SurfaceCount = pCreateSurface->dwSCnt;
285     DD_SURFACE_LOCAL DdSurfaceLocal;
286     DD_SURFACE_MORE DdSurfaceMore;
287     DD_SURFACE_GLOBAL DdSurfaceGlobal;
288 
289     HANDLE hPrevSurface, hSurface;
290 
291     PDD_SURFACE_LOCAL pDdSurfaceLocal = NULL;
292     PDD_SURFACE_MORE pDdSurfaceMore = NULL;
293     PDD_SURFACE_GLOBAL pDdSurfaceGlobal = NULL;
294 
295     PDD_SURFACE_LOCAL ptmpDdSurfaceLocal = NULL;
296     PDD_SURFACE_MORE ptmpDdSurfaceMore = NULL;
297     PDD_SURFACE_GLOBAL ptmpDdSurfaceGlobal = NULL;
298     PHANDLE phSurface = NULL, puhSurface = NULL;
299     ULONG i;
300     LPDDSURFACEDESC pSurfaceDesc = NULL;
301 
302     /* TODO: Optimize speed. Most games/dx apps/programs do not want one surface, they want at least two.
303      * So we need increase the stack to contain two surfaces instead of one. This will increase
304      * the speed of the apps when allocating buffers. How to increase the surface stack space:
305      * we need to create a struct for DD_SURFACE_LOCAL DdSurfaceLocal, DD_SURFACE_MORE DdSurfaceMore
306      * DD_SURFACE_GLOBAL DdSurfaceGlobal, HANDLE hPrevSurface, hSurface like
307      * struct { DD_SURFACE_LOCAL DdSurfaceLocal1, DD_SURFACE_LOCAL DdSurfaceLocal2 }
308      * in a way that it may contain two surfaces, maybe even four. We need to watch what is most common before
309      * we create the size. Activate this IF when you start doing the optimze and please also
310      * take reports from users which value they got here.
311      */
312 #if 1
313     {
314         char buffer[1024];
315         \
316         sprintf ( buffer, "Function %s : Optimze max to %d Surface ? (%s:%d)\n", __FUNCTION__, (int)SurfaceCount,__FILE__,__LINE__ );
317         OutputDebugStringA(buffer);
318     }
319 #endif
320 
321     /* Check how many surfaces there are */
322     if (SurfaceCount != 1)
323     {
324         /* We got more than one surface, so we need to allocate memory for them */
325         pDdSurfaceLocal = (PDD_SURFACE_LOCAL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (sizeof(DD_SURFACE_LOCAL) * SurfaceCount ));
326         pDdSurfaceMore = (PDD_SURFACE_MORE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (sizeof(DD_SURFACE_MORE) * SurfaceCount ));
327         pDdSurfaceGlobal = (PDD_SURFACE_GLOBAL)  HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (sizeof(DD_SURFACE_GLOBAL) * SurfaceCount ));
328         phSurface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (sizeof(HANDLE) * SurfaceCount ));
329         puhSurface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (sizeof(HANDLE) * SurfaceCount ));
330 
331         /* Check if we successfully allocated all memory we need */
332         if ((pDdSurfaceLocal == NULL) || (pDdSurfaceMore == NULL) || (pDdSurfaceGlobal == NULL) || (phSurface == NULL) || (puhSurface == NULL))
333         {
334             pCreateSurface->ddRVal = DDERR_OUTOFMEMORY;
335 
336             if ( pDdSurfaceLocal != NULL )
337             {
338                 HeapFree(GetProcessHeap(), 0, pDdSurfaceLocal);
339             }
340 
341             if ( pDdSurfaceMore != NULL )
342             {
343                 HeapFree(GetProcessHeap(), 0, pDdSurfaceMore);
344             }
345 
346             if ( pDdSurfaceGlobal != NULL )
347             {
348                 HeapFree(GetProcessHeap(), 0, pDdSurfaceGlobal);
349             }
350 
351             if ( phSurface != NULL )
352             {
353                 HeapFree(GetProcessHeap(), 0, phSurface);
354             }
355 
356             if ( puhSurface != NULL )
357             {
358                 HeapFree(GetProcessHeap(), 0, puhSurface);
359             }
360 
361             return DDHAL_DRIVER_HANDLED;
362         }
363     }
364     else
365     {
366         /* We'll use what we have on the stack */
367         pDdSurfaceLocal = &DdSurfaceLocal;
368         pDdSurfaceMore = &DdSurfaceMore;
369         pDdSurfaceGlobal = &DdSurfaceGlobal;
370         phSurface = &hPrevSurface;
371         puhSurface = &hSurface;
372 
373         /* Clear the structures */
374         RtlZeroMemory(&DdSurfaceLocal, sizeof(DdSurfaceLocal));
375         RtlZeroMemory(&DdSurfaceGlobal, sizeof(DdSurfaceGlobal));
376         RtlZeroMemory(&DdSurfaceMore, sizeof(DdSurfaceMore));
377     }
378 
379     /* check if we got a surface or not */
380     if (SurfaceCount!=0)
381     {
382         /* Loop for each surface */
383         ptmpDdSurfaceGlobal = pDdSurfaceGlobal;
384         ptmpDdSurfaceLocal = pDdSurfaceLocal;
385         ptmpDdSurfaceMore = pDdSurfaceMore;
386         pSurfaceDesc = pCreateSurface->lpDDSurfaceDesc;
387 
388         for (i = 0; i < SurfaceCount; i++)
389         {
390             LPDDRAWI_DDRAWSURFACE_LCL lcl = pCreateSurface->lplpSList[i];
391             LPDDRAWI_DDRAWSURFACE_GBL gpl = pCreateSurface->lplpSList[i]->lpGbl;
392 
393             phSurface[i] = (HANDLE)lcl->hDDSurface;
394             ptmpDdSurfaceLocal->ddsCaps.dwCaps = lcl->ddsCaps.dwCaps;
395 
396             ptmpDdSurfaceLocal->dwFlags = (ptmpDdSurfaceLocal->dwFlags &
397                                            (0xB0000000 | DDRAWISURF_INMASTERSPRITELIST |
398                                             DDRAWISURF_HELCB | DDRAWISURF_FRONTBUFFER |
399                                             DDRAWISURF_BACKBUFFER | DDRAWISURF_INVALID |
400                                             DDRAWISURF_DCIBUSY | DDRAWISURF_DCILOCK)) |
401                                           (lcl->dwFlags & DDRAWISURF_DRIVERMANAGED);
402 
403             ptmpDdSurfaceGlobal->wWidth = gpl->wWidth;
404             ptmpDdSurfaceGlobal->wHeight = gpl->wHeight;
405             ptmpDdSurfaceGlobal->lPitch = gpl->lPitch;
406             ptmpDdSurfaceGlobal->fpVidMem = gpl->fpVidMem;
407             ptmpDdSurfaceGlobal->dwBlockSizeX = gpl->dwBlockSizeX;
408             ptmpDdSurfaceGlobal->dwBlockSizeY = gpl->dwBlockSizeY;
409 
410             if (lcl->dwFlags & DDRAWISURF_HASPIXELFORMAT)
411             {
412                 RtlCopyMemory( &ptmpDdSurfaceGlobal->ddpfSurface ,
413                                &gpl->ddpfSurface,
414                                sizeof(DDPIXELFORMAT));
415 
416                 ptmpDdSurfaceGlobal->ddpfSurface.dwSize = sizeof(DDPIXELFORMAT);
417             }
418             else
419             {
420                 RtlCopyMemory( &ptmpDdSurfaceGlobal->ddpfSurface ,
421                                &gpl->lpDD->vmiData.ddpfDisplay,
422                                sizeof(DDPIXELFORMAT));
423             }
424 
425             /* Note if lcl->lpSurfMore is NULL zero out
426              * ptmpDdSurfaceMore->ddsCapsEx.dwCaps2,
427              * dwCaps3, dwCaps4, ptmpDdSurfaceMore->dwSurfaceHandle
428              */
429             if (lcl->lpSurfMore)
430             {
431                 ptmpDdSurfaceMore->ddsCapsEx.dwCaps2 = lcl->lpSurfMore->ddsCapsEx.dwCaps2;
432                 ptmpDdSurfaceMore->ddsCapsEx.dwCaps3 = lcl->lpSurfMore->ddsCapsEx.dwCaps3;
433                 ptmpDdSurfaceMore->ddsCapsEx.dwCaps4 = lcl->lpSurfMore->ddsCapsEx.dwCaps4;
434                 ptmpDdSurfaceMore->dwSurfaceHandle = lcl->lpSurfMore->dwSurfaceHandle;
435             }
436 
437 
438             /* count to next SurfaceCount */
439             ptmpDdSurfaceGlobal = (PDD_SURFACE_GLOBAL) (((PBYTE) ((ULONG_PTR) ptmpDdSurfaceGlobal)) + sizeof(DD_SURFACE_GLOBAL));
440             ptmpDdSurfaceLocal = (PDD_SURFACE_LOCAL) (((PBYTE) ((ULONG_PTR) ptmpDdSurfaceLocal)) + sizeof(DD_SURFACE_LOCAL));
441             ptmpDdSurfaceMore = (PDD_SURFACE_MORE) (((PBYTE) ((ULONG_PTR) ptmpDdSurfaceMore)) + sizeof(DD_SURFACE_MORE));
442         }
443     }
444 
445     /* Call win32k now */
446     pCreateSurface->ddRVal = DDERR_GENERIC;
447 
448     Return = NtGdiDdCreateSurface(GetDdHandle(pCreateSurface->lpDD->hDD),
449                                   (HANDLE *)phSurface,
450                                   pSurfaceDesc,
451                                   pDdSurfaceGlobal,
452                                   pDdSurfaceLocal,
453                                   pDdSurfaceMore,
454                                   (PDD_CREATESURFACEDATA)pCreateSurface,
455                                   puhSurface);
456 
457     if (SurfaceCount == 0)
458     {
459         pCreateSurface->ddRVal = DDERR_GENERIC;
460     }
461     else
462     {
463         ptmpDdSurfaceMore = pDdSurfaceMore;
464         ptmpDdSurfaceGlobal = pDdSurfaceGlobal;
465         ptmpDdSurfaceLocal = pDdSurfaceLocal;
466 
467         for (i=0; i<SurfaceCount; i++)
468         {
469             LPDDRAWI_DDRAWSURFACE_LCL lcl = pCreateSurface->lplpSList[i];
470             LPDDRAWI_DDRAWSURFACE_GBL gpl = pCreateSurface->lplpSList[i]->lpGbl;
471 
472             gpl->lPitch = ptmpDdSurfaceGlobal->lPitch;
473             gpl->fpVidMem = ptmpDdSurfaceGlobal->fpVidMem;
474             gpl->dwBlockSizeX = ptmpDdSurfaceGlobal->dwBlockSizeX;
475             gpl->dwBlockSizeY = ptmpDdSurfaceGlobal->dwBlockSizeY;
476 
477             if (lcl->dwFlags & DDRAWISURF_HASPIXELFORMAT)
478             {
479                 RtlCopyMemory( &gpl->ddpfSurface, &ptmpDdSurfaceGlobal->ddpfSurface , sizeof(DDPIXELFORMAT));
480             }
481 
482             if (pCreateSurface->ddRVal != DD_OK)
483             {
484                 gpl->fpVidMem = 0;
485                 if (lcl->hDDSurface)
486                 {
487                     NtGdiDdDeleteSurfaceObject( (HANDLE)lcl->hDDSurface);
488                 }
489                 lcl->hDDSurface = 0;
490             }
491             else
492             {
493 
494                 lcl->hDDSurface = (ULONG_PTR) puhSurface[i];
495             }
496 
497             lcl->ddsCaps.dwCaps = ptmpDdSurfaceLocal->ddsCaps.dwCaps;
498             if (lcl->lpSurfMore)
499             {
500                 lcl->lpSurfMore->ddsCapsEx.dwCaps2 = ptmpDdSurfaceMore->ddsCapsEx.dwCaps2;
501                 lcl->lpSurfMore->ddsCapsEx.dwCaps3 = ptmpDdSurfaceMore->ddsCapsEx.dwCaps3;
502                 lcl->lpSurfMore->ddsCapsEx.dwCaps4 = ptmpDdSurfaceMore->ddsCapsEx.dwCaps4;
503             }
504 
505             /* count to next SurfaceCount */
506             ptmpDdSurfaceGlobal = (PDD_SURFACE_GLOBAL) (((PBYTE) ((ULONG_PTR) ptmpDdSurfaceGlobal)) + sizeof(DD_SURFACE_GLOBAL));
507             ptmpDdSurfaceLocal = (PDD_SURFACE_LOCAL) (((PBYTE) ((ULONG_PTR) ptmpDdSurfaceLocal)) + sizeof(DD_SURFACE_LOCAL));
508             ptmpDdSurfaceMore = (PDD_SURFACE_MORE) (((PBYTE) ((ULONG_PTR) ptmpDdSurfaceMore)) + sizeof(DD_SURFACE_MORE));
509         }
510     }
511 
512     /* Check if we have to free all our local allocations */
513     if (SurfaceCount > 1)
514     {
515         if ( pDdSurfaceLocal != NULL )
516         {
517             HeapFree(GetProcessHeap(), 0, pDdSurfaceLocal);
518         }
519 
520         if ( pDdSurfaceMore != NULL )
521         {
522             HeapFree(GetProcessHeap(), 0, pDdSurfaceMore);
523         }
524 
525         if ( pDdSurfaceGlobal != NULL )
526         {
527             HeapFree(GetProcessHeap(), 0, pDdSurfaceGlobal);
528         }
529 
530         if ( phSurface != NULL )
531         {
532             HeapFree(GetProcessHeap(), 0, phSurface);
533         }
534 
535         if ( puhSurface != NULL )
536         {
537             HeapFree(GetProcessHeap(), 0, puhSurface);
538         }
539     }
540 
541     /* Return */
542     return Return;
543 }
544 
545 /*
546  * @implemented
547  *
548  * DdSetColorKey
549  */
550 DWORD
551 WINAPI
552 DdSetColorKey(LPDDHAL_SETCOLORKEYDATA pSetColorKey)
553 {
554     /* Call win32k */
555     return NtGdiDdSetColorKey((HANDLE)pSetColorKey->lpDDSurface->hDDSurface,
556                               (PDD_SETCOLORKEYDATA)pSetColorKey);
557 }
558 
559 /*
560  * @implemented
561  *
562  * DdGetScanLine
563  */
564 DWORD
565 WINAPI
566 DdGetScanLine(LPDDHAL_GETSCANLINEDATA pGetScanLine)
567 {
568     /* Call win32k */
569     return NtGdiDdGetScanLine(GetDdHandle(pGetScanLine->lpDD->hDD),
570                               (PDD_GETSCANLINEDATA)pGetScanLine);
571 }
572 
573 
574 /*
575  * @implemented
576  *
577  * DvpCreateVideoPort
578  */
579 BOOL
580 WINAPI
581 DvpCreateVideoPort(LPDDHAL_CREATEVPORTDATA pDvdCreatePort)
582 {
583     pDvdCreatePort->lpVideoPort->hDDVideoPort =
584         NtGdiDvpCreateVideoPort(GetDdHandle(pDvdCreatePort->lpDD->lpGbl->hDD),
585                                 (PDD_CREATEVPORTDATA) pDvdCreatePort);
586 
587     return TRUE;
588 }
589 
590 /*
591  * @implemented
592  *
593  * DvpCreateVideoPort
594  */
595 DWORD
596 WINAPI
597 DvpDestroyVideoPort(LPDDHAL_DESTROYVPORTDATA pDvdDestoryPort)
598 {
599     return NtGdiDvpDestroyVideoPort(pDvdDestoryPort->lpVideoPort->hDDVideoPort, (PDD_DESTROYVPORTDATA)pDvdDestoryPort);
600 }
601 
602 /*
603  * @implemented
604  *
605  * DvpCreateVideoPort
606  */
607 DWORD
608 WINAPI
609 DvpFlipVideoPort(LPDDHAL_FLIPVPORTDATA pDvdPortFlip)
610 {
611     return NtGdiDvpFlipVideoPort(pDvdPortFlip->lpVideoPort->hDDVideoPort,
612                                  (HANDLE)pDvdPortFlip->lpSurfCurr->hDDSurface,
613                                  (HANDLE)pDvdPortFlip->lpSurfTarg->hDDSurface,
614                                  (PDD_FLIPVPORTDATA) pDvdPortFlip);
615 }
616 
617 /*
618  * @implemented
619  *
620  * DvpGetVideoPortBandwidth
621  */
622 DWORD
623 WINAPI
624 DvpGetVideoPortBandwidth(LPDDHAL_GETVPORTBANDWIDTHDATA pDvdPortBandWidth)
625 {
626     return NtGdiDvpGetVideoPortBandwidth(pDvdPortBandWidth->lpVideoPort->hDDVideoPort, (PDD_GETVPORTBANDWIDTHDATA)pDvdPortBandWidth);
627 }
628 
629 /*
630  * @implemented
631  *
632  * DvpColorControl
633  */
634 DWORD
635 WINAPI
636 DvpColorControl(LPDDHAL_VPORTCOLORDATA pDvdPortColorControl)
637 {
638     return NtGdiDvpColorControl(pDvdPortColorControl->lpVideoPort->hDDVideoPort, (PDD_VPORTCOLORDATA) pDvdPortColorControl);
639 }
640 
641 /*
642  * @implemented
643  *
644  * DvpGetVideoSignalStatus
645  */
646 DWORD
647 WINAPI
648 DvpGetVideoSignalStatus(LPDDHAL_GETVPORTSIGNALDATA pDvdPortVideoSignalStatus)
649 {
650     return NtGdiDvpGetVideoSignalStatus(pDvdPortVideoSignalStatus->lpVideoPort->hDDVideoPort, (PDD_GETVPORTSIGNALDATA) pDvdPortVideoSignalStatus);
651 }
652 
653 /*
654  * @implemented
655  *
656  * DvpGetVideoPortFlipStatus
657  */
658 DWORD
659 WINAPI
660 DvpGetVideoPortFlipStatus(LPDDHAL_GETVPORTFLIPSTATUSDATA pDvdPortVideoPortFlipStatus)
661 {
662     return NtGdiDvpGetVideoPortFlipStatus(GetDdHandle(pDvdPortVideoPortFlipStatus->lpDD->lpGbl->hDD), (PDD_GETVPORTFLIPSTATUSDATA) pDvdPortVideoPortFlipStatus);
663 
664 }
665 
666 /*
667  * @implemented
668  *
669  * DvpCanCreateVideoPort
670  */
671 DWORD
672 WINAPI
673 DvpCanCreateVideoPort(LPDDHAL_CANCREATEVPORTDATA pDvdCanCreateVideoPort)
674 {
675     return NtGdiDvpCanCreateVideoPort(GetDdHandle(pDvdCanCreateVideoPort->lpDD->lpGbl->hDD), (PDD_CANCREATEVPORTDATA) pDvdCanCreateVideoPort);
676 }
677 /*
678  * @implemented
679  *
680  * DvpWaitForVideoPortSync
681  */
682 DWORD
683 WINAPI
684 DvpWaitForVideoPortSync(LPDDHAL_WAITFORVPORTSYNCDATA pDvdWaitForVideoPortSync)
685 {
686     return NtGdiDvpWaitForVideoPortSync(pDvdWaitForVideoPortSync->lpVideoPort->hDDVideoPort,  (PDD_WAITFORVPORTSYNCDATA) pDvdWaitForVideoPortSync);
687 }
688 
689 /*
690  * @implemented
691  *
692  * DvpUpdateVideoPort
693  */
694 DWORD
695 WINAPI
696 DvpUpdateVideoPort(LPDDHAL_UPDATEVPORTDATA pDvdUpdateVideoPort)
697 {
698     /*
699      * Windows XP limit to max 10 handles of videoport surface and Vbi
700      * ReactOS doing same to keep compatible, if it is more that 10
701      * videoport surface or vbi the stack will be curpted in windows xp
702      * ReactOS safe guard againts that
703      *
704      */
705 
706     HANDLE phSurfaceVideo[10];
707     HANDLE phSurfaceVbi[10];
708 
709     if (pDvdUpdateVideoPort->dwFlags != DDRAWI_VPORTSTOP)
710     {
711         DWORD dwNumAutoflip;
712         DWORD dwNumVBIAutoflip;
713 
714         /* Take copy of lplpDDSurface for the handle value will be modify in dxg */
715         dwNumAutoflip = pDvdUpdateVideoPort->dwNumAutoflip;
716         if ((dwNumAutoflip == 0) &&
717                 (pDvdUpdateVideoPort->lplpDDSurface == 0))
718         {
719             dwNumAutoflip++;
720         }
721 
722         if (dwNumAutoflip != 0)
723         {
724             if (dwNumAutoflip>10)
725             {
726                 dwNumAutoflip = 10;
727             }
728             memcpy(phSurfaceVideo,pDvdUpdateVideoPort->lplpDDSurface,dwNumAutoflip*sizeof(HANDLE));
729         }
730 
731         /* Take copy of lplpDDVBISurface for the handle value will be modify in dxg */
732         dwNumVBIAutoflip = pDvdUpdateVideoPort->dwNumVBIAutoflip;
733         if ( (dwNumVBIAutoflip == 0) &&
734                 (pDvdUpdateVideoPort->lplpDDVBISurface == 0) )
735         {
736             dwNumVBIAutoflip++;
737         }
738 
739         if (dwNumVBIAutoflip != 0)
740         {
741             if (dwNumVBIAutoflip>10)
742             {
743                 dwNumVBIAutoflip = 10;
744             }
745             memcpy(phSurfaceVbi,pDvdUpdateVideoPort->lplpDDVBISurface,dwNumVBIAutoflip*sizeof(HANDLE));
746         }
747     }
748 
749     /* Call Win32k */
750     return NtGdiDvpUpdateVideoPort(pDvdUpdateVideoPort->lpVideoPort->hDDVideoPort,phSurfaceVideo,phSurfaceVbi, (PDD_UPDATEVPORTDATA)pDvdUpdateVideoPort);
751 }
752 
753 /*
754  * @implemented
755  *
756  * DvpWaitForVideoPortSync
757  */
758 DWORD
759 WINAPI
760 DvpGetVideoPortField(LPDDHAL_FLIPVPORTDATA pDvdGetVideoPortField)
761 {
762     return NtGdiDvpGetVideoPortField(pDvdGetVideoPortField->lpVideoPort->hDDVideoPort, (PDD_GETVPORTFIELDDATA)pDvdGetVideoPortField);
763 }
764 
765 /*
766  * @implemented
767  *
768  * DvpWaitForVideoPortSync
769  */
770 DWORD
771 WINAPI
772 DvpGetVideoPortInputFormats(LPDDHAL_GETVPORTINPUTFORMATDATA pDvdGetVideoPortInputFormat)
773 {
774     return NtGdiDvpGetVideoPortInputFormats(pDvdGetVideoPortInputFormat->lpVideoPort->hDDVideoPort, (PDD_GETVPORTINPUTFORMATDATA) pDvdGetVideoPortInputFormat);
775 }
776 
777 /*
778  * @implemented
779  *
780  * DvpGetVideoPortLine
781  */
782 DWORD
783 WINAPI
784 DvpGetVideoPortLine(LPDDHAL_GETVPORTLINEDATA pDvdGetVideoPortLine)
785 {
786     return NtGdiDvpGetVideoPortLine(pDvdGetVideoPortLine->lpVideoPort->hDDVideoPort, (PDD_GETVPORTLINEDATA)pDvdGetVideoPortLine);
787 }
788 
789 /*
790  * @implemented
791  *
792  * DvpGetVideoPortOutputFormats
793  */
794 DWORD
795 WINAPI
796 DvpGetVideoPortOutputFormats(LPDDHAL_GETVPORTLINEDATA pDvdGetVideoPortOutputFormat)
797 {
798     return NtGdiDvpGetVideoPortLine(pDvdGetVideoPortOutputFormat->lpVideoPort->hDDVideoPort, (PDD_GETVPORTLINEDATA)pDvdGetVideoPortOutputFormat);
799 }
800 
801 /*
802  * @implemented
803  *
804  * DvpGetVideoPortConnectInfo
805  */
806 DWORD
807 WINAPI
808 DvpGetVideoPortConnectInfo(LPDDHAL_GETVPORTCONNECTDATA pDvdGetVideoPortInfo)
809 {
810     return NtGdiDvpGetVideoPortConnectInfo( GetDdHandle( pDvdGetVideoPortInfo->lpDD->lpGbl->hDD) , (PDD_GETVPORTCONNECTDATA) pDvdGetVideoPortInfo);
811 }
812 
813 /*
814  * @implemented
815  *
816  * DdGetAvailDriverMemory
817  */
818 DWORD
819 WINAPI
820 DdGetAvailDriverMemory(LPDDHAL_GETAVAILDRIVERMEMORYDATA pDdGetAvailDriverMemory)
821 {
822     return NtGdiDdGetAvailDriverMemory(GetDdHandle( pDdGetAvailDriverMemory->lpDD->hDD), (PDD_GETAVAILDRIVERMEMORYDATA) pDdGetAvailDriverMemory);
823 }
824 
825 /*
826  * @implemented
827  *
828  * DdAlphaBlt
829  */
830 DWORD
831 WINAPI
832 DdAlphaBlt(LPDDHAL_BLTDATA pDdAlphaBlt)
833 {
834     HANDLE hDDSrcSurface = 0;
835 
836     if (pDdAlphaBlt->lpDDSrcSurface != 0)
837     {
838         hDDSrcSurface = (HANDLE) pDdAlphaBlt->lpDDSrcSurface->hDDSurface;
839     }
840 
841     return NtGdiDdAlphaBlt((HANDLE)pDdAlphaBlt->lpDDDestSurface->hDDSurface, hDDSrcSurface, (PDD_BLTDATA)&pDdAlphaBlt);
842 }
843 
844 /*
845  * @implemented
846  *
847  * DdCreateSurfaceEx
848  */
849 DWORD
850 WINAPI
851 DdCreateSurfaceEx(LPDDHAL_CREATESURFACEEXDATA pDdCreateSurfaceEx)
852 {
853     pDdCreateSurfaceEx->ddRVal = NtGdiDdCreateSurfaceEx( GetDdHandle(pDdCreateSurfaceEx->lpDDLcl->lpGbl->hDD),
854                                  (HANDLE)pDdCreateSurfaceEx->lpDDSLcl->hDDSurface,
855                                  pDdCreateSurfaceEx->lpDDSLcl->lpSurfMore->dwSurfaceHandle);
856     return TRUE;
857 }
858 
859 /*
860  * @implemented
861  *
862  * DdColorControl
863  */
864 DWORD
865 WINAPI
866 DdColorControl(LPDDHAL_COLORCONTROLDATA pDdColorControl)
867 {
868     return NtGdiDdColorControl( (HANDLE) pDdColorControl->lpDDSurface->hDDSurface, (PDD_COLORCONTROLDATA) &pDdColorControl);
869 }
870 
871 /*
872  * @implemented
873  *
874  * DdSetExclusiveMode
875  */
876 DWORD
877 WINAPI
878 DdSetExclusiveMode(LPDDHAL_SETEXCLUSIVEMODEDATA pDdSetExclusiveMode)
879 {
880     return NtGdiDdSetExclusiveMode( GetDdHandle(pDdSetExclusiveMode->lpDD->hDD), (PDD_SETEXCLUSIVEMODEDATA) &pDdSetExclusiveMode);
881 }
882 
883 /*
884  * @implemented
885  *
886  * DdFlipToGDISurface
887  */
888 DWORD
889 WINAPI
890 DdFlipToGDISurface(LPDDHAL_FLIPTOGDISURFACEDATA pDdFlipToGDISurface)
891 {
892     return NtGdiDdFlipToGDISurface( GetDdHandle(pDdFlipToGDISurface->lpDD->hDD), (PDD_FLIPTOGDISURFACEDATA) &pDdFlipToGDISurface);
893 }
894 
895 /* TODO */
896 DWORD
897 WINAPI
898 DdGetDriverInfo(LPDDHAL_GETDRIVERINFODATA pData)
899 {
900     DDHAL_GETDRIVERINFODATA pDrvInfoData;
901     DWORD retValue = DDHAL_DRIVER_NOTHANDLED;
902     HANDLE hDD;
903 
904     /* FIXME add SEH around this functions */
905 
906     RtlZeroMemory(&pDrvInfoData, sizeof (DDHAL_GETDRIVERINFODATA));
907     RtlCopyMemory(&pDrvInfoData.guidInfo, &pData->guidInfo, sizeof(GUID));
908 
909     hDD = GetDdHandle(pData->dwContext);
910 
911     pDrvInfoData.dwSize = sizeof (DDHAL_GETDRIVERINFODATA);
912     pDrvInfoData.ddRVal = DDERR_GENERIC;
913     pDrvInfoData.dwContext = (ULONG_PTR)hDD;
914 
915 
916     /* Videoport Callbacks check and setup for DirectX/ ReactX */
917     if (IsEqualGUID(&pData->guidInfo, &GUID_VideoPortCallbacks))
918     {
919         DDHAL_DDVIDEOPORTCALLBACKS  pDvdPort;
920         DDHAL_DDVIDEOPORTCALLBACKS* pUserDvdPort = (DDHAL_DDVIDEOPORTCALLBACKS *)pData->lpvData;
921 
922         /* Clear internal out buffer and set it up*/
923         RtlZeroMemory(&pDvdPort, DDVIDEOPORTCALLBACKSSIZE);
924         pDvdPort.dwSize = DDVIDEOPORTCALLBACKSSIZE;
925 
926         /* set up internal buffer */
927         pDrvInfoData.lpvData = (PVOID)&pDvdPort;
928         pDrvInfoData.dwExpectedSize = DDVIDEOPORTCALLBACKSSIZE ;
929 
930         /* Call win32k */
931         retValue = NtGdiDdGetDriverInfo(hDD, (PDD_GETDRIVERINFODATA)&pDrvInfoData);
932 
933         /* Setup user out buffer and convert kmode callbacks to user mode */
934         pUserDvdPort->dwSize = DDVIDEOPORTCALLBACKSSIZE;
935         pUserDvdPort->dwFlags = pDrvInfoData.dwFlags =  0;
936 
937         pUserDvdPort->dwFlags = (pDrvInfoData.dwFlags & ~(DDHAL_VPORT32_CREATEVIDEOPORT | DDHAL_VPORT32_FLIP |
938                                  DDHAL_VPORT32_DESTROY | DDHAL_VPORT32_UPDATE | DDHAL_VPORT32_WAITFORSYNC)) |
939                                 (DDHAL_VPORT32_CREATEVIDEOPORT | DDHAL_VPORT32_FLIP |
940                                  DDHAL_VPORT32_DESTROY | DDHAL_VPORT32_UPDATE);
941 
942         pData->dwActualSize = DDVIDEOPORTCALLBACKSSIZE;
943         pUserDvdPort->CreateVideoPort = (LPDDHALVPORTCB_CREATEVIDEOPORT) DvpCreateVideoPort;
944         pUserDvdPort->FlipVideoPort = (LPDDHALVPORTCB_FLIP) DvpFlipVideoPort;
945         pUserDvdPort->DestroyVideoPort = (LPDDHALVPORTCB_DESTROYVPORT) DvpDestroyVideoPort;
946         pUserDvdPort->UpdateVideoPort = (LPDDHALVPORTCB_UPDATE) DvpUpdateVideoPort;
947 
948         if (pDvdPort.CanCreateVideoPort)
949         {
950             pUserDvdPort->CanCreateVideoPort = (LPDDHALVPORTCB_CANCREATEVIDEOPORT) DvpCanCreateVideoPort;
951         }
952 
953         if (pDvdPort.GetVideoPortBandwidth)
954         {
955             pUserDvdPort->GetVideoPortBandwidth = (LPDDHALVPORTCB_GETBANDWIDTH) DvpGetVideoPortBandwidth;
956         }
957 
958         if (pDvdPort.GetVideoPortInputFormats)
959         {
960             pUserDvdPort->GetVideoPortInputFormats = (LPDDHALVPORTCB_GETINPUTFORMATS) DvpGetVideoPortInputFormats;
961         }
962 
963         if (pDvdPort.GetVideoPortOutputFormats)
964         {
965             pUserDvdPort->GetVideoPortOutputFormats = (LPDDHALVPORTCB_GETOUTPUTFORMATS) DvpGetVideoPortOutputFormats;
966         }
967 
968         if (pDvdPort.GetVideoPortField)
969         {
970             pUserDvdPort->GetVideoPortField = (LPDDHALVPORTCB_GETFIELD) DvpGetVideoPortField;
971         }
972 
973         if (pDvdPort.GetVideoPortLine)
974         {
975             pUserDvdPort->GetVideoPortLine = (LPDDHALVPORTCB_GETLINE) DvpGetVideoPortLine;
976         }
977 
978         if (pDvdPort.GetVideoPortConnectInfo)
979         {
980             pUserDvdPort->GetVideoPortConnectInfo = (LPDDHALVPORTCB_GETVPORTCONNECT) DvpGetVideoPortConnectInfo;
981         }
982 
983         if (pDvdPort.GetVideoPortFlipStatus)
984         {
985             pUserDvdPort->GetVideoPortFlipStatus = (LPDDHALVPORTCB_GETFLIPSTATUS) DvpGetVideoPortFlipStatus;
986         }
987 
988         if (pDvdPort.WaitForVideoPortSync)
989         {
990             pUserDvdPort->WaitForVideoPortSync = (LPDDHALVPORTCB_WAITFORSYNC) DvpWaitForVideoPortSync;
991         }
992 
993         if (pDvdPort.GetVideoSignalStatus)
994         {
995             pUserDvdPort->GetVideoSignalStatus = (LPDDHALVPORTCB_GETSIGNALSTATUS) DvpGetVideoSignalStatus;
996         }
997 
998         if (pDvdPort.ColorControl)
999         {
1000             pUserDvdPort->ColorControl = (LPDDHALVPORTCB_COLORCONTROL) DvpColorControl;
1001         }
1002 
1003         /* Windows XP never repot back the true return value,
1004          *  it only report back if we have a driver or not
1005          *  ReactOS keep this behoir to be compatible with
1006          *  Windows XP
1007          */
1008         pData->ddRVal = retValue;
1009     }
1010 
1011     /* Color Control Callbacks check and setup for DirectX/ ReactX */
1012     if (IsEqualGUID(&pData->guidInfo, &GUID_ColorControlCallbacks))
1013     {
1014         DDHAL_DDCOLORCONTROLCALLBACKS  pColorControl;
1015         DDHAL_DDCOLORCONTROLCALLBACKS* pUserColorControl = (DDHAL_DDCOLORCONTROLCALLBACKS *)pData->lpvData;
1016 
1017         /* Clear internal out buffer and set it up*/
1018         RtlZeroMemory(&pColorControl, DDCOLORCONTROLCALLBACKSSIZE);
1019         pColorControl.dwSize = DDCOLORCONTROLCALLBACKSSIZE;
1020 
1021         /* set up internal buffer */
1022         pDrvInfoData.lpvData = (PVOID)&pColorControl;
1023         pDrvInfoData.dwExpectedSize = DDCOLORCONTROLCALLBACKSSIZE ;
1024 
1025         /* Call win32k */
1026         retValue = NtGdiDdGetDriverInfo(hDD, (PDD_GETDRIVERINFODATA)&pDrvInfoData);
1027 
1028         pData->dwActualSize = DDCOLORCONTROLCALLBACKSSIZE;
1029         pData->dwFlags = pDrvInfoData.dwFlags;
1030 
1031         pUserColorControl->dwSize = DDCOLORCONTROLCALLBACKSSIZE;
1032         pUserColorControl->dwFlags = pColorControl.dwFlags;
1033 
1034         if (pColorControl.ColorControl != NULL)
1035         {
1036             pUserColorControl->ColorControl = (LPDDHALCOLORCB_COLORCONTROL) DdColorControl;
1037         }
1038 
1039         /* Windows XP never repot back the true return value,
1040          *  it only report back if we have a driver or not
1041          *  ReactOS keep this behoir to be compatible with
1042          *  Windows XP
1043          */
1044         pData->ddRVal = retValue;
1045     }
1046 
1047     /* Misc Callbacks check and setup for DirectX/ ReactX */
1048     else if (IsEqualGUID(&pData->guidInfo, &GUID_MiscellaneousCallbacks))
1049     {
1050         DDHAL_DDMISCELLANEOUSCALLBACKS  pMisc;
1051         DDHAL_DDMISCELLANEOUSCALLBACKS* pUserMisc = (DDHAL_DDMISCELLANEOUSCALLBACKS *)pData->lpvData;
1052 
1053         /* Clear internal out buffer and set it up*/
1054         RtlZeroMemory(&pMisc, DDMISCELLANEOUSCALLBACKSSIZE);
1055         pMisc.dwSize = DDMISCELLANEOUSCALLBACKSSIZE;
1056 
1057         /* set up internal buffer */
1058         pDrvInfoData.lpvData = (PVOID)&pMisc;
1059         pDrvInfoData.dwExpectedSize = DDMISCELLANEOUSCALLBACKSSIZE ;
1060 
1061         /* Call win32k */
1062         retValue = NtGdiDdGetDriverInfo(hDD, (PDD_GETDRIVERINFODATA)&pDrvInfoData);
1063 
1064         pData->dwActualSize = DDMISCELLANEOUSCALLBACKSSIZE;
1065 
1066         /* Only one callbacks are supported */
1067         pUserMisc->dwFlags = pMisc.dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY;
1068         pUserMisc->GetAvailDriverMemory = (LPDDHAL_GETAVAILDRIVERMEMORY) DdGetAvailDriverMemory;
1069 
1070         /* This callbacks are only for win9x and theirfor it is not longer use in NT or ReactOS
1071          * pUserMisc->UpdateNonLocalHeap;
1072          * pUserMisc->GetHeapAlignment;
1073          * pUserMisc->GetSysmemBltStatus; */
1074 
1075         /* Windows XP never repot back the true return value,
1076          *  it only report back if we have a driver or not
1077          *  ReactOS keep this behoir to be compatible with
1078          *  Windows XP
1079          */
1080         pData->ddRVal = retValue;
1081     }
1082 
1083     /* Misc 2 Callbacks check and setup for DirectX/ ReactX */
1084     else if (IsEqualGUID(&pData->guidInfo, &GUID_Miscellaneous2Callbacks))
1085     {
1086         DDHAL_DDMISCELLANEOUS2CALLBACKS  pMisc;
1087         DDHAL_DDMISCELLANEOUS2CALLBACKS* pUserMisc = (DDHAL_DDMISCELLANEOUS2CALLBACKS *)pData->lpvData;
1088 
1089         /* Clear internal out buffer and set it up*/
1090         RtlZeroMemory(&pMisc, DDMISCELLANEOUS2CALLBACKSSIZE);
1091         pMisc.dwSize = DDMISCELLANEOUS2CALLBACKSSIZE;
1092 
1093         /* set up internal buffer */
1094         pDrvInfoData.lpvData = (PVOID)&pMisc;
1095         pDrvInfoData.dwExpectedSize = DDMISCELLANEOUS2CALLBACKSSIZE ;
1096 
1097         /* Call win32k */
1098         retValue = NtGdiDdGetDriverInfo(hDD, (PDD_GETDRIVERINFODATA)&pDrvInfoData);
1099 
1100         pData->dwActualSize = DDMISCELLANEOUS2CALLBACKSSIZE;
1101 
1102         pUserMisc->dwFlags = pMisc.dwFlags;
1103 
1104         /* This functions are not documneted in MSDN for this struct, here is directx/reactx alpha blend */
1105         if ( pMisc.Reserved )
1106         {
1107             pUserMisc->Reserved = (LPVOID) DdAlphaBlt;
1108         }
1109 
1110         if ( pMisc.CreateSurfaceEx )
1111         {
1112             pUserMisc->CreateSurfaceEx = (LPDDHAL_CREATESURFACEEX) DdCreateSurfaceEx;
1113         }
1114 
1115         if ( pMisc.GetDriverState )
1116         {
1117             pUserMisc->GetDriverState = (LPDDHAL_GETDRIVERSTATE) NtGdiDdGetDriverState;
1118         }
1119 
1120         /* NOTE : pUserMisc->DestroyDDLocal is outdated and are not beign tuch */
1121 
1122         /* Windows XP never repot back the true return value,
1123          *  it only report back if we have a driver or not
1124          *  ReactOS keep this behoir to be compatible with
1125          *  Windows XP
1126          */
1127         pData->ddRVal = retValue;
1128     }
1129 
1130     /* NT Callbacks check and setup for DirectX/ ReactX */
1131     else if (IsEqualGUID(&pData->guidInfo, &GUID_NTCallbacks))
1132     {
1133         /* MS does not have DHAL_* version of this callbacks
1134          * so we are force using PDD_* callbacks here
1135          */
1136         DD_NTCALLBACKS  pNtKernel;
1137         PDD_NTCALLBACKS pUserNtKernel = (PDD_NTCALLBACKS)pData->lpvData;
1138 
1139         /* Clear internal out buffer and set it up*/
1140         RtlZeroMemory(&pNtKernel, sizeof(DD_NTCALLBACKS));
1141         pNtKernel.dwSize = sizeof(DD_NTCALLBACKS);
1142 
1143         /* set up internal buffer */
1144         pDrvInfoData.lpvData = (PVOID)&pNtKernel;
1145         pDrvInfoData.dwExpectedSize = sizeof(DD_NTCALLBACKS) ;
1146 
1147         /* Call win32k */
1148         retValue = NtGdiDdGetDriverInfo(hDD, (PDD_GETDRIVERINFODATA)&pDrvInfoData);
1149 
1150         pData->dwActualSize = sizeof(DD_NTCALLBACKS);
1151 
1152         pUserNtKernel->dwSize = sizeof(DD_NTCALLBACKS);
1153         pUserNtKernel->dwFlags = pNtKernel.dwFlags;
1154         pUserNtKernel->FreeDriverMemory = 0;
1155 
1156         if (pNtKernel.SetExclusiveMode)
1157         {
1158             pUserNtKernel->SetExclusiveMode = (PDD_SETEXCLUSIVEMODE) DdSetExclusiveMode;
1159         }
1160 
1161         if (pNtKernel.FlipToGDISurface)
1162         {
1163             pUserNtKernel->FlipToGDISurface = (PDD_FLIPTOGDISURFACE) DdFlipToGDISurface;
1164         }
1165 
1166         /* Windows XP never repot back the true return value,
1167          *  it only report back if we have a driver or not
1168          *  ReactOS keep this behoir to be compatible with
1169          *  Windows XP
1170          */
1171         pData->ddRVal = retValue;
1172     }
1173 
1174     /* D3D Callbacks version 2 check and setup for DirectX/ ReactX */
1175     else if (IsEqualGUID(&pData->guidInfo, &GUID_D3DCallbacks2))
1176     {
1177         // FIXME GUID_D3DCallbacks2
1178     }
1179 
1180     /* D3D Callbacks version 3 check and setup for DirectX/ ReactX */
1181     else if (IsEqualGUID(&pData->guidInfo, &GUID_D3DCallbacks3))
1182     {
1183         // FIXME GUID_D3DCallbacks3
1184     }
1185 
1186     /* D3DParseUnknownCommand Callbacks check and setup for DirectX/ ReactX */
1187     else if (IsEqualGUID(&pData->guidInfo, &GUID_D3DParseUnknownCommandCallback))
1188     {
1189         // FIXME GUID_D3DParseUnknownCommandCallback
1190     }
1191 
1192     /* MotionComp Callbacks check and setup for DirectX/ ReactX */
1193     else if (IsEqualGUID(&pData->guidInfo, &GUID_MotionCompCallbacks))
1194     {
1195         // FIXME GUID_MotionCompCallbacks
1196     }
1197 
1198     /* FIXME VPE2 Callbacks check and setup for DirectX/ ReactX */
1199     //else if (IsEqualGUID(&pData->guidInfo, &GUID_VPE2Callbacks))
1200     //{
1201     // FIXME GUID_VPE2Callbacks
1202     //}
1203     else
1204     {
1205         /* set up internal buffer */
1206         pDrvInfoData.dwExpectedSize = pData->dwExpectedSize;
1207         pDrvInfoData.lpvData = pData->lpvData;
1208 
1209         /* We do not cover all callbacks for user mode, they are only cover by kmode */
1210         retValue = NtGdiDdGetDriverInfo(hDD, (PDD_GETDRIVERINFODATA)&pDrvInfoData);
1211 
1212         /* Setup return data */
1213         pData->dwActualSize = pDrvInfoData.dwActualSize;
1214         pData->lpvData = pDrvInfoData.lpvData;
1215         /* Windows XP never repot back the true return value,
1216          *  it only report back if we have a driver or not
1217          *  ReactOS keep this behoir to be compatible with
1218          *  Windows XP
1219          */
1220         pData->ddRVal = retValue;
1221     }
1222 
1223     return retValue;
1224 }
1225 
1226 
1227 /*
1228  * @implemented
1229  *
1230  * D3dContextCreate
1231  */
1232 BOOL
1233 WINAPI
1234 D3dContextCreate(LPD3DHAL_CONTEXTCREATEDATA pdcci)
1235 {
1236     HANDLE hSurfZ = NULL;
1237 
1238     if (pdcci->lpDDSZLcl)
1239     {
1240         hSurfZ = (HANDLE)pdcci->lpDDSZLcl->hDDSurface;
1241     }
1242 
1243     return  NtGdiD3dContextCreate(GetDdHandle(pdcci->lpDDLcl->hDD),
1244                                   (HANDLE)pdcci->lpDDSLcl->hDDSurface,
1245                                   hSurfZ,
1246                                   (D3DNTHAL_CONTEXTCREATEI *)pdcci);
1247 }
1248 
1249 /*
1250  * @implemented
1251  *
1252  * DdCanCreateD3DBuffer
1253  */
1254 DWORD
1255 WINAPI
1256 DdCanCreateD3DBuffer(LPDDHAL_CANCREATESURFACEDATA CanCreateD3DBuffer)
1257 {
1258     /*
1259      * Note : This functions are basic same, in win32k
1260      * NtGdiDdCanCreateD3DBuffer and  NtGdiDdCanCreateSurface are mergs
1261      * toghter in win32k at end and retrurn same data, it is still sepreated
1262      * at user mode but in kmode it is not.
1263      */
1264 
1265     /* Call win32k */
1266     return NtGdiDdCanCreateD3DBuffer(GetDdHandle(CanCreateD3DBuffer->lpDD->hDD),
1267                                      (PDD_CANCREATESURFACEDATA)CanCreateD3DBuffer);
1268 }
1269 
1270 
1271 /*
1272  * @implemented
1273  *
1274  * DdCreateD3DBuffer
1275  */
1276 DWORD
1277 WINAPI
1278 DdCreateD3DBuffer(LPDDHAL_CREATESURFACEDATA pCreateSurface)
1279 {
1280     HANDLE puhSurface = 0;
1281     DDRAWI_DDRAWSURFACE_GBL *pSurfGBL;
1282     DDRAWI_DDRAWSURFACE_LCL *pSurfLcl;
1283     DD_SURFACE_GLOBAL puSurfaceGlobalData;
1284     DD_SURFACE_MORE puSurfaceMoreData;
1285     DD_SURFACE_LOCAL puSurfaceLocalData;
1286     DWORD retValue;
1287 
1288     /* Zero all local memory pointer */
1289     RtlZeroMemory(&puSurfaceGlobalData, sizeof(DD_SURFACE_GLOBAL) );
1290     RtlZeroMemory(&puSurfaceMoreData, sizeof(DD_SURFACE_MORE) ) ;
1291     RtlZeroMemory(&puSurfaceLocalData, sizeof(DD_SURFACE_LOCAL) );
1292 
1293     pCreateSurface->dwSCnt = 1;
1294     pSurfLcl = pCreateSurface->lplpSList[0];
1295     pSurfGBL = pSurfLcl->lpGbl;
1296 
1297     /* Convert DDRAWI_DDRAWSURFACE_GBL to DD_SURFACE_GLOBAL */
1298     puSurfaceGlobalData.wWidth = pSurfGBL->wWidth;
1299     puSurfaceGlobalData.wHeight = pSurfGBL->wHeight;
1300     puSurfaceGlobalData.dwLinearSize = pSurfGBL->dwLinearSize;
1301     puSurfaceGlobalData.fpVidMem = pSurfGBL->fpVidMem;
1302     puSurfaceGlobalData.dwBlockSizeX = pSurfGBL->dwBlockSizeX;
1303     puSurfaceGlobalData.dwBlockSizeY = pSurfGBL->dwBlockSizeY;
1304 
1305     /* Convert DDRAWI_DDRAWSURFACE_MORE to DD_SURFACE_MORE */
1306     puSurfaceMoreData.dwSurfaceHandle = pSurfLcl->lpSurfMore->dwSurfaceHandle;
1307     puSurfaceMoreData.ddsCapsEx.dwCaps2 = pSurfLcl->lpSurfMore->ddsCapsEx.dwCaps2;
1308     puSurfaceMoreData.ddsCapsEx.dwCaps3 = pSurfLcl->lpSurfMore->ddsCapsEx.dwCaps3;
1309     puSurfaceMoreData.ddsCapsEx.dwCaps4 = pSurfLcl->lpSurfMore->ddsCapsEx.dwCaps4;
1310 
1311     /* Convert DDRAWI_DDRAWSURFACE_LCL to DD_SURFACE_LOCAL */
1312     puSurfaceLocalData.dwFlags = pSurfLcl->dwFlags;
1313     puSurfaceLocalData.ddsCaps.dwCaps = pSurfLcl->ddsCaps.dwCaps;
1314 
1315     /* Call win32k */
1316     retValue = NtGdiDdCreateD3DBuffer( GetDdHandle(pCreateSurface->lpDD->hDD),
1317                                        (HANDLE*)&pSurfLcl->hDDSurface,
1318                                        pCreateSurface->lpDDSurfaceDesc,
1319                                        &puSurfaceGlobalData,
1320                                        &puSurfaceLocalData,
1321                                        &puSurfaceMoreData,
1322                                        (DD_CREATESURFACEDATA *) pCreateSurface,
1323                                        &puhSurface);
1324 
1325     /* Setup surface handle if we got one back  */
1326     if ( puhSurface != NULL )
1327     {
1328         pCreateSurface->lplpSList[0]->hDDSurface = (ULONG_PTR)puhSurface;
1329     }
1330 
1331     /* Convert DD_SURFACE_GLOBAL to DDRAWI_DDRAWSURFACE_GBL */
1332     pSurfGBL->dwLinearSize = puSurfaceGlobalData.dwLinearSize;
1333     pSurfGBL->fpVidMem = puSurfaceGlobalData.fpVidMem;
1334     pSurfGBL->dwBlockSizeX = puSurfaceGlobalData.dwBlockSizeX;
1335     pSurfGBL->dwBlockSizeY = puSurfaceGlobalData.dwBlockSizeY;
1336 
1337     return retValue;
1338 }
1339 
1340 /*
1341  * @implemented
1342  *
1343  * DdDestroyD3DBuffer
1344  */
1345 DWORD
1346 WINAPI
1347 DdDestroyD3DBuffer(LPDDHAL_DESTROYSURFACEDATA pDestroySurface)
1348 {
1349     DWORD retValue = 0;
1350     if ( pDestroySurface->lpDDSurface->hDDSurface)
1351     {
1352         /* Call win32k */
1353         retValue = NtGdiDdDestroyD3DBuffer((HANDLE)pDestroySurface->lpDDSurface->hDDSurface);
1354     }
1355 
1356     return retValue;
1357 }
1358 
1359 /*
1360  * @implemented
1361  *
1362  * DdLockD3D
1363  */
1364 DWORD
1365 WINAPI
1366 DdLockD3D(LPDDHAL_LOCKDATA Lock)
1367 {
1368 
1369     /* Call win32k */
1370     return NtGdiDdLockD3D((HANDLE)Lock->lpDDSurface->hDDSurface, (PDD_LOCKDATA)Lock);
1371 }
1372 
1373 /*
1374  * @implemented
1375  *
1376  * DdUnlockD3D
1377  */
1378 DWORD
1379 WINAPI
1380 DdUnlockD3D(LPDDHAL_UNLOCKDATA Unlock)
1381 {
1382     /* Call win32k */
1383     return NtGdiDdUnlock((HANDLE)Unlock->lpDDSurface->hDDSurface,
1384                          (PDD_UNLOCKDATA)Unlock);
1385 }
1386 
1387 
1388 /* PRIVATE FUNCTIONS *********************************************************/
1389 
1390 BOOL
1391 WINAPI
1392 bDDCreateSurface(LPDDRAWI_DDRAWSURFACE_LCL pSurface,
1393                  BOOL bComplete)
1394 {
1395     DD_SURFACE_LOCAL SurfaceLocal;
1396     DD_SURFACE_GLOBAL SurfaceGlobal;
1397     DD_SURFACE_MORE SurfaceMore;
1398 
1399     /* Zero struct */
1400     RtlZeroMemory(&SurfaceLocal, sizeof(DD_SURFACE_LOCAL));
1401     RtlZeroMemory(&SurfaceGlobal, sizeof(DD_SURFACE_GLOBAL));
1402     RtlZeroMemory(&SurfaceMore, sizeof(DD_SURFACE_MORE));
1403 
1404     /* Set up SurfaceLocal struct */
1405     SurfaceLocal.ddsCaps.dwCaps = pSurface->ddsCaps.dwCaps;
1406     SurfaceLocal.dwFlags = pSurface->dwFlags;
1407 
1408     /* Set up SurfaceMore struct */
1409     RtlMoveMemory(&SurfaceMore.ddsCapsEx,
1410                   &pSurface->ddckCKDestBlt,
1411                   sizeof(DDSCAPSEX));
1412     SurfaceMore.dwSurfaceHandle = pSurface->lpSurfMore->dwSurfaceHandle;
1413 
1414     /* Set up SurfaceGlobal struct */
1415     SurfaceGlobal.fpVidMem = pSurface->lpGbl->fpVidMem;
1416     SurfaceGlobal.dwLinearSize = pSurface->lpGbl->dwLinearSize;
1417     SurfaceGlobal.wHeight = pSurface->lpGbl->wHeight;
1418     SurfaceGlobal.wWidth = pSurface->lpGbl->wWidth;
1419 
1420     /* Check if we have a pixel format */
1421     if (pSurface->dwFlags & DDSD_PIXELFORMAT)
1422     {
1423         /* Use global one */
1424         SurfaceGlobal.ddpfSurface = pSurface->lpGbl->lpDD->vmiData.ddpfDisplay;
1425         SurfaceGlobal.ddpfSurface.dwSize = sizeof(DDPIXELFORMAT);
1426     }
1427     else
1428     {
1429         /* Use local one */
1430         SurfaceGlobal.ddpfSurface = pSurface->lpGbl->lpDD->vmiData.ddpfDisplay;
1431     }
1432 
1433     /* Create the object */
1434     pSurface->hDDSurface = (DWORD_PTR)NtGdiDdCreateSurfaceObject(GetDdHandle(pSurface->lpGbl->lpDD->hDD),
1435                            (HANDLE)pSurface->hDDSurface,
1436                            &SurfaceLocal,
1437                            &SurfaceMore,
1438                            &SurfaceGlobal,
1439                            bComplete);
1440 
1441     /* Return status */
1442     if (pSurface->hDDSurface) return TRUE;
1443     return FALSE;
1444 }
1445 
1446 /* PUBLIC FUNCTIONS **********************************************************/
1447 
1448 /*
1449  * @implemented
1450  *
1451  * GDIEntry 1
1452  */
1453 BOOL
1454 WINAPI
1455 DdCreateDirectDrawObject(LPDDRAWI_DIRECTDRAW_GBL pDirectDrawGlobal,
1456                          HDC hdc)
1457 {
1458     BOOL Return = FALSE;
1459 
1460     /* Check if the global hDC (hdc == 0) is being used */
1461     if (!hdc)
1462     {
1463         /* We'll only allow this if the global object doesn't exist yet */
1464         if (!ghDirectDraw)
1465         {
1466             /* Create the DC */
1467             if ((hdc = CreateDCW(L"Display", NULL, NULL, NULL)))
1468             {
1469                 /* Create the DDraw Object */
1470                 ghDirectDraw = NtGdiDdCreateDirectDrawObject(hdc);
1471 
1472                 /* Delete our DC */
1473                 DeleteDC(hdc);
1474             }
1475         }
1476 
1477         /* If we created the object, or had one ...*/
1478         if (ghDirectDraw)
1479         {
1480             /* Increase count and set success */
1481             gcDirectDraw++;
1482             Return = TRUE;
1483         }
1484 
1485         /* Zero the handle */
1486         pDirectDrawGlobal->hDD = 0;
1487     }
1488     else
1489     {
1490         /* Using the per-process object, so create it */
1491         pDirectDrawGlobal->hDD = (ULONG_PTR)NtGdiDdCreateDirectDrawObject(hdc);
1492 
1493         /* Set the return value */
1494         Return = pDirectDrawGlobal->hDD ? TRUE : FALSE;
1495     }
1496 
1497     /* Return to caller */
1498     return Return;
1499 }
1500 
1501 /*
1502  * @implemented
1503  *
1504  * GDIEntry 2
1505  */
1506 BOOL
1507 WINAPI
1508 DdQueryDirectDrawObject(LPDDRAWI_DIRECTDRAW_GBL pDirectDrawGlobal,
1509                         LPDDHALINFO pHalInfo,
1510                         LPDDHAL_DDCALLBACKS pDDCallbacks,
1511                         LPDDHAL_DDSURFACECALLBACKS pDDSurfaceCallbacks,
1512                         LPDDHAL_DDPALETTECALLBACKS pDDPaletteCallbacks,
1513                         LPD3DHAL_CALLBACKS pD3dCallbacks,
1514                         LPD3DHAL_GLOBALDRIVERDATA pD3dDriverData,
1515                         LPDDHAL_DDEXEBUFCALLBACKS pD3dBufferCallbacks,
1516                         LPDDSURFACEDESC pD3dTextureFormats,
1517                         LPDWORD pdwFourCC,
1518                         LPVIDMEM pvmList)
1519 {
1520     PVIDEOMEMORY VidMemList = NULL;
1521     DD_HALINFO HalInfo;
1522     D3DNTHAL_CALLBACKS D3dCallbacks;
1523     D3DNTHAL_GLOBALDRIVERDATA D3dDriverData;
1524     DD_D3DBUFCALLBACKS D3dBufferCallbacks;
1525     DWORD CallbackFlags[3];
1526     DWORD dwNumHeaps=0, FourCCs=0;
1527     DWORD Flags;
1528     BOOL retVal = TRUE;
1529 
1530     /* Clear the structures */
1531     RtlZeroMemory(&HalInfo, sizeof(DD_HALINFO));
1532     RtlZeroMemory(&D3dCallbacks, sizeof(D3DNTHAL_CALLBACKS));
1533     RtlZeroMemory(&D3dDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
1534     RtlZeroMemory(&D3dBufferCallbacks, sizeof(DD_D3DBUFCALLBACKS));
1535     RtlZeroMemory(CallbackFlags, sizeof(DWORD)*3);
1536 
1537     /* Note : XP always alloc 24*sizeof(VIDEOMEMORY) of pvmlist so we change it to it */
1538     if ( (pvmList != NULL) &&
1539             (pHalInfo->vmiData.dwNumHeaps != 0) )
1540     {
1541         VidMemList = (PVIDEOMEMORY) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (sizeof(VIDEOMEMORY) * 24 ) * pHalInfo->vmiData.dwNumHeaps);
1542     }
1543 
1544 
1545     /* Do the query */
1546     if (!NtGdiDdQueryDirectDrawObject(GetDdHandle(pDirectDrawGlobal->hDD),
1547                                       &HalInfo,
1548                                       CallbackFlags,
1549                                       &D3dCallbacks,
1550                                       &D3dDriverData,
1551                                       &D3dBufferCallbacks,
1552                                       pD3dTextureFormats,
1553                                       &dwNumHeaps,
1554                                       VidMemList,
1555                                       &FourCCs,
1556                                       pdwFourCC))
1557     {
1558         /* We failed, free the memory and return */
1559         retVal = FALSE;
1560         goto cleanup;
1561     }
1562 
1563     /* Clear the incoming pointer */
1564     RtlZeroMemory(pHalInfo, sizeof(DDHALINFO));
1565 
1566     /* Convert all the data */
1567     pHalInfo->dwSize = sizeof(DDHALINFO);
1568     pHalInfo->lpDDCallbacks = pDDCallbacks;
1569     pHalInfo->lpDDSurfaceCallbacks = pDDSurfaceCallbacks;
1570     pHalInfo->lpDDPaletteCallbacks = pDDPaletteCallbacks;
1571 
1572     /* Check for NT5+ D3D Data */
1573     if ( (D3dCallbacks.dwSize != 0) &&
1574             (D3dDriverData.dwSize != 0) )
1575     {
1576         /* Write these down */
1577         pHalInfo->lpD3DGlobalDriverData = (ULONG_PTR)pD3dDriverData;
1578         pHalInfo->lpD3DHALCallbacks = (ULONG_PTR)pD3dCallbacks;
1579 
1580         /* Check for Buffer Callbacks */
1581         if (D3dBufferCallbacks.dwSize)
1582         {
1583             /* Write this one too */
1584             pHalInfo->lpDDExeBufCallbacks = pD3dBufferCallbacks;
1585         }
1586     }
1587 
1588     /* Continue converting the rest */
1589     pHalInfo->vmiData.dwFlags = HalInfo.vmiData.dwFlags;
1590     pHalInfo->vmiData.dwDisplayWidth = HalInfo.vmiData.dwDisplayWidth;
1591     pHalInfo->vmiData.dwDisplayHeight = HalInfo.vmiData.dwDisplayHeight;
1592     pHalInfo->vmiData.lDisplayPitch = HalInfo.vmiData.lDisplayPitch;
1593     pHalInfo->vmiData.fpPrimary = 0;
1594 
1595     RtlCopyMemory( &pHalInfo->vmiData.ddpfDisplay,
1596                    &HalInfo.vmiData.ddpfDisplay,
1597                    sizeof(DDPIXELFORMAT));
1598 
1599     pHalInfo->vmiData.dwOffscreenAlign = HalInfo.vmiData.dwOffscreenAlign;
1600     pHalInfo->vmiData.dwOverlayAlign = HalInfo.vmiData.dwOverlayAlign;
1601     pHalInfo->vmiData.dwTextureAlign = HalInfo.vmiData.dwTextureAlign;
1602     pHalInfo->vmiData.dwZBufferAlign = HalInfo.vmiData.dwZBufferAlign;
1603     pHalInfo->vmiData.dwAlphaAlign = HalInfo.vmiData.dwAlphaAlign;
1604 
1605     pHalInfo->vmiData.dwNumHeaps = dwNumHeaps;
1606     pHalInfo->vmiData.pvmList = pvmList;
1607 
1608     RtlCopyMemory( &pHalInfo->ddCaps,
1609                    &HalInfo.ddCaps,
1610                    sizeof(DDCORECAPS ));
1611 
1612     pHalInfo->ddCaps.dwNumFourCCCodes = FourCCs;
1613     pHalInfo->lpdwFourCC = pdwFourCC;
1614 
1615     /* always force rope 0x1000 for hal it mean only source copy is supported */
1616     pHalInfo->ddCaps.dwRops[6] = 0x1000;
1617 
1618     /* Set the HAL flags what ReactX got from the driver
1619      * Windows XP force setting DDHALINFO_GETDRIVERINFOSET if the driver does not set it
1620      * and ReactX doing same to keep compatible with drivers, but the driver are
1621      * force support DdGetDriverInfo acoriding MSDN but it seam some driver do not set
1622      * this flag even it is being supported. that is mean. It is small hack to keep
1623      * bad driver working, that trust this is always being setting by it self at end
1624      */
1625     pHalInfo->dwFlags = (HalInfo.dwFlags & ~DDHALINFO_GETDRIVERINFOSET) | DDHALINFO_GETDRIVERINFOSET;
1626     pHalInfo->GetDriverInfo = (LPDDHAL_GETDRIVERINFO) DdGetDriverInfo;
1627 
1628     /* Now check if we got any DD callbacks */
1629     if (pDDCallbacks)
1630     {
1631         /* Zero the structure */
1632         RtlZeroMemory(pDDCallbacks, sizeof(DDHAL_DDCALLBACKS));
1633         pDDCallbacks->dwSize = sizeof(DDHAL_DDCALLBACKS);
1634 
1635         /* Set the flags for this structure
1636          * Windows XP force setting DDHAL_CB32_CREATESURFACE if the driver does not set it
1637          * and ReactX doing same to keep compatible with drivers, but the driver are
1638          * force support pDDCallbacks acoriding MSDN but it seam some driver do not set
1639          * this flag even it is being supported. that is mean. It is small hack to keep
1640          * bad driver working, that trust this is always being setting by it self at end
1641         */
1642         Flags = (CallbackFlags[0] & ~DDHAL_CB32_CREATESURFACE) | DDHAL_CB32_CREATESURFACE;
1643         pDDCallbacks->dwFlags = Flags;
1644 
1645         /* Write the always-on functions */
1646         pDDCallbacks->CreateSurface = DdCreateSurface;
1647 
1648         /* Now write the pointers, if applicable */
1649         if (Flags & DDHAL_CB32_WAITFORVERTICALBLANK)
1650         {
1651             pDDCallbacks->WaitForVerticalBlank = DdWaitForVerticalBlank;
1652         }
1653         if (Flags & DDHAL_CB32_CANCREATESURFACE)
1654         {
1655             pDDCallbacks->CanCreateSurface = DdCanCreateSurface;
1656         }
1657         if (Flags & DDHAL_CB32_GETSCANLINE)
1658         {
1659             pDDCallbacks->GetScanLine = DdGetScanLine;
1660         }
1661     }
1662 
1663     /* Check for DD Surface Callbacks */
1664     if (pDDSurfaceCallbacks)
1665     {
1666         /* Zero the structures */
1667         RtlZeroMemory(pDDSurfaceCallbacks, sizeof(DDHAL_DDSURFACECALLBACKS));
1668         pDDSurfaceCallbacks->dwSize  = sizeof(DDHAL_DDSURFACECALLBACKS);
1669 
1670         /* Set the flags for this structure
1671          * Windows XP force setting DDHAL_SURFCB32_LOCK, DDHAL_SURFCB32_UNLOCK,
1672          * DDHAL_SURFCB32_SETCOLORKEY, DDHAL_SURFCB32_DESTROYSURFACE if the driver
1673          * does not set it and ReactX doing same to keep compatible with drivers,
1674          * but the driver are force support pDDSurfaceCallbacks acoriding MSDN but it seam
1675          * some driver do not set this flag even it is being supported. that is mean.
1676          * It is small hack to keep bad driver working, that trust this is always being
1677          * setting by it self at end
1678          */
1679 
1680         Flags = (CallbackFlags[1] & ~(DDHAL_SURFCB32_LOCK | DDHAL_SURFCB32_UNLOCK |
1681                                       DDHAL_SURFCB32_SETCOLORKEY | DDHAL_SURFCB32_DESTROYSURFACE)) |
1682                 (DDHAL_SURFCB32_LOCK | DDHAL_SURFCB32_UNLOCK |
1683                  DDHAL_SURFCB32_SETCOLORKEY | DDHAL_SURFCB32_DESTROYSURFACE);
1684 
1685         pDDSurfaceCallbacks->dwFlags = Flags;
1686 
1687         /* Write the always-on functions */
1688         pDDSurfaceCallbacks->Lock = DdLock;
1689         pDDSurfaceCallbacks->Unlock = DdUnlock;
1690         pDDSurfaceCallbacks->SetColorKey = DdSetColorKey;
1691         pDDSurfaceCallbacks->DestroySurface = DdDestroySurface;
1692 
1693         /* Write the optional ones */
1694         if (Flags & DDHAL_SURFCB32_FLIP)
1695         {
1696             pDDSurfaceCallbacks->Flip = DdFlip;
1697         }
1698         if (Flags & DDHAL_SURFCB32_BLT)
1699         {
1700             pDDSurfaceCallbacks->Blt = DdBlt;
1701         }
1702         if (Flags & DDHAL_SURFCB32_GETBLTSTATUS)
1703         {
1704             pDDSurfaceCallbacks->GetBltStatus = DdGetBltStatus;
1705         }
1706         if (Flags & DDHAL_SURFCB32_GETFLIPSTATUS)
1707         {
1708             pDDSurfaceCallbacks->GetFlipStatus = DdGetFlipStatus;
1709         }
1710         if (Flags & DDHAL_SURFCB32_UPDATEOVERLAY)
1711         {
1712             pDDSurfaceCallbacks->UpdateOverlay = DdUpdateOverlay;
1713         }
1714         if (Flags & DDHAL_SURFCB32_SETOVERLAYPOSITION)
1715         {
1716             pDDSurfaceCallbacks->SetOverlayPosition = DdSetOverlayPosition;
1717         }
1718         if (Flags & DDHAL_SURFCB32_ADDATTACHEDSURFACE)
1719         {
1720             pDDSurfaceCallbacks->AddAttachedSurface = DdAddAttachedSurface;
1721         }
1722     }
1723 
1724     /* Check for DD Palette Callbacks, This interface are dead for user mode,
1725      * only what it can support are being report back.
1726      */
1727     if (pDDPaletteCallbacks)
1728     {
1729         /* Zero the struct */
1730         RtlZeroMemory(pDDPaletteCallbacks, sizeof(DDHAL_DDPALETTECALLBACKS));
1731 
1732         /* Write the header */
1733         pDDPaletteCallbacks->dwSize  = sizeof(DDHAL_DDPALETTECALLBACKS);
1734         pDDPaletteCallbacks->dwFlags = CallbackFlags[2];
1735     }
1736 
1737     if (pD3dCallbacks)
1738     {
1739         /* Zero the struct */
1740         RtlZeroMemory(pD3dCallbacks, sizeof(DDHAL_DDEXEBUFCALLBACKS));
1741 
1742         /* Check if we have one */
1743         if (D3dCallbacks.dwSize)
1744         {
1745             /* Write the header */
1746             pD3dCallbacks->dwSize = sizeof(DDHAL_DDEXEBUFCALLBACKS);
1747 
1748             /* Now check for each callback */
1749             if (D3dCallbacks.ContextCreate)
1750             {
1751                 pD3dCallbacks->ContextCreate = (LPD3DHAL_CONTEXTCREATECB) D3dContextCreate;
1752             }
1753             if (D3dCallbacks.ContextDestroy)
1754             {
1755                 pD3dCallbacks->ContextDestroy = (LPD3DHAL_CONTEXTDESTROYCB) NtGdiD3dContextDestroy;
1756             }
1757             if (D3dCallbacks.ContextDestroyAll)
1758             {
1759                 pD3dCallbacks->ContextDestroyAll = (LPD3DHAL_CONTEXTDESTROYALLCB) NtGdiD3dContextDestroyAll;
1760             }
1761         }
1762     }
1763 
1764     /* Check for D3D Driver Data */
1765     if (pD3dDriverData)
1766     {
1767         /* Copy the struct */
1768         RtlMoveMemory(pD3dDriverData, &D3dDriverData, sizeof(D3DHAL_GLOBALDRIVERDATA));
1769 
1770         /* Write the pointer to the texture formats */
1771         pD3dDriverData->lpTextureFormats = pD3dTextureFormats;
1772     }
1773 
1774     /* Check for D3D Buffer Callbacks */
1775     if (pD3dBufferCallbacks)
1776     {
1777         /* Zero the struct */
1778         RtlZeroMemory(pD3dBufferCallbacks, sizeof(DDHAL_DDEXEBUFCALLBACKS));
1779 
1780         if ( D3dBufferCallbacks.dwSize)
1781         {
1782             pD3dBufferCallbacks->dwSize = D3dBufferCallbacks.dwSize;
1783 
1784             pD3dBufferCallbacks->dwFlags = D3dBufferCallbacks.dwFlags;
1785             if ( D3dBufferCallbacks.CanCreateD3DBuffer)
1786             {
1787                 pD3dBufferCallbacks->CanCreateExecuteBuffer = (LPDDHALEXEBUFCB_CANCREATEEXEBUF)DdCanCreateD3DBuffer;
1788             }
1789 
1790             if (D3dBufferCallbacks.CreateD3DBuffer)
1791             {
1792                 pD3dBufferCallbacks->CreateExecuteBuffer = (LPDDHALEXEBUFCB_CREATEEXEBUF) DdCreateD3DBuffer;
1793             }
1794 
1795             if ( D3dBufferCallbacks.DestroyD3DBuffer )
1796             {
1797                 pD3dBufferCallbacks->DestroyExecuteBuffer = (LPDDHALEXEBUFCB_DESTROYEXEBUF) DdDestroyD3DBuffer;
1798             }
1799 
1800             if ( D3dBufferCallbacks.LockD3DBuffer )
1801             {
1802                 pD3dBufferCallbacks->LockExecuteBuffer = (LPDDHALEXEBUFCB_LOCKEXEBUF) DdLockD3D;
1803             }
1804 
1805             if ( D3dBufferCallbacks.UnlockD3DBuffer )
1806             {
1807                 pD3dBufferCallbacks->UnlockExecuteBuffer = (LPDDHALEXEBUFCB_UNLOCKEXEBUF) DdUnlockD3D;
1808             }
1809 
1810         }
1811     }
1812 
1813     /* FIXME VidMemList */
1814 
1815 cleanup:
1816     if (VidMemList)
1817     {
1818         HeapFree(GetProcessHeap(), 0, VidMemList);
1819     }
1820 
1821     return retVal;
1822 }
1823 
1824 /*
1825  * @implemented
1826  *
1827  * GDIEntry 3
1828  */
1829 BOOL
1830 WINAPI
1831 DdDeleteDirectDrawObject(LPDDRAWI_DIRECTDRAW_GBL pDirectDrawGlobal)
1832 {
1833     BOOL Return = FALSE;
1834 
1835     /* If this is the global object */
1836     if(pDirectDrawGlobal->hDD)
1837     {
1838         /* Free it */
1839         Return = NtGdiDdDeleteDirectDrawObject((HANDLE)pDirectDrawGlobal->hDD);
1840         if (Return)
1841         {
1842             pDirectDrawGlobal->hDD = 0;
1843         }
1844     }
1845     else if (ghDirectDraw)
1846     {
1847         /* Always success here */
1848         Return = TRUE;
1849 
1850         /* Make sure this is the last instance */
1851         if (!(--gcDirectDraw))
1852         {
1853             /* Delete the object */
1854             Return = NtGdiDdDeleteDirectDrawObject(ghDirectDraw);
1855             if (Return)
1856             {
1857                 ghDirectDraw = 0;
1858             }
1859         }
1860     }
1861 
1862     /* Return */
1863     return Return;
1864 }
1865 
1866 /*
1867  * @implemented
1868  *
1869  * GDIEntry 4
1870  */
1871 BOOL
1872 WINAPI
1873 DdCreateSurfaceObject( LPDDRAWI_DDRAWSURFACE_LCL pSurfaceLocal,
1874                        BOOL bPrimarySurface)
1875 {
1876     return bDDCreateSurface(pSurfaceLocal, TRUE);
1877 }
1878 
1879 
1880 /*
1881  * @implemented
1882  *
1883  * GDIEntry 5
1884  */
1885 BOOL
1886 WINAPI
1887 DdDeleteSurfaceObject(LPDDRAWI_DDRAWSURFACE_LCL pSurfaceLocal)
1888 {
1889     BOOL Return = FALSE;
1890 
1891     /* Make sure there is one */
1892     if (pSurfaceLocal->hDDSurface)
1893     {
1894         /* Delete it */
1895         Return = NtGdiDdDeleteSurfaceObject((HANDLE)pSurfaceLocal->hDDSurface);
1896         pSurfaceLocal->hDDSurface = 0;
1897     }
1898 
1899     return Return;
1900 }
1901 
1902 /*
1903  * @implemented
1904  *
1905  * GDIEntry 6
1906  */
1907 BOOL
1908 WINAPI
1909 DdResetVisrgn(LPDDRAWI_DDRAWSURFACE_LCL pSurfaceLocal,
1910               HWND hWnd)
1911 {
1912     /* Call win32k directly */
1913     return NtGdiDdResetVisrgn((HANDLE) pSurfaceLocal->hDDSurface, hWnd);
1914 }
1915 
1916 /*
1917  * @implemented
1918  *
1919  * GDIEntry 7
1920  */
1921 HDC
1922 WINAPI
1923 DdGetDC(LPDDRAWI_DDRAWSURFACE_LCL pSurfaceLocal,
1924         LPPALETTEENTRY pColorTable)
1925 {
1926     /* Call win32k directly */
1927     return NtGdiDdGetDC((HANDLE)pSurfaceLocal->hDDSurface, pColorTable);
1928 }
1929 
1930 /*
1931  * @implemented
1932  *
1933  * GDIEntry 8
1934  */
1935 BOOL
1936 WINAPI
1937 DdReleaseDC(LPDDRAWI_DDRAWSURFACE_LCL pSurfaceLocal)
1938 {
1939     /* Call win32k directly */
1940     return NtGdiDdReleaseDC((HANDLE) pSurfaceLocal->hDDSurface);
1941 }
1942 
1943 /*
1944  * @unimplemented
1945  * GDIEntry 9
1946  */
1947 HBITMAP
1948 WINAPI
1949 DdCreateDIBSection(HDC hdc,
1950                    CONST BITMAPINFO *pbmi,
1951                    UINT iUsage,
1952                    VOID **ppvBits,
1953                    HANDLE hSectionApp,
1954                    DWORD dwOffset)
1955 {
1956     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1957     return 0;
1958 }
1959 
1960 /*
1961  * @implemented
1962  *
1963  * GDIEntry 10
1964  */
1965 BOOL
1966 WINAPI
1967 DdReenableDirectDrawObject(LPDDRAWI_DIRECTDRAW_GBL pDirectDrawGlobal,
1968                            BOOL *pbNewMode)
1969 {
1970     /* Call win32k directly */
1971     return NtGdiDdReenableDirectDrawObject(GetDdHandle(pDirectDrawGlobal->hDD),
1972                                            pbNewMode);
1973 }
1974 
1975 
1976 /*
1977  * @implemented
1978  *
1979  * GDIEntry 11
1980  */
1981 BOOL
1982 WINAPI
1983 DdAttachSurface( LPDDRAWI_DDRAWSURFACE_LCL pSurfaceFrom,
1984                  LPDDRAWI_DDRAWSURFACE_LCL pSurfaceTo)
1985 {
1986     /* Create Surface if it does not exits one */
1987     if (!pSurfaceFrom->hDDSurface)
1988     {
1989         if (!bDDCreateSurface(pSurfaceFrom, FALSE))
1990         {
1991             return FALSE;
1992         }
1993     }
1994 
1995     /* Create Surface if it does not exits one */
1996     if (!pSurfaceTo->hDDSurface)
1997     {
1998         if (!bDDCreateSurface(pSurfaceTo, FALSE))
1999         {
2000             return FALSE;
2001         }
2002     }
2003 
2004     /* Call win32k */
2005     return NtGdiDdAttachSurface((HANDLE)pSurfaceFrom->hDDSurface,
2006                                 (HANDLE)pSurfaceTo->hDDSurface);
2007 }
2008 
2009 /*
2010  * @implemented
2011  *
2012  * GDIEntry 12
2013  */
2014 VOID
2015 WINAPI
2016 DdUnattachSurface(LPDDRAWI_DDRAWSURFACE_LCL pSurface,
2017                   LPDDRAWI_DDRAWSURFACE_LCL pSurfaceAttached)
2018 {
2019     /* Call win32k */
2020     NtGdiDdUnattachSurface((HANDLE)pSurface->hDDSurface,
2021                            (HANDLE)pSurfaceAttached->hDDSurface);
2022 }
2023 
2024 /*
2025  * @implemented
2026  *
2027  * GDIEntry 13
2028  */
2029 ULONG
2030 WINAPI
2031 DdQueryDisplaySettingsUniqueness(VOID)
2032 {
2033     return GdiSharedHandleTable->flDeviceUniq;
2034 }
2035 
2036 /*
2037  * @implemented
2038  *
2039  * GDIEntry 14
2040  */
2041 HANDLE
2042 WINAPI
2043 DdGetDxHandle(LPDDRAWI_DIRECTDRAW_LCL pDDraw,
2044               LPDDRAWI_DDRAWSURFACE_LCL pSurface,
2045               BOOL bRelease)
2046 {
2047     HANDLE hDD = NULL;
2048     HANDLE hSurface = NULL;
2049 
2050     /* Check if we already have a surface */
2051     if (!pSurface)
2052     {
2053         /* We don't have one, use the DirectDraw Object handle instead */
2054         hDD = GetDdHandle(pDDraw->lpGbl->hDD);
2055     }
2056     else
2057     {
2058         hSurface = (HANDLE)pSurface->hDDSurface;
2059     }
2060 
2061     /* Call the API */
2062     return (HANDLE)NtGdiDdGetDxHandle(hDD, hSurface, bRelease);
2063 }
2064 
2065 /*
2066  * @implemented
2067  *
2068  * GDIEntry 15
2069  */
2070 BOOL
2071 WINAPI
2072 DdSetGammaRamp(LPDDRAWI_DIRECTDRAW_LCL pDDraw,
2073                HDC hdc,
2074                LPVOID lpGammaRamp)
2075 {
2076     /* Call win32k directly */
2077     return NtGdiDdSetGammaRamp(GetDdHandle(pDDraw->lpGbl->hDD),
2078                                hdc,
2079                                lpGammaRamp);
2080 }
2081 
2082 
2083 
2084 
2085