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