xref: /reactos/win32ss/reactx/ntddraw/ddraw.c (revision 2ea03b5b)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * PURPOSE:          Native DirectDraw implementation
5  * FILE:             win32ss/reactx/ntddraw/ddraw.c
6  * PROGRAMER:        Magnus olsen (magnus@greatlord.com)
7  * REVISION HISTORY:
8  *       19/1-2006   Magnus Olsen
9  */
10 
11 #include <win32k.h>
12 #include <debug.h>
13 
14 PGD_DXDDSTARTUPDXGRAPHICS gpfnStartupDxGraphics = NULL;
15 PGD_DXDDCLEANUPDXGRAPHICS gpfnCleanupDxGraphics = NULL;
16 
17 /* export from dxeng.c */
18 extern DRVFN gaEngFuncs[];
19 extern ULONG gcEngFuncs;
20 extern EDD_DIRECTDRAW_GLOBAL edd_DdirectDraw_Global;
21 
22 
23 DRVFN gpDxFuncs[DXG_INDEX_DxDdIoctl + 1];
24 HANDLE ghDxGraphics = NULL;
25 ULONG gdwDirectDrawContext = 0;
26 
27 #define DXDBG 1
28 
29 /************************************************************************/
30 /* DirectX graphic/video driver loading and cleanup starts here         */
31 /************************************************************************/
32 NTSTATUS
33 APIENTRY
34 DxDdStartupDxGraphics(  ULONG ulc1,
35                         PDRVENABLEDATA DxEngDrvOld,
36                         ULONG ulc2,
37                         PDRVENABLEDATA DxgDrvOld,
38                         PULONG DirectDrawContext,
39                         PEPROCESS Proc)
40 {
41     DRVENABLEDATA DxEngDrv;
42     DRVENABLEDATA DxgDrv;
43 
44     NTSTATUS Status = STATUS_PROCEDURE_NOT_FOUND;
45 
46     /* FIXME: Setup of gaEngFuncs driver export list
47      * but not in this api, we can add it here tempary until we figout where
48      * no code have been writen for it yet
49      */
50 
51 
52     /* FIXME: ReactOS does not loading the dxapi.sys or import functions from it yet */
53     // DxApiGetVersion()
54 
55     /* Loading the kernel interface of DirectX for win32k */
56 
57     DPRINT1("Warning: trying loading xp/2003/windows7/reactos dxg.sys\n");
58     ghDxGraphics = EngLoadImage(L"\\SystemRoot\\System32\\drivers\\dxg.sys");
59     if ( ghDxGraphics == NULL)
60     {
61         Status = STATUS_DLL_NOT_FOUND;
62         DPRINT1("Warning: no ReactX or DirectX kernel driver found\n");
63     }
64     else
65     {
66         /* Import DxDdStartupDxGraphics and  DxDdCleanupDxGraphics */
67         gpfnStartupDxGraphics = EngFindImageProcAddress(ghDxGraphics,"DxDdStartupDxGraphics");
68         gpfnCleanupDxGraphics = EngFindImageProcAddress(ghDxGraphics,"DxDdCleanupDxGraphics");
69 
70         if ((gpfnStartupDxGraphics) &&
71             (gpfnCleanupDxGraphics))
72         {
73             /* Setup driver data for activate the dx interface */
74             DxEngDrv.iDriverVersion = DDI_DRIVER_VERSION_NT5_01;
75             DxEngDrv.pdrvfn = gaEngFuncs;
76             DxEngDrv.c = gcEngFuncs;
77 
78             Status = gpfnStartupDxGraphics ( sizeof(DRVENABLEDATA),
79                                              &DxEngDrv,
80                                              sizeof(DRVENABLEDATA),
81                                              &DxgDrv,
82                                              &gdwDirectDrawContext,
83                                              Proc );
84         }
85 
86         /* Check if we manage loading the data and execute the dxStartupDxGraphics if it is successful */
87         if (!NT_SUCCESS(Status))
88         {
89             gpfnStartupDxGraphics = NULL;
90             gpfnCleanupDxGraphics = NULL;
91             if (ghDxGraphics != NULL)
92             {
93                 EngUnloadImage( ghDxGraphics);
94                 ghDxGraphics = NULL;
95             }
96             DPRINT1("Warning: DirectX graphics interface can not be initialized\n");
97         }
98         else
99         {
100             /* Sort the drv functions list in index order, this allows us doing, smaller optimize
101              * in API that are redirect to dx.sys
102              */
103 
104             PDRVFN lstDrvFN = DxgDrv.pdrvfn;
105             INT t;
106             for (t=0;t<=DXG_INDEX_DxDdIoctl;t++)
107             {
108                 gpDxFuncs[lstDrvFN[t].iFunc].iFunc =lstDrvFN[t].iFunc;
109                 gpDxFuncs[lstDrvFN[t].iFunc].pfn =lstDrvFN[t].pfn;
110             }
111 
112             DPRINT1("DirectX interface is activated\n");
113 
114         }
115         /* Return the status */
116     }
117 
118     return Status;
119 }
120 
121 /************************************************************************/
122 /* DirectX graphic/video driver loading cleanup ends here               */
123 /************************************************************************/
124 
125 /************************************************************************/
126 /* NtGdiDdCreateDirectDrawObject                                        */
127 /************************************************************************/
128 HANDLE
129 APIENTRY
130 NtGdiDdCreateDirectDrawObject(HDC hdc)
131 {
132     PGD_DDCREATEDIRECTDRAWOBJECT pfnDdCreateDirectDrawObject;
133 
134     if (hdc == NULL)
135     {
136         DPRINT1("Warning: hdc is NULL\n");
137         return 0;
138     }
139 
140     /* Get the pfnDdCreateDirectDrawObject after we load the drv */
141     pfnDdCreateDirectDrawObject = (PGD_DDCREATEDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdCreateDirectDrawObject].pfn;
142 
143     if (pfnDdCreateDirectDrawObject == NULL)
144     {
145         DPRINT1("Warning: no pfnDdCreateDirectDrawObject\n");
146         return DDHAL_DRIVER_NOTHANDLED;
147     }
148 
149     DPRINT1("Calling dxg.sys DdCreateDirectDrawObject\n");
150 
151     return pfnDdCreateDirectDrawObject(hdc);
152 }
153 
154 /*++
155 * @name NtGdiDxgGenericThunk
156 * @implemented
157 *
158 * The function NtGdiDxgGenericThunk redirects DirectX calls to another function.
159 * It redirects to dxg.sys in Windows XP/2003, dxkrnl.sys in Vista and is fully implemented in win32k.sys in Windows 2000 and below
160 *
161 * @param ULONG_PTR ulIndex
162 * The functions we want to redirect
163 *
164 * @param ULONG_PTR ulHandle
165 * Unknown
166 *
167 * @param SIZE_T *pdwSizeOfPtr1
168 * Unknown
169 *
170 * @param PVOID pvPtr1
171 * Unknown
172 *
173 * @param SIZE_T *pdwSizeOfPtr2
174 * Unknown
175 *
176 * @param PVOID pvPtr2
177 * Unknown
178 *
179 * @return
180 * Always returns DDHAL_DRIVER_NOTHANDLED
181 *
182 * @remarks.
183 * dxg.sys NtGdiDxgGenericThunk calls are redirected to dxg.sys
184 * This function is no longer used but is still present in Windows NT 2000/XP/2003.
185 *
186 *--*/
187 DWORD
188 APIENTRY
189 NtGdiDxgGenericThunk(ULONG_PTR ulIndex,
190                      ULONG_PTR ulHandle,
191                      SIZE_T *pdwSizeOfPtr1,
192                      PVOID pvPtr1,
193                      SIZE_T *pdwSizeOfPtr2,
194                      PVOID pvPtr2)
195 {
196     PGD_DXGENERICTRUNK pfnDxgGenericThunk = (PGD_DXGENERICTRUNK)gpDxFuncs[DXG_INDEX_DxDxgGenericThunk].pfn;
197 
198     if (pfnDxgGenericThunk == NULL)
199     {
200         DPRINT1("Warning: no pfnDxgGenericThunk\n");
201         return DDHAL_DRIVER_NOTHANDLED;
202     }
203 
204     DPRINT1("Calling dxg.sys pfnDxgGenericThunk\n");
205     return pfnDxgGenericThunk(ulIndex, ulHandle, pdwSizeOfPtr1, pvPtr1, pdwSizeOfPtr2, pvPtr2);
206 }
207 
208 /************************************************************************/
209 /* NtGdiDdGetDriverState                                                */
210 /************************************************************************/
211 DWORD
212 APIENTRY
213 NtGdiDdGetDriverState(PDD_GETDRIVERSTATEDATA pdata)
214 {
215     PGD_DDGETDRIVERSTATE pfnDdGetDriverState = (PGD_DDGETDRIVERSTATE)gpDxFuncs[DXG_INDEX_DxDdGetDriverState].pfn;
216 
217     if (pfnDdGetDriverState == NULL)
218     {
219         DPRINT1("Warning: no pfnDdGetDriverState\n");
220         return DDHAL_DRIVER_NOTHANDLED;
221     }
222 
223     DPRINT1("Calling dxg.sys DdGetDriverState\n");
224     return pfnDdGetDriverState(pdata);
225 }
226 
227 /************************************************************************/
228 /* NtGdiDdColorControl                                                  */
229 /************************************************************************/
230 DWORD
231 APIENTRY
232 NtGdiDdColorControl(HANDLE hSurface,
233                     PDD_COLORCONTROLDATA puColorControlData)
234 {
235     PGD_DDCOLORCONTROL pfnDdColorControl = (PGD_DDCOLORCONTROL)gpDxFuncs[DXG_INDEX_DxDdColorControl].pfn;
236 
237     if (pfnDdColorControl == NULL)
238     {
239         DPRINT1("Warning: no pfnDdColorControl\n");
240         return DDHAL_DRIVER_NOTHANDLED;
241     }
242 
243     DPRINT1("Calling dxg.sys DdColorControl\n");
244     return pfnDdColorControl(hSurface,puColorControlData);
245 }
246 
247 /************************************************************************/
248 /* NtGdiDdCreateSurfaceObject                                           */
249 /************************************************************************/
250 HANDLE
251 APIENTRY
252 NtGdiDdCreateSurfaceObject(HANDLE hDirectDrawLocal,
253                            HANDLE hSurface,
254                            PDD_SURFACE_LOCAL puSurfaceLocal,
255                            PDD_SURFACE_MORE puSurfaceMore,
256                            PDD_SURFACE_GLOBAL puSurfaceGlobal,
257                            BOOL bComplete
258 )
259 {
260     PGD_DXDDCREATESURFACEOBJECT pfnDdCreateSurfaceObject = (PGD_DXDDCREATESURFACEOBJECT)gpDxFuncs[DXG_INDEX_DxDdCreateSurfaceObject].pfn;
261 
262     if (pfnDdCreateSurfaceObject == NULL)
263     {
264         DPRINT1("Warning: no pfnDdCreateSurfaceObject\n");
265         return DDHAL_DRIVER_NOTHANDLED;
266     }
267 
268     DPRINT1("Calling dxg.sys pfnDdCreateSurfaceObject\n");
269     return pfnDdCreateSurfaceObject(hDirectDrawLocal, hSurface, puSurfaceLocal, puSurfaceMore, puSurfaceGlobal, bComplete);
270 }
271 
272 /************************************************************************/
273 /* NtGdiDdDeleteDirectDrawObject                                        */
274 /************************************************************************/
275 BOOL
276 APIENTRY
277 NtGdiDdDeleteDirectDrawObject(HANDLE hDirectDrawLocal)
278 {
279     PGD_DXDDDELETEDIRECTDRAWOBJECT pfnDdDeleteDirectDrawObject = (PGD_DXDDDELETEDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdDeleteDirectDrawObject].pfn;
280 
281     if (pfnDdDeleteDirectDrawObject == NULL)
282     {
283         DPRINT1("Warning: no pfnDdDeleteDirectDrawObject\n");
284         return FALSE;
285     }
286 
287     if (hDirectDrawLocal == NULL)
288     {
289          DPRINT1("Warning: hDirectDrawLocal is NULL\n");
290          return FALSE;
291     }
292 
293     DPRINT1("hDirectDrawLocal = %p \n", hDirectDrawLocal);
294     DPRINT1("Calling dxg.sys pfnDdDeleteDirectDrawObject\n");
295 
296     return pfnDdDeleteDirectDrawObject(hDirectDrawLocal);
297 }
298 
299 /************************************************************************/
300 /* NtGdiDdDeleteSurfaceObject                                           */
301 /************************************************************************/
302 BOOL
303 APIENTRY
304 NtGdiDdDeleteSurfaceObject(HANDLE hSurface)
305 {
306     PGD_DXDDDELETESURFACEOBJECT pfnDdDeleteSurfaceObject = (PGD_DXDDDELETESURFACEOBJECT)gpDxFuncs[DXG_INDEX_DxDdDeleteSurfaceObject].pfn;
307 
308     if (pfnDdDeleteSurfaceObject == NULL)
309     {
310         DPRINT1("Warning: no pfnDdDeleteSurfaceObject\n");
311         return DDHAL_DRIVER_NOTHANDLED;
312     }
313     /* Try and see if the handle is valid */
314 
315     DPRINT1("Calling dxg.sys DdDeleteSurfaceObject\n");
316     return pfnDdDeleteSurfaceObject(hSurface);
317 }
318 
319 /************************************************************************/
320 /* NtGdiDdQueryDirectDrawObject                                         */
321 /************************************************************************/
322 BOOL
323 APIENTRY
324 NtGdiDdQueryDirectDrawObject(HANDLE hDirectDrawLocal,
325                              DD_HALINFO  *pHalInfo,
326                              DWORD *pCallBackFlags,
327                              LPD3DNTHAL_CALLBACKS puD3dCallbacks,
328                              LPD3DNTHAL_GLOBALDRIVERDATA puD3dDriverData,
329                              PDD_D3DBUFCALLBACKS puD3dBufferCallbacks,
330                              LPDDSURFACEDESC puD3dTextureFormats,
331                              DWORD *puNumHeaps,
332                              VIDEOMEMORY *puvmList,
333                              DWORD *puNumFourCC,
334                              DWORD *puFourCC)
335 {
336     PGD_DXDDQUERYDIRECTDRAWOBJECT pfnDdQueryDirectDrawObject = (PGD_DXDDQUERYDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdQueryDirectDrawObject].pfn;
337 
338     if (pfnDdQueryDirectDrawObject == NULL)
339     {
340         DPRINT1("Warning: no pfnDdQueryDirectDrawObject\n");
341         return DDHAL_DRIVER_NOTHANDLED;
342     }
343 
344     DPRINT1("Calling dxg.sys pfnDdQueryDirectDrawObject\n");
345 
346 
347     return pfnDdQueryDirectDrawObject(hDirectDrawLocal, pHalInfo, pCallBackFlags, puD3dCallbacks, puD3dDriverData,
348                                       puD3dBufferCallbacks, puD3dTextureFormats, puNumHeaps, puvmList, puNumFourCC, puFourCC);
349 
350 }
351 
352 
353 /************************************************************************/
354 /* NtGdiDdReenableDirectDrawObject                                      */
355 /************************************************************************/
356 BOOL
357 APIENTRY
358 NtGdiDdReenableDirectDrawObject(HANDLE hDirectDrawLocal,
359                                 BOOL *pubNewMode)
360 {
361 #if DXDBG
362     BOOL status = FALSE;
363 #endif
364     PGD_DXDDREENABLEDIRECTDRAWOBJECT pfnDdReenableDirectDrawObject = (PGD_DXDDREENABLEDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdReenableDirectDrawObject].pfn;
365 
366     if (pfnDdReenableDirectDrawObject == NULL)
367     {
368         DPRINT1("Warning: no pfnDdReenableDirectDrawObject\n");
369         return DDHAL_DRIVER_NOTHANDLED;
370     }
371 
372     DPRINT1("Calling dxg.sys pfnDdReenableDirectDrawObject\n");
373 
374 #if DXDBG
375     status = pfnDdReenableDirectDrawObject(hDirectDrawLocal, pubNewMode);
376     DPRINT1("end Calling dxg.sys pfnDdReenableDirectDrawObject\n");
377     DPRINT1("return value : 0x%08x\n", status);
378     return status;
379 #else
380     return pfnDdReenableDirectDrawObject(hDirectDrawLocal, pubNewMode);
381 #endif
382 }
383 
384 
385 /************************************************************************/
386 /* NtGdiDdGetDriverInfo                                                 */
387 /************************************************************************/
388 DWORD
389 APIENTRY
390 NtGdiDdGetDriverInfo(HANDLE hDirectDrawLocal,
391                      PDD_GETDRIVERINFODATA puGetDriverInfoData)
392 
393 {
394     PGD_DXDDGETDRIVERINFO pfnDdGetDriverInfo = (PGD_DXDDGETDRIVERINFO)gpDxFuncs[DXG_INDEX_DxDdGetDriverInfo].pfn;
395 
396     if (pfnDdGetDriverInfo == NULL)
397     {
398         DPRINT1("Warning: no pfnDdGetDriverInfo\n");
399         return DDHAL_DRIVER_NOTHANDLED;
400     }
401 
402     DPRINT1("Calling dxg.sys pfnDdGetDriverInfo\n");
403     return pfnDdGetDriverInfo(hDirectDrawLocal, puGetDriverInfoData);
404 }
405 
406 
407 /************************************************************************/
408 /* NtGdiDdGetAvailDriverMemory                                          */
409 /************************************************************************/
410 DWORD
411 APIENTRY
412 NtGdiDdGetAvailDriverMemory(HANDLE hDirectDrawLocal,
413                             PDD_GETAVAILDRIVERMEMORYDATA puGetAvailDriverMemoryData)
414 {
415     PGD_DXDDGETAVAILDRIVERMEMORY pfnDdGetAvailDriverMemory = (PGD_DXDDGETAVAILDRIVERMEMORY)gpDxFuncs[DXG_INDEX_DxDdGetAvailDriverMemory].pfn;
416 
417     if (pfnDdGetAvailDriverMemory == NULL)
418     {
419         DPRINT1("Warning: no pfnDdGetAvailDriverMemory\n");
420         return DDHAL_DRIVER_NOTHANDLED;
421     }
422 
423     DPRINT1("Calling dxg.sys pfnDdGetAvailDriverMemory\n");
424     return pfnDdGetAvailDriverMemory(hDirectDrawLocal, puGetAvailDriverMemoryData);
425 }
426 
427 
428 /************************************************************************/
429 /* NtGdiDdSetExclusiveMode                                              */
430 /************************************************************************/
431 
432 DWORD
433 APIENTRY
434 NtGdiDdSetExclusiveMode(HANDLE hDirectDraw,
435                         PDD_SETEXCLUSIVEMODEDATA puSetExclusiveModeData)
436 {
437     PGD_DXDDSETEXCLUSIVEMODE pfnDdSetExclusiveMode = (PGD_DXDDSETEXCLUSIVEMODE)gpDxFuncs[DXG_INDEX_DxDdSetExclusiveMode].pfn;
438 
439     if (pfnDdSetExclusiveMode == NULL)
440     {
441         DPRINT1("Warning: no pfnDdSetExclusiveMode\n");
442         return DDHAL_DRIVER_NOTHANDLED;
443     }
444 
445     DPRINT1("Calling dxg.sys pfnDdSetExclusiveMode\n");
446     return pfnDdSetExclusiveMode(hDirectDraw, puSetExclusiveModeData);
447 
448 }
449 
450 
451 /************************************************************************/
452 /* NtGdiDdFlipToGDISurface                                              */
453 /************************************************************************/
454 DWORD
455 APIENTRY
456 NtGdiDdFlipToGDISurface(HANDLE hDirectDraw,
457                         PDD_FLIPTOGDISURFACEDATA puFlipToGDISurfaceData)
458 {
459     PGD_DXDDFLIPTOGDISURFACE pfnDdFlipToGDISurface = (PGD_DXDDFLIPTOGDISURFACE)gpDxFuncs[DXG_INDEX_DxDdFlipToGDISurface].pfn;
460 
461     if (pfnDdFlipToGDISurface == NULL)
462     {
463         DPRINT1("Warning: no pfnDdFlipToGDISurface\n");
464         return DDHAL_DRIVER_NOTHANDLED;
465     }
466 
467     DPRINT1("Calling dxg.sys pfnDdFlipToGDISurface\n");
468     return pfnDdFlipToGDISurface(hDirectDraw, puFlipToGDISurfaceData);
469 
470 }
471 
472 /************************************************************************/
473 /* NtGdiDdGetDC                                                         */
474 /************************************************************************/
475 HDC
476 APIENTRY
477 NtGdiDdGetDC(HANDLE hSurface,
478              PALETTEENTRY *puColorTable)
479 {
480     PGD_DDGETDC pfnDdGetDC = (PGD_DDGETDC)gpDxFuncs[DXG_INDEX_DxDdGetDC].pfn;
481 
482     if (pfnDdGetDC == NULL)
483     {
484         DPRINT1("Warning: no pfnDdGetDC\n");
485         return DDHAL_DRIVER_NOTHANDLED;
486     }
487 
488     DPRINT1("Calling dxg.sys pfnDdGetDC\n");
489     return pfnDdGetDC(hSurface, puColorTable);
490 }
491 
492 /************************************************************************/
493 /* NtGdiDdGetDxHandle                                                   */
494 /************************************************************************/
495 HANDLE
496 APIENTRY
497 NtGdiDdGetDxHandle(HANDLE hDirectDraw,
498                    HANDLE hSurface,
499                    BOOL bRelease)
500 {
501     PGD_DDGETDXHANDLE pfnDdGetDxHandle = (PGD_DDGETDXHANDLE)gpDxFuncs[DXG_INDEX_DxDdGetDxHandle].pfn;
502 
503     if (pfnDdGetDxHandle == NULL)
504     {
505         DPRINT1("Warning: no pfnDdGetDxHandle\n");
506         return DDHAL_DRIVER_NOTHANDLED;
507     }
508 
509     DPRINT1("Calling dxg.sys pfnDdGetDxHandle\n");
510     return pfnDdGetDxHandle(hDirectDraw, hSurface, bRelease);
511 }
512 
513 
514 /************************************************************************/
515 /* NtGdiDdReleaseDC                                                     */
516 /************************************************************************/
517 BOOL
518 APIENTRY
519 NtGdiDdReleaseDC(HANDLE hSurface)
520 {
521     PGD_DDRELEASEDC pfnDdReleaseDC = (PGD_DDRELEASEDC)gpDxFuncs[DXG_INDEX_DxDdReleaseDC].pfn;
522 
523     if (pfnDdReleaseDC == NULL)
524     {
525         DPRINT1("Warning: no pfnDdReleaseDC\n");
526         return DDHAL_DRIVER_NOTHANDLED;
527     }
528 
529     DPRINT1("Calling dxg.sys pfnDdReleaseDC\n");
530     return pfnDdReleaseDC(hSurface);
531 }
532 
533 /************************************************************************/
534 /* NtGdiDdResetVisrgn                                                   */
535 /************************************************************************/
536 BOOL
537 APIENTRY
538 NtGdiDdResetVisrgn(HANDLE hSurface,
539                    HWND hwnd)
540 {
541 
542     PGD_DDRESTVISRGN pfnDdResetVisrgn = (PGD_DDRESTVISRGN)gpDxFuncs[DXG_INDEX_DxDdResetVisrgn].pfn;
543 
544     if (pfnDdResetVisrgn == NULL)
545     {
546         DPRINT1("Warning: no pfnDdResetVisrgn\n");
547         return DDHAL_DRIVER_NOTHANDLED;
548     }
549 
550     DPRINT1("Calling dxg.sys pfnDdResetVisrgn\n");
551     return pfnDdResetVisrgn(hSurface, hwnd);
552 }
553 
554 /************************************************************************/
555 /* NtGdiDdSetGammaRamp                                                  */
556 /************************************************************************/
557 BOOL
558 APIENTRY
559 NtGdiDdSetGammaRamp(HANDLE hDirectDraw,
560                     HDC hdc,
561                     LPVOID lpGammaRamp)
562 {
563     PGD_DDSETGAMMARAMP pfnDdSetGammaRamp = (PGD_DDSETGAMMARAMP)gpDxFuncs[DXG_INDEX_DxDdSetGammaRamp].pfn;
564 
565     if (pfnDdSetGammaRamp == NULL)
566     {
567         DPRINT1("Warning: no pfnDdSetGammaRamp\n");
568         return DDHAL_DRIVER_NOTHANDLED;
569     }
570 
571     DPRINT1("Calling dxg.sys pfnDdSetGammaRamp\n");
572     return pfnDdSetGammaRamp(hDirectDraw, hdc, lpGammaRamp);
573 }
574