Take care of one BSOD in NtGdiDdCreateDirectDrawObject, it is not correct fix, it...
[reactos.git] / reactos / subsys / win32k / ntddraw / ddraw.c
index bda7125..4077b57 100644 (file)
@@ -1,5 +1,4 @@
-/* 
- *
+/*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Native DirectDraw implementation
@@ -8,88 +7,54 @@
  * REVISION HISTORY:
  *       25-10-2003  PB  Created
  */
-#include <ddk/ntddk.h>
-#include <win32k/win32k.h>
-#include <win32k/gdiobj.h>
+
+#include <w32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
-#define GDI_OBJECT_TYPE_DIRECTDRAW    0x00600000
-#define GDI_OBJECT_TYPE_DD_SURFACE    0x00610000
-#define GDI_OBJECT_TYPE_DD_VIDEOPORT  0x00620000
-#define GDI_OBJECT_TYPE_DD_PALETTE    0x00630000
-#define GDI_OBJECT_TYPE_DD_CLIPPER    0x00640000
-#define GDI_OBJECT_TYPE_DD_MOTIONCOMP 0x00650000
-
 /************************************************************************/
 /* DIRECT DRAW OBJECT                                                   */
 /************************************************************************/
 
-typedef struct
-{
-       DD_DIRECTDRAW_LOCAL Local;
-       DD_DIRECTDRAW_GLOBAL Global;
-       // Drv callbacks
-       PGD_GETDIRECTDRAWINFO           DrvGetDirectDrawInfo;
-       PGD_DISABLEDIRECTDRAW           DrvDisableDirectDraw;
-       // DD callbacks
-       PDD_CREATESURFACE               DdCreateSurface;
-       PDD_SETCOLORKEY                 DdDrvSetColorKey; // ?????
-       PDD_WAITFORVERTICALBLANK        DdWaitForVerticalBlank;
-       PDD_CANCREATESURFACE            DdCanCreateSurface;
-       PDD_CREATEPALETTE               DdCreatePalette;
-       PDD_GETSCANLINE                 DdGetScanLine;
-       PDD_MAPMEMORY                   DdMapMemory;
-       // Surface callbacks
-       PDD_SURFCB_DESTROYSURFACE           DdDestroySurface;
-       PDD_SURFCB_FLIP                 DdFlip;
-       PDD_SURFCB_SETCLIPLIST          DdSetClipList;
-       PDD_SURFCB_LOCK                 DdLock;
-       PDD_SURFCB_UNLOCK               DdUnlock;
-       PDD_SURFCB_BLT                  DdBlt;
-       PDD_SURFCB_SETCOLORKEY          DdSetColorKey;
-       PDD_SURFCB_ADDATTACHEDSURFACE   DdAddAttachedSurface;
-       PDD_SURFCB_GETBLTSTATUS         DdGetBltStatus;
-       PDD_SURFCB_GETFLIPSTATUS        DdGetFlipStatus;
-       PDD_SURFCB_UPDATEOVERLAY        DdUpdateOverlay;
-       PDD_SURFCB_SETOVERLAYPOSITION   DdSetOverlayPosition;
-       PDD_SURFCB_SETPALETTE           DdSetPalette;
-       // Palette callbacks
-       PDD_PALCB_DESTROYPALETTE        DdDestroyPalette;
-       PDD_PALCB_SETENTRIES            DdSetEntries;
-       // D3D Device context callbacks
-       PD3DNTHAL_CONTEXTCREATECB       D3dContextCreate;
-       PD3DNTHAL_CONTEXTDESTROYCB      D3dContextDestroy;
-       // D3D Buffer callbacks
-       PDD_CANCREATESURFACE            DdCanCreateD3DBuffer;
-       PDD_CREATESURFACE               DdCreateD3DBuffer;
-       PDD_SURFCB_DESTROYSURFACE       DdDestroyD3DBuffer;
-       PDD_SURFCB_LOCK                 DdLockD3DBuffer;
-       PDD_SURFCB_UNLOCK               DdUnlockD3DBuffer;
-} DD_DIRECTDRAW, *PDD_DIRECTDRAW;
-
-static BOOL FASTCALL DirectDrawCleanup(PDD_DIRECTDRAW pDirectDraw)
+BOOL INTERNAL_CALL
+DD_Cleanup(PVOID ObjectBody)
 {
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(ObjectBody, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("DD_Cleanup\n");
+       
+       if (!pDirectDraw)
+               return FALSE;
+
        pDirectDraw->DrvDisableDirectDraw(pDirectDraw->Global.dhpdev);
+
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);
        return TRUE;
 }
 
-HANDLE STDCALL NtGdiDdCreateDirectDrawObject(      
+HANDLE STDCALL NtGdiDdCreateDirectDrawObject(
     HDC hdc
 )
 {
        DD_CALLBACKS callbacks;
        DD_SURFACECALLBACKS surface_callbacks;
        DD_PALETTECALLBACKS palette_callbacks;
-
-       RtlZeroMemory(&callbacks, sizeof(callbacks));
-       callbacks.dwSize = sizeof(callbacks);
-       RtlZeroMemory(&surface_callbacks, sizeof(surface_callbacks));
-       surface_callbacks.dwSize = sizeof(surface_callbacks);
-       RtlZeroMemory(&palette_callbacks, sizeof(palette_callbacks));
-       palette_callbacks.dwSize = sizeof(palette_callbacks);
-
+       DPRINT1("NtGdiDdCreateDirectDrawObject\n");
+
+       RtlZeroMemory(&callbacks, sizeof(DD_CALLBACKS));
+       callbacks.dwSize = sizeof(DD_CALLBACKS);
+       RtlZeroMemory(&surface_callbacks, sizeof(DD_SURFACECALLBACKS));
+       surface_callbacks.dwSize = sizeof(DD_SURFACECALLBACKS);
+       RtlZeroMemory(&palette_callbacks, sizeof(DD_PALETTECALLBACKS));
+       palette_callbacks.dwSize = sizeof(DD_PALETTECALLBACKS);
+
+       /* FIXME hdc can be zero for d3d9 */
+    /* we need create it, if in that case */
+       if (hdc == NULL)
+       {
+           return NULL;
+    }
+    
        DC *pDC = DC_LockDc(hdc);
        if (!pDC)
                return NULL;
@@ -97,22 +62,36 @@ HANDLE STDCALL NtGdiDdCreateDirectDrawObject(
        if (!pDC->DriverFunctions.EnableDirectDraw)
        {
                // Driver doesn't support DirectDraw
-               DC_UnlockDc(hdc);
+               DC_UnlockDc(pDC);
                return NULL;
        }
-
+       
        BOOL success = pDC->DriverFunctions.EnableDirectDraw(
                pDC->PDev, &callbacks, &surface_callbacks, &palette_callbacks);
 
        if (!success)
        {
                // DirectDraw creation failed
-               DC_UnlockDc(hdc);
+               DC_UnlockDc(pDC);
+               return NULL;
+       }
+
+       HANDLE hDirectDraw = GDIOBJ_AllocObj(GDI_OBJECT_TYPE_DIRECTDRAW);
+       if (!hDirectDraw)
+       {
+               /* No more memmory */
+               DC_UnlockDc(pDC);
                return NULL;
        }
 
-       HANDLE hDirectDraw = GDIOBJ_AllocObj(sizeof(DD_DIRECTDRAW), GDI_OBJECT_TYPE_DIRECTDRAW, (GDICLEANUPPROC)DirectDrawCleanup);
        PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDraw, GDI_OBJECT_TYPE_DIRECTDRAW);
+       if (!pDirectDraw)
+       {
+               /* invalid handle */
+               DC_UnlockDc(pDC);
+               return NULL;
+       }
+       
 
        pDirectDraw->Global.dhpdev = pDC->PDev;
        pDirectDraw->Local.lpGbl = &pDirectDraw->Global;
@@ -120,72 +99,35 @@ HANDLE STDCALL NtGdiDdCreateDirectDrawObject(
        pDirectDraw->DrvGetDirectDrawInfo = pDC->DriverFunctions.GetDirectDrawInfo;
        pDirectDraw->DrvDisableDirectDraw = pDC->DriverFunctions.DisableDirectDraw;
 
-       if (callbacks.dwFlags && DDHAL_CB32_CREATESURFACE)
-               pDirectDraw->DdCreateSurface = callbacks.CreateSurface;
-       if (callbacks.dwFlags && DDHAL_CB32_SETCOLORKEY)
-               pDirectDraw->DdDrvSetColorKey = callbacks.SetColorKey;
-       if (callbacks.dwFlags && DDHAL_CB32_WAITFORVERTICALBLANK)
-               pDirectDraw->DdWaitForVerticalBlank = callbacks.WaitForVerticalBlank;
-       if (callbacks.dwFlags && DDHAL_CB32_CANCREATESURFACE)
-               pDirectDraw->DdCanCreateSurface = callbacks.CanCreateSurface;
-       if (callbacks.dwFlags && DDHAL_CB32_CREATEPALETTE)
-               pDirectDraw->DdCreatePalette = callbacks.CreatePalette;
-       if (callbacks.dwFlags && DDHAL_CB32_GETSCANLINE)
-               pDirectDraw->DdGetScanLine = callbacks.GetScanLine;
-       if (callbacks.dwFlags && DDHAL_CB32_MAPMEMORY)
-               pDirectDraw->DdMapMemory = callbacks.MapMemory;
-
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_DESTROYSURFACE)
-               pDirectDraw->DdDestroySurface = surface_callbacks.DestroySurface;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_FLIP)
-               pDirectDraw->DdFlip = surface_callbacks.Flip;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETCLIPLIST)
-               pDirectDraw->DdSetClipList = surface_callbacks.SetClipList;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_LOCK)
-               pDirectDraw->DdLock = surface_callbacks.Lock;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_UNLOCK)
-               pDirectDraw->DdUnlock = surface_callbacks.Unlock;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_BLT)
-               pDirectDraw->DdBlt = surface_callbacks.Blt;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETCOLORKEY)
-               pDirectDraw->DdSetColorKey = surface_callbacks.SetColorKey;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_ADDATTACHEDSURFACE)
-               pDirectDraw->DdAddAttachedSurface = surface_callbacks.AddAttachedSurface;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_GETBLTSTATUS)
-               pDirectDraw->DdGetBltStatus = surface_callbacks.GetBltStatus;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_GETFLIPSTATUS)
-               pDirectDraw->DdGetFlipStatus = surface_callbacks.GetFlipStatus;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_UPDATEOVERLAY)
-               pDirectDraw->DdUpdateOverlay = surface_callbacks.UpdateOverlay;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETOVERLAYPOSITION)
-               pDirectDraw->DdSetOverlayPosition = surface_callbacks.SetOverlayPosition;
-       if (surface_callbacks.dwFlags && DDHAL_SURFCB32_SETPALETTE)
-               pDirectDraw->DdSetPalette = surface_callbacks.SetPalette;
-
-       if (palette_callbacks.dwFlags && DDHAL_PALCB32_DESTROYPALETTE)
-               pDirectDraw->DdDestroyPalette = palette_callbacks.DestroyPalette;
-       if (palette_callbacks.dwFlags && DDHAL_PALCB32_SETENTRIES)
-               pDirectDraw->DdSetEntries = palette_callbacks.SetEntries;
-
-       GDIOBJ_UnlockObj(hDirectDraw, GDI_OBJECT_TYPE_DIRECTDRAW);
-       DC_UnlockDc(hdc);
+    /* DD_CALLBACKS setup */   
+       RtlMoveMemory(&pDirectDraw->DD, &callbacks, sizeof(DD_CALLBACKS));
+       
+       /* DD_SURFACECALLBACKS  setup*/ 
+       RtlMoveMemory(&pDirectDraw->Surf, &surface_callbacks, sizeof(DD_SURFACECALLBACKS));
+
+       /* DD_PALETTECALLBACKS setup*/  
+       RtlMoveMemory(&pDirectDraw->Pal, &surface_callbacks, sizeof(DD_PALETTECALLBACKS));
+       
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);
+       DC_UnlockDc(pDC);
 
        return hDirectDraw;
 }
 
-BOOL STDCALL NtGdiDdDeleteDirectDrawObject(      
+BOOL STDCALL NtGdiDdDeleteDirectDrawObject(
     HANDLE hDirectDrawLocal
 )
 {
-       return GDIOBJ_FreeObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW, 0);
+    DPRINT1("NtGdiDdDeleteDirectDrawObject\n");
+       return GDIOBJ_FreeObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
 }
 
-BOOL STDCALL NtGdiDdQueryDirectDrawObject(      
+BOOL STDCALL NtGdiDdQueryDirectDrawObject(
     HANDLE hDirectDrawLocal,
     DD_HALINFO *pHalInfo,
     DWORD *pCallBackFlags,
-    PD3DNTHAL_CALLBACKS puD3dCallbacks,
-    PD3DNTHAL_GLOBALDRIVERDATA puD3dDriverData,
+    LPD3DNTHAL_CALLBACKS puD3dCallbacks,
+    LPD3DNTHAL_GLOBALDRIVERDATA puD3dDriverData,
     PDD_D3DBUFCALLBACKS puD3dBufferCallbacks,
     LPDDSURFACEDESC puD3dTextureFormats,
     DWORD *puNumHeaps,
@@ -195,6 +137,8 @@ BOOL STDCALL NtGdiDdQueryDirectDrawObject(
 )
 {
        PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdQueryDirectDrawObject\n");
+       
        if (!pDirectDraw)
                return FALSE;
 
@@ -208,58 +152,590 @@ BOOL STDCALL NtGdiDdQueryDirectDrawObject(
 
        if (!success)
        {
-               GDIOBJ_UnlockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+               GDIOBJ_UnlockObjByPtr(pDirectDraw);
                return FALSE;
        }
 
-       if (pHalInfo->lpD3DHALCallbacks)
+       if (pHalInfo)
        {
-               RtlMoveMemory(puD3dCallbacks, pHalInfo->lpD3DHALCallbacks, sizeof(D3DNTHAL_CALLBACKS));
-               pDirectDraw->D3dContextCreate = puD3dCallbacks->ContextCreate;
-               pDirectDraw->D3dContextDestroy = puD3dCallbacks->ContextDestroy;
+       RtlMoveMemory(&pDirectDraw->Hal, pHalInfo, sizeof(DD_HALINFO));
+
+          if (pHalInfo->lpD3DHALCallbacks)
+          {
+                RtlMoveMemory(puD3dCallbacks, pHalInfo->lpD3DHALCallbacks, sizeof(D3DNTHAL_CALLBACKS));                
+          }
+
+          if (pHalInfo->lpD3DGlobalDriverData)
+          {
+                RtlMoveMemory(puD3dDriverData, pHalInfo->lpD3DGlobalDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
+          }
+          if (pHalInfo->lpD3DBufCallbacks)
+          {
+                RtlMoveMemory(puD3dBufferCallbacks, pHalInfo->lpD3DBufCallbacks, sizeof(DD_D3DBUFCALLBACKS));
+          }
+                       
+        }
+        
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);
+
+       return TRUE;
+}
+
+
+DWORD STDCALL NtGdiDdGetDriverInfo(
+    HANDLE hDirectDrawLocal,
+    PDD_GETDRIVERINFODATA puGetDriverInfoData)
+
+{
+       DWORD  ddRVal;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdGetDriverInfo\n");
+       
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       if   (!(pDirectDraw->Hal.dwFlags & DDHALINFO_GETDRIVERINFOSET))
+            ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+            ddRVal = pDirectDraw->Hal.GetDriverInfo(puGetDriverInfoData);
+   
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+
+       return ddRVal;
+}
+
+/************************************************************************/
+/* DD CALLBACKS                                                         */
+/* FIXME NtGdiDdCreateSurface we do not call to ddCreateSurface         */
+/************************************************************************/
+
+DWORD STDCALL NtGdiDdCreateSurface(
+    HANDLE hDirectDrawLocal,
+    HANDLE *hSurface,
+    DDSURFACEDESC *puSurfaceDescription,
+    DD_SURFACE_GLOBAL *puSurfaceGlobalData,
+    DD_SURFACE_LOCAL *puSurfaceLocalData,
+    DD_SURFACE_MORE *puSurfaceMoreData,
+    PDD_CREATESURFACEDATA puCreateSurfaceData,
+    HANDLE *puhSurface
+)
+{
+       DWORD  ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+       DPRINT1("NtGdiDdCreateSurface\n");
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puCreateSurfaceData->lpDD;
+
+       /* use our cache version instead */
+       puCreateSurfaceData->lpDD = &pDirectDraw->Global;
+       
+       /* make the call */
+       if (!(pDirectDraw->DD.dwFlags & DDHAL_CB32_CANCREATESURFACE))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+       {         
+          ddRVal = pDirectDraw->DD.CreateSurface(puCreateSurfaceData);  
        }
 
-       if (pHalInfo->lpD3DGlobalDriverData)
+       /* But back the orignal PDev */
+       puCreateSurfaceData->lpDD = lgpl;
+    
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);     
+       return ddRVal;
+}
+
+DWORD STDCALL NtGdiDdWaitForVerticalBlank(
+    HANDLE hDirectDrawLocal,
+    PDD_WAITFORVERTICALBLANKDATA puWaitForVerticalBlankData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+       DPRINT1("NtGdiDdWaitForVerticalBlank\n");
+
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puWaitForVerticalBlankData->lpDD;
+
+       /* use our cache version instead */
+       puWaitForVerticalBlankData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->DD.dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else    
+           ddRVal = pDirectDraw->DD.WaitForVerticalBlank(puWaitForVerticalBlankData);
+
+       /* But back the orignal PDev */
+       puWaitForVerticalBlankData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+       return ddRVal;
+}
+
+DWORD STDCALL NtGdiDdCanCreateSurface(
+    HANDLE hDirectDrawLocal,
+    PDD_CANCREATESURFACEDATA puCanCreateSurfaceData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;     
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdCanCreateSurface\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puCanCreateSurfaceData->lpDD;
+
+       /* use our cache version instead */
+       puCanCreateSurfaceData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->DD.dwFlags & DDHAL_CB32_CANCREATESURFACE))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else    
+           ddRVal = pDirectDraw->DD.CanCreateSurface(puCanCreateSurfaceData);
+
+       /* But back the orignal PDev */
+       puCanCreateSurfaceData->lpDD = lgpl;
+
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);
+       return ddRVal;
+}
+
+DWORD STDCALL NtGdiDdGetScanLine(
+    HANDLE hDirectDrawLocal,
+    PDD_GETSCANLINEDATA puGetScanLineData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdGetScanLine\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puGetScanLineData->lpDD;
+
+       /* use our cache version instead */
+       puGetScanLineData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->DD.dwFlags & DDHAL_CB32_GETSCANLINE))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else    
+           ddRVal = pDirectDraw->DD.GetScanLine(puGetScanLineData);
+
+       /* But back the orignal PDev */
+       puGetScanLineData->lpDD = lgpl;
+
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);
+       return ddRVal;
+}
+
+
+
+/************************************************************************/
+/* Surface CALLBACKS                                                    */
+/* FIXME                                                                */
+/* NtGdiDdDestroySurface                                                */ 
+/************************************************************************/
+
+DWORD STDCALL NtGdiDdDestroySurface(
+    HANDLE hSurface,
+    BOOL bRealDestroy
+)
+{      
+       DWORD  ddRVal  = DDHAL_DRIVER_NOTHANDLED;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdDestroySurface\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_DESTROYSURFACE))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else    
        {
-               RtlMoveMemory(puD3dDriverData, pHalInfo->lpD3DGlobalDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
-       }
+               DD_DESTROYSURFACEDATA DestroySurf; 
        
-       if (pHalInfo->lpD3DBufCallbacks)
-       {
-               RtlMoveMemory(puD3dBufferCallbacks, pHalInfo->lpD3DBufCallbacks, sizeof(DD_D3DBUFCALLBACKS));
-               pDirectDraw->DdCanCreateD3DBuffer = puD3dBufferCallbacks->CanCreateD3DBuffer;
-               pDirectDraw->DdCreateD3DBuffer = puD3dBufferCallbacks->CreateD3DBuffer;
-               pDirectDraw->DdDestroyD3DBuffer = puD3dBufferCallbacks->DestroyD3DBuffer;
-               pDirectDraw->DdLockD3DBuffer = puD3dBufferCallbacks->LockD3DBuffer;
-               pDirectDraw->DdUnlockD3DBuffer = puD3dBufferCallbacks->UnlockD3DBuffer;
+               /* FIXME 
+                * bRealDestroy 
+                * are we doing right ??
+                */
+        DestroySurf.lpDD =  &pDirectDraw->Global;
+
+        DestroySurf.lpDDSurface = hSurface;  // ?
+        DestroySurf.DestroySurface = pDirectDraw->Surf.DestroySurface;         
+               
+        ddRVal = pDirectDraw->Surf.DestroySurface(&DestroySurf); 
        }
+
        
-       GDIOBJ_UnlockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;                     
+}
 
-       return TRUE;
+DWORD STDCALL NtGdiDdFlip(
+    HANDLE hSurfaceCurrent,
+    HANDLE hSurfaceTarget,
+    HANDLE hSurfaceCurrentLeft,
+    HANDLE hSurfaceTargetLeft,
+    PDD_FLIPDATA puFlipData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurfaceTarget, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdFlip\n");
+       
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puFlipData->lpDD;
+
+       /* use our cache version instead */
+       puFlipData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_FLIP))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.Flip(puFlipData);
+
+       /* But back the orignal PDev */
+       puFlipData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;             
 }
 
+DWORD STDCALL NtGdiDdLock(
+    HANDLE hSurface,
+    PDD_LOCKDATA puLockData,
+    HDC hdcClip
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdLock\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puLockData->lpDD;
+
+       /* use our cache version instead */
+       puLockData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_LOCK))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.Lock(puLockData);
+
+       /* But back the orignal PDev */
+       puLockData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;             
+}
+
+DWORD STDCALL NtGdiDdUnlock(
+    HANDLE hSurface,
+    PDD_UNLOCKDATA puUnlockData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdUnlock\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puUnlockData->lpDD;
+
+       /* use our cache version instead */
+       puUnlockData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_UNLOCK))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.Unlock(puUnlockData);
+
+       /* But back the orignal PDev */
+       puUnlockData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);    
+       return ddRVal;
+}
+
+DWORD STDCALL NtGdiDdBlt(
+    HANDLE hSurfaceDest,
+    HANDLE hSurfaceSrc,
+    PDD_BLTDATA puBltData
+)
+{
+    DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+    PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurfaceDest, GDI_OBJECT_TYPE_DIRECTDRAW);
+    DPRINT1("NtGdiDdBlt\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puBltData->lpDD;
+
+       /* use our cache version instead */
+       puBltData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_BLT))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.Blt(puBltData);
+
+       /* But back the orignal PDev */
+       puBltData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;
+   }
+
+DWORD STDCALL NtGdiDdSetColorKey(
+    HANDLE hSurface,
+    PDD_SETCOLORKEYDATA puSetColorKeyData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdSetColorKey\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puSetColorKeyData->lpDD;
+
+       /* use our cache version instead */
+       puSetColorKeyData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_SETCOLORKEY))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.SetColorKey(puSetColorKeyData);
+
+       /* But back the orignal PDev */
+       puSetColorKeyData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;     
+}
+
+
+DWORD STDCALL NtGdiDdAddAttachedSurface(
+    HANDLE hSurface,
+    HANDLE hSurfaceAttached,
+    PDD_ADDATTACHEDSURFACEDATA puAddAttachedSurfaceData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurfaceAttached, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdAddAttachedSurface\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puAddAttachedSurfaceData->lpDD;
+
+       /* use our cache version instead */
+       puAddAttachedSurfaceData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_ADDATTACHEDSURFACE))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.AddAttachedSurface(puAddAttachedSurfaceData);
+
+       /* But back the orignal PDev */
+       puAddAttachedSurfaceData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;     
+}
+
+DWORD STDCALL NtGdiDdGetBltStatus(
+    HANDLE hSurface,
+    PDD_GETBLTSTATUSDATA puGetBltStatusData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdGetBltStatus\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puGetBltStatusData->lpDD;
+
+       /* use our cache version instead */
+       puGetBltStatusData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_GETBLTSTATUS))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.GetBltStatus(puGetBltStatusData);
+
+       /* But back the orignal PDev */
+       puGetBltStatusData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;             
+}
+
+DWORD STDCALL NtGdiDdGetFlipStatus(
+    HANDLE hSurface,
+    PDD_GETFLIPSTATUSDATA puGetFlipStatusData
+)
+{
+    DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdGetFlipStatus\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puGetFlipStatusData->lpDD;
+
+       /* use our cache version instead */
+       puGetFlipStatusData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_GETFLIPSTATUS))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.GetFlipStatus(puGetFlipStatusData);
+
+       /* But back the orignal PDev */
+       puGetFlipStatusData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;             
+}
+
+DWORD STDCALL NtGdiDdUpdateOverlay(
+    HANDLE hSurfaceDestination,
+    HANDLE hSurfaceSource,
+    PDD_UPDATEOVERLAYDATA puUpdateOverlayData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+    PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurfaceDestination, GDI_OBJECT_TYPE_DIRECTDRAW);
+    DPRINT1("NtGdiDdUpdateOverlay\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puUpdateOverlayData->lpDD;
+
+       /* use our cache version instead */
+       puUpdateOverlayData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_UPDATEOVERLAY))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.UpdateOverlay(puUpdateOverlayData);
+
+       /* But back the orignal PDev */
+       puUpdateOverlayData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;
+}
+
+DWORD STDCALL NtGdiDdSetOverlayPosition(
+    HANDLE hSurfaceSource,
+    HANDLE hSurfaceDestination,
+    PDD_SETOVERLAYPOSITIONDATA puSetOverlayPositionData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+    PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hSurfaceDestination, GDI_OBJECT_TYPE_DIRECTDRAW);
+    DPRINT1("NtGdiDdSetOverlayPosition\n");
+       if (pDirectDraw == NULL) 
+               return DDHAL_DRIVER_NOTHANDLED;
+
+       /* backup the orignal PDev and info */
+       lgpl = puSetOverlayPositionData->lpDD;
+
+       /* use our cache version instead */
+       puSetOverlayPositionData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+       if (!(pDirectDraw->Surf.dwFlags & DDHAL_SURFCB32_SETOVERLAYPOSITION))
+               ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       else
+        ddRVal = pDirectDraw->Surf.SetOverlayPosition(puSetOverlayPositionData);
+
+       /* But back the orignal PDev */
+       puSetOverlayPositionData->lpDD = lgpl;
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+    return ddRVal;
+}
+
+
 /************************************************************************/
 /* SURFACE OBJECT                                                       */
 /************************************************************************/
 
-typedef struct
-{
-       DD_SURFACE_LOCAL Local;
-       DD_SURFACE_MORE More;
-       DD_SURFACE_GLOBAL Global;
-       DD_ATTACHLIST AttachList;
-       DD_ATTACHLIST AttachListFrom;
-       BOOL bComplete;
-} DD_SURFACE, *PDD_SURFACE;
-
-static BOOL FASTCALL DDSurfaceCleanup(PDD_SURFACE pSurface)
+BOOL INTERNAL_CALL
+DDSURF_Cleanup(PVOID pDDSurf)
 {
-       //FIXME: implement
+       /* FIXME: implement 
+        * PDD_SURFACE pDDSurf = PVOID pDDSurf
+        */
+    DPRINT1("DDSURF_Cleanup\n");
        return TRUE;
 }
 
-HANDLE STDCALL NtGdiDdCreateSurfaceObject(      
+HANDLE STDCALL NtGdiDdCreateSurfaceObject(
     HANDLE hDirectDrawLocal,
     HANDLE hSurface,
     PDD_SURFACE_LOCAL puSurfaceLocal,
@@ -269,13 +745,15 @@ HANDLE STDCALL NtGdiDdCreateSurfaceObject(
 )
 {
        PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdCreateSurfaceObject\n");
        if (!pDirectDraw)
                return NULL;
 
        if (!hSurface)
-               hSurface = GDIOBJ_AllocObj(sizeof(DD_SURFACE), GDI_OBJECT_TYPE_DD_SURFACE, (GDICLEANUPPROC)DDSurfaceCleanup);
+               hSurface = GDIOBJ_AllocObj(GDI_OBJECT_TYPE_DD_SURFACE);
 
        PDD_SURFACE pSurface = GDIOBJ_LockObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE);
+        /* FIXME - Handle pSurface == NULL!!!! */
 
        RtlMoveMemory(&pSurface->Local, puSurfaceLocal, sizeof(DD_SURFACE_LOCAL));
        RtlMoveMemory(&pSurface->More, puSurfaceMore, sizeof(DD_SURFACE_MORE));
@@ -288,21 +766,29 @@ HANDLE STDCALL NtGdiDdCreateSurfaceObject(
        // FIXME: figure out how to use this
        pSurface->bComplete = bComplete;
 
-       GDIOBJ_UnlockObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE);
-       GDIOBJ_UnlockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       GDIOBJ_UnlockObjByPtr(pSurface);
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);
 
        return hSurface;
 }
 
-BOOL STDCALL NtGdiDdDeleteSurfaceObject(      
+BOOL STDCALL NtGdiDdDeleteSurfaceObject(
     HANDLE hSurface
 )
 {
-       return GDIOBJ_FreeObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE, 0);
+    DPRINT1("NtGdiDdDeleteSurfaceObject\n");
+       return GDIOBJ_FreeObj(hSurface, GDI_OBJECT_TYPE_DD_SURFACE);
 }
 
+
+
+/************************************************************************/
+/* DIRECT DRAW SURFACR END                                                   */
+/************************************************************************/
+
+
 /*
-BOOL STDCALL NtGdiDdAttachSurface(      
+BOOL STDCALL NtGdiDdAttachSurface(
     HANDLE hSurfaceFrom,
     HANDLE hSurfaceTo
 )
@@ -313,7 +799,7 @@ BOOL STDCALL NtGdiDdAttachSurface(
        PDD_SURFACE pSurfaceTo = GDIOBJ_LockObj(hSurfaceTo, GDI_OBJECT_TYPE_DD_SURFACE);
        if (!pSurfaceTo)
        {
-               GDIOBJ_UnlockObj(hSurfaceTo, GDI_OBJECT_TYPE_DD_SURFACE);
+               GDIOBJ_UnlockObjByPtr(pSurfaceFrom);
                return FALSE;
        }
 
@@ -322,10 +808,73 @@ BOOL STDCALL NtGdiDdAttachSurface(
                pSurfaceFrom->Local.lpAttachListFrom = pSurfaceFrom->AttachListFrom;
        }
 
-       GDIOBJ_UnlockObj(hSurfaceFrom, GDI_OBJECT_TYPE_DD_SURFACE);
-       GDIOBJ_UnlockObj(hSurfaceTo, GDI_OBJECT_TYPE_DD_SURFACE);
+       GDIOBJ_UnlockObjByPtr(pSurfaceFrom);
+       GDIOBJ_UnlockObjByPtr(pSurfaceTo);
        return TRUE;
 }
 */
 
+DWORD STDCALL NtGdiDdGetAvailDriverMemory(
+    HANDLE hDirectDrawLocal,
+    PDD_GETAVAILDRIVERMEMORYDATA puGetAvailDriverMemoryData
+)
+{
+       DWORD  ddRVal = DDHAL_DRIVER_NOTHANDLED;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdGetAvailDriverMemory\n");
+
+       /* backup the orignal PDev and info */
+       lgpl = puGetAvailDriverMemoryData->lpDD;
+
+       /* use our cache version instead */
+       puGetAvailDriverMemoryData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+   // ddRVal = pDirectDraw->DdGetAvailDriverMemory(puGetAvailDriverMemoryData); 
+       GDIOBJ_UnlockObjByPtr(pDirectDraw);
+
+
+       /* But back the orignal PDev */
+       puGetAvailDriverMemoryData->lpDD = lgpl;
+
+       return ddRVal;
+}
+
+
+
+
+DWORD STDCALL NtGdiDdSetExclusiveMode(
+    HANDLE hDirectDraw,
+    PDD_SETEXCLUSIVEMODEDATA puSetExclusiveModeData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW_GLOBAL lgpl;
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDraw, GDI_OBJECT_TYPE_DIRECTDRAW);
+       DPRINT1("NtGdiDdSetExclusiveMode\n");
+
+       /* backup the orignal PDev and info */
+       lgpl = puSetExclusiveModeData->lpDD;
+
+       /* use our cache version instead */
+       puSetExclusiveModeData->lpDD = &pDirectDraw->Global;
+
+       /* make the call */
+    ddRVal = pDirectDraw->DdSetExclusiveMode(puSetExclusiveModeData);
+
+    GDIOBJ_UnlockObjByPtr(pDirectDraw);
+
+       /* But back the orignal PDev */
+       puSetExclusiveModeData->lpDD = lgpl;
+    
+       return ddRVal;  
+}
+
+
+
+
 /* EOF */