From d4291a5710df64295e9b2924e4d64eac2b8e46d8 Mon Sep 17 00:00:00 2001
From: Luke Benstead <kazade@gmail.com>
Date: Sun, 24 May 2009 09:33:33 +0100
Subject: Split off IDirectDrawSurface4 thunks (broken!)

---
 dlls/ddraw/ddraw.c          |    1 +
 dlls/ddraw/ddraw_private.h  |    7 +
 dlls/ddraw/ddraw_thunks.c   |    9 +-
 dlls/ddraw/surface.c        |   10 +-
 dlls/ddraw/surface_thunks.c |  436 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 459 insertions(+), 4 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index ac4bd4c..f2953bd 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1975,6 +1975,7 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
         return DDERR_OUTOFVIDEOMEMORY;
     }
     (*ppSurf)->lpVtbl = &IDirectDrawSurface7_Vtbl;
+    (*ppSurf)->IDirectDrawSurface4_vtbl = &IDirectDrawSurface4_Vtbl;
     (*ppSurf)->IDirectDrawSurface3_vtbl = &IDirectDrawSurface3_Vtbl;
     (*ppSurf)->IDirectDrawSurface2_vtbl = &IDirectDrawSurface2_Vtbl;
     (*ppSurf)->IDirectDrawSurface_vtbl = &IDirectDrawSurface_Vtbl;
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 9ad5b26..b7f3218 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -258,6 +258,7 @@ struct IDirectDrawSurfaceImpl
 {
     /* IUnknown fields */
     const IDirectDrawSurface7Vtbl *lpVtbl;
+    const IDirectDrawSurface4Vtbl *IDirectDrawSurface4_vtbl;
     const IDirectDrawSurface3Vtbl *IDirectDrawSurface3_vtbl;
     const IDirectDrawSurface2Vtbl *IDirectDrawSurface2_vtbl;
     const IDirectDrawSurfaceVtbl *IDirectDrawSurface_vtbl;
@@ -314,6 +315,7 @@ struct IDirectDrawSurfaceImpl
 
 /* VTable declaration. It's located in surface.c / surface_thunks.c */
 extern const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl;
+extern const IDirectDrawSurface4Vtbl IDirectDrawSurface4_Vtbl;
 extern const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl;
 extern const IDirectDrawSurface2Vtbl IDirectDrawSurface2_Vtbl;
 extern const IDirectDrawSurfaceVtbl IDirectDrawSurface_Vtbl;
@@ -349,6 +351,11 @@ static inline IDirectDrawSurfaceImpl *surface_from_surface3(IDirectDrawSurface3
     return (IDirectDrawSurfaceImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawSurfaceImpl, IDirectDrawSurface3_vtbl));
 }
 
+static inline IDirectDrawSurfaceImpl *surface_from_surface4(IDirectDrawSurface4 *iface)
+{
+    return (IDirectDrawSurfaceImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawSurfaceImpl, IDirectDrawSurface4_vtbl));
+}
+
 /* Get the number of bytes per pixel for a given surface */
 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.dwRGBBitCount+7)/8))
 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
diff --git a/dlls/ddraw/ddraw_thunks.c b/dlls/ddraw/ddraw_thunks.c
index 15b2754..585126f 100644
--- a/dlls/ddraw/ddraw_thunks.c
+++ b/dlls/ddraw/ddraw_thunks.c
@@ -423,11 +423,16 @@ IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
 			       IUnknown *pUnkOuter)
 {
     HRESULT hr;
+    LPDIRECTDRAWSURFACE7 pSurface7;
     IDirectDrawSurfaceImpl *impl;
 
     hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
-            pSDesc, (LPDIRECTDRAWSURFACE7 *)ppSurface, pUnkOuter);
-    impl = (IDirectDrawSurfaceImpl *)*ppSurface;
+            pSDesc, &pSurface7, pUnkOuter);
+            
+    *ppSurface = pSurface7 ? (IDirectDrawSurface4*)&((IDirectDrawSurfaceImpl*)pSurface7)->IDirectDrawSurface4_vtbl : NULL;
+    
+    impl = (IDirectDrawSurfaceImpl *)pSurface7;
+    
     if(SUCCEEDED(hr) && impl)
     {
         set_surf_version(impl, 4);
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index b7bd788..a2dfa26 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -85,14 +85,20 @@ IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7 *iface,
 
     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),obj);
     if (IsEqualGUID(riid, &IID_IUnknown)
-     || IsEqualGUID(riid, &IID_IDirectDrawSurface7)
-     || IsEqualGUID(riid, &IID_IDirectDrawSurface4) )
+     || IsEqualGUID(riid, &IID_IDirectDrawSurface7) )
     {
         IUnknown_AddRef(iface);
         *obj = iface;
         TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj);
         return S_OK;
     }
+    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface4) )
+    {
+        *obj = &This->IDirectDrawSurface4_vtbl;
+        IUnknown_AddRef((IUnknown*) *obj);
+        TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This, *obj);
+        return S_OK;
+    }
     else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3) )
     {
         IUnknown_AddRef(iface);
diff --git a/dlls/ddraw/surface_thunks.c b/dlls/ddraw/surface_thunks.c
index c64c88e..ac4bc7d 100644
--- a/dlls/ddraw/surface_thunks.c
+++ b/dlls/ddraw/surface_thunks.c
@@ -39,6 +39,12 @@ struct callback_info
     LPVOID context;
 };
 
+struct callback_info2 
+{
+    LPDDENUMSURFACESCALLBACK2 callback;
+    LPVOID context;
+};
+
 static void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
 {
     memset(out, 0, sizeof(*out));
@@ -142,6 +148,16 @@ EnumCallback3(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD,
             &ddsd, info->context);
 }
 
+static HRESULT CALLBACK
+EnumCallback4(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD,
+         LPVOID context)
+{
+    const struct callback_info2* info = context;
+    return info->callback(iface ?
+            (IDirectDrawSurface4 *)&((IDirectDrawSurfaceImpl *)iface)->IDirectDrawSurface4_vtbl : NULL,
+            pDDSD, info->context);
+}
+
 /* IDirectDrawSurface thunks below */
 
 static HRESULT WINAPI
@@ -1255,6 +1271,372 @@ IDirectDrawSurface3Impl_SetSurfaceDesc(LPDIRECTDRAWSURFACE3 This,
             (LPDDSURFACEDESC2)pDDSD, dwFlags);
 }
 
+/* IDirectDrawSurface4 thunks below */
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 This, REFIID iid,
+                       LPVOID *ppObj)
+{
+    return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)surface_from_surface4(This), iid, ppObj);
+}
+
+static ULONG WINAPI
+IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 This)
+{
+    return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)surface_from_surface4(This));
+}
+
+static ULONG WINAPI
+IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface)
+{
+    IDirectDrawSurfaceImpl *This = surface_from_surface4(iface);
+    TRACE("(%p)\n", This);
+    return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)surface_from_surface4(iface));
+}
+
+/*
+ * IDirectDrawSurface4 doesn't do the same as the former versions here so
+ * we use the DDS7 one
+ */
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_AddAttachedSurface(LPDIRECTDRAWSURFACE4 iface,
+                                           LPDIRECTDRAWSURFACE4 Attach)
+{
+    return IDirectDrawSurface7_AddAttachedSurface((IDirectDrawSurface7 *)surface_from_surface4(iface), 
+                                                  (IDirectDrawSurface7 *)surface_from_surface4(Attach));
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE4 This,
+                        LPRECT pRect)
+{
+    return IDirectDrawSurface7_AddOverlayDirtyRect((IDirectDrawSurface7 *)surface_from_surface4(This), pRect);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_Blt(LPDIRECTDRAWSURFACE4 This, LPRECT prcDst,
+                LPDIRECTDRAWSURFACE4 pSrcSurf, LPRECT prcSrc,
+                DWORD dwFlags, LPDDBLTFX pFX)
+{
+    return IDirectDrawSurface7_Blt((IDirectDrawSurface7 *)surface_from_surface4(This), prcDst,
+            pSrcSurf ? (IDirectDrawSurface7 *)surface_from_surface4(pSrcSurf) : NULL, prcSrc, dwFlags, pFX);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_BltBatch(LPDIRECTDRAWSURFACE4 This,
+                 LPDDBLTBATCH pBatch, DWORD dwCount,
+                 DWORD dwFlags)
+{
+    return IDirectDrawSurface7_BltBatch((IDirectDrawSurface7 *)surface_from_surface4(This), pBatch, dwCount, dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_BltFast(LPDIRECTDRAWSURFACE4 This, DWORD x, DWORD y,
+                LPDIRECTDRAWSURFACE4 pSrcSurf, LPRECT prcSrc,
+                DWORD dwTrans)
+{
+    return IDirectDrawSurface7_BltFast((IDirectDrawSurface7 *)surface_from_surface4(This), x, y,
+            pSrcSurf ? (IDirectDrawSurface7 *)surface_from_surface4(pSrcSurf) : NULL, prcSrc, dwTrans);
+}
+
+static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 This)
+{
+    return IDirectDrawSurface7_ChangeUniquenessValue((IDirectDrawSurface7 *)surface_from_surface4(This));
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_DeleteAttachedSurface(LPDIRECTDRAWSURFACE4 This,
+                          DWORD dwFlags,
+                          LPDIRECTDRAWSURFACE4 pAttached)
+{
+    return IDirectDrawSurface7_DeleteAttachedSurface((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags,
+            pAttached ? (IDirectDrawSurface7 *)surface_from_surface4(pAttached) : NULL);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 This,
+                         LPVOID context,
+                         LPDDENUMSURFACESCALLBACK2 callback)
+{
+    struct callback_info2 info;
+
+    info.callback = callback;
+    info.context  = context;
+
+    return IDirectDrawSurface7_EnumAttachedSurfaces((IDirectDrawSurface7 *)surface_from_surface4(This),
+            &info, EnumCallback4);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_EnumOverlayZOrders(LPDIRECTDRAWSURFACE4 This,
+                       DWORD dwFlags, LPVOID context,
+                       LPDDENUMSURFACESCALLBACK2 callback)
+{
+    struct callback_info2 info;
+
+    info.callback = callback;
+    info.context  = context;
+
+    return IDirectDrawSurface7_EnumOverlayZOrders((IDirectDrawSurface7 *)surface_from_surface4(This),
+            dwFlags, &info, EnumCallback4);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_Flip(LPDIRECTDRAWSURFACE4 This,
+                 LPDIRECTDRAWSURFACE4 pOverride, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_Flip((IDirectDrawSurface7 *)surface_from_surface4(This),
+            pOverride ? (IDirectDrawSurface7 *)surface_from_surface4(pOverride) : NULL, dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 This,
+                                       REFGUID tag)
+{
+    return IDirectDrawSurface7_FreePrivateData((IDirectDrawSurface7 *)surface_from_surface4(This), tag);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetAttachedSurface(LPDIRECTDRAWSURFACE4 This,
+                       LPDDSCAPS2 pCaps,
+                       LPDIRECTDRAWSURFACE4* ppAttached)
+{
+    DDSCAPS2 caps;
+    LPDIRECTDRAWSURFACE7 pAttached7;
+    HRESULT hr;
+
+    caps.dwCaps  = pCaps->dwCaps;
+    caps.dwCaps2 = 0;
+    caps.dwCaps3 = 0;
+    caps.dwCaps4 = 0;
+
+    hr = IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)surface_from_surface4(This), &caps, &pAttached7);
+    if (FAILED(hr)) *ppAttached = NULL;
+    else *ppAttached = pAttached7 ?
+            (IDirectDrawSurface4 *)&((IDirectDrawSurfaceImpl *)pAttached7)->IDirectDrawSurface4_vtbl : NULL;
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_GetBltStatus((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetCaps(LPDIRECTDRAWSURFACE4 This, LPDDSCAPS2 pCaps)
+{
+    DDSCAPS2 caps;
+    HRESULT hr;
+
+    hr = IDirectDrawSurface7_GetCaps((IDirectDrawSurface7 *)surface_from_surface4(This), &caps);
+    if (FAILED(hr)) return hr;
+
+    pCaps->dwCaps = caps.dwCaps;
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetClipper(LPDIRECTDRAWSURFACE4 This,
+                   LPDIRECTDRAWCLIPPER* ppClipper)
+{
+    return IDirectDrawSurface7_GetClipper((IDirectDrawSurface7 *)surface_from_surface4(This), ppClipper);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetColorKey(LPDIRECTDRAWSURFACE4 This, DWORD dwFlags,
+                    LPDDCOLORKEY pCKey)
+{
+    return IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags, pCKey);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 This, HDC* phDC)
+{
+    return IDirectDrawSurface7_GetDC((IDirectDrawSurface7 *)surface_from_surface4(This), phDC);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetFlipStatus(LPDIRECTDRAWSURFACE4 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_GetFlipStatus((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetOverlayPosition(LPDIRECTDRAWSURFACE4 This, LPLONG pX,
+                       LPLONG pY)
+{
+    return IDirectDrawSurface7_GetOverlayPosition((IDirectDrawSurface7 *)surface_from_surface4(This), pX, pY);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetPalette(LPDIRECTDRAWSURFACE4 This,
+                   LPDIRECTDRAWPALETTE* ppPalette)
+{
+    return IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)surface_from_surface4(This), ppPalette);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetPixelFormat(LPDIRECTDRAWSURFACE4 This,
+                       LPDDPIXELFORMAT pPixelFormat)
+{
+    return IDirectDrawSurface7_GetPixelFormat((IDirectDrawSurface7 *)surface_from_surface4(This), pPixelFormat);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 This,
+                                      REFGUID tag,
+                                      void *Data,
+                                      DWORD *Size)
+{
+    return IDirectDrawSurface7_GetPrivateData((IDirectDrawSurface7 *)surface_from_surface4(This),
+                             tag, Data, Size);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetSurfaceDesc(LPDIRECTDRAWSURFACE4 This,
+                       LPDDSURFACEDESC2 pDDSD)
+{
+    return IDirectDrawSurface7_GetSurfaceDesc((IDirectDrawSurface7 *)surface_from_surface4(This), pDDSD);
+}
+
+static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 This, LPDWORD pValue)
+{
+    return IDirectDrawSurface7_GetUniquenessValue((IDirectDrawSurface7 *)surface_from_surface4(This), pValue);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_Initialize(LPDIRECTDRAWSURFACE4 This, LPDIRECTDRAW pDD,
+                   LPDDSURFACEDESC2 pDDSD)
+{
+    return IDirectDrawSurface7_Initialize((IDirectDrawSurface7 *)surface_from_surface4(This),
+            pDD, pDDSD);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 This)
+{
+    return IDirectDrawSurface7_IsLost((IDirectDrawSurface7 *)surface_from_surface4(This));
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_Lock(LPDIRECTDRAWSURFACE4 This, LPRECT pRect,
+                 LPDDSURFACEDESC2 pDDSD, DWORD dwFlags, HANDLE h)
+{
+    return IDirectDrawSurface7_Lock((IDirectDrawSurface7 *)surface_from_surface4(This),
+            pRect, pDDSD, dwFlags, h);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 This, HDC hDC)
+{
+    return IDirectDrawSurface7_ReleaseDC((IDirectDrawSurface7 *)surface_from_surface4(This), hDC);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 This)
+{
+    return IDirectDrawSurface7_Restore((IDirectDrawSurface7 *)surface_from_surface4(This));
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_SetClipper(LPDIRECTDRAWSURFACE4 This,
+                   LPDIRECTDRAWCLIPPER pClipper)
+{
+    return IDirectDrawSurface7_SetClipper((IDirectDrawSurface7 *)surface_from_surface4(This), pClipper);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_SetColorKey(LPDIRECTDRAWSURFACE4 This, DWORD dwFlags,
+                    LPDDCOLORKEY pCKey)
+{
+    return IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags, pCKey);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_SetOverlayPosition(LPDIRECTDRAWSURFACE4 This, LONG x,
+                       LONG y)
+{
+    return IDirectDrawSurface7_SetOverlayPosition((IDirectDrawSurface7 *)surface_from_surface4(This), x, y);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_SetPalette(LPDIRECTDRAWSURFACE4 This,
+                   LPDIRECTDRAWPALETTE pPalette)
+{
+    return IDirectDrawSurface7_SetPalette((IDirectDrawSurface7 *)surface_from_surface4(This), pPalette);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 This,
+                                      REFGUID tag,
+                                      void *Data,
+                                      DWORD Size,
+                                      DWORD Flags)
+{
+    return IDirectDrawSurface7_SetPrivateData((IDirectDrawSurface7 *)surface_from_surface4(This),
+                                tag, Data, Size, Flags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_Unlock(LPDIRECTDRAWSURFACE4 This, RECT *data)
+{
+    /* data might not be the LPRECT of later versions, so drop it. */
+    return IDirectDrawSurface7_Unlock((IDirectDrawSurface7 *)surface_from_surface4(This), NULL);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_UpdateOverlay(LPDIRECTDRAWSURFACE4 This, LPRECT prcSrc,
+                      LPDIRECTDRAWSURFACE4 pDstSurf,
+                      LPRECT prcDst, DWORD dwFlags,
+                      LPDDOVERLAYFX pFX)
+{
+    return IDirectDrawSurface7_UpdateOverlay((IDirectDrawSurface7 *)surface_from_surface4(This), prcSrc,
+            pDstSurf ? (IDirectDrawSurface7 *)surface_from_surface4(pDstSurf) : NULL, prcDst, dwFlags, pFX);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE4 This,
+                         DWORD dwFlags)
+{
+    return IDirectDrawSurface7_UpdateOverlayDisplay((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE4 This,
+                        DWORD dwFlags,
+                        LPDIRECTDRAWSURFACE4 pSurfReference)
+{
+    return IDirectDrawSurface7_UpdateOverlayZOrder((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags,
+            pSurfReference ? (IDirectDrawSurface7 *)surface_from_surface4(pSurfReference) : NULL);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_GetDDInterface(LPDIRECTDRAWSURFACE4 This, LPVOID* ppDD)
+{
+    return IDirectDrawSurface7_GetDDInterface((IDirectDrawSurface7 *)surface_from_surface4(This), ppDD);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_PageLock(LPDIRECTDRAWSURFACE4 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_PageLock((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_PageUnlock(LPDIRECTDRAWSURFACE4 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_PageUnlock((IDirectDrawSurface7 *)surface_from_surface4(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface4Impl_SetSurfaceDesc(LPDIRECTDRAWSURFACE4 This,
+                       LPDDSURFACEDESC2 pDDSD, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_SetSurfaceDesc((IDirectDrawSurface7 *)surface_from_surface4(This),
+            pDDSD, dwFlags);
+}
+
 const IDirectDrawSurfaceVtbl IDirectDrawSurface_Vtbl = 
 {
     IDirectDrawSurface1Impl_QueryInterface,
@@ -1381,3 +1763,57 @@ const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
     IDirectDrawSurface3Impl_PageUnlock,
     IDirectDrawSurface3Impl_SetSurfaceDesc
 };
+
+const IDirectDrawSurface4Vtbl IDirectDrawSurface4_Vtbl =
+{
+    /*** IUnknown ***/
+    IDirectDrawSurface4Impl_QueryInterface,
+    IDirectDrawSurface4Impl_AddRef,
+    IDirectDrawSurface4Impl_Release,
+    /*** IDirectDrawSurface ***/
+    IDirectDrawSurface4Impl_AddAttachedSurface,
+    IDirectDrawSurface4Impl_AddOverlayDirtyRect,
+    IDirectDrawSurface4Impl_Blt,
+    IDirectDrawSurface4Impl_BltBatch,
+    IDirectDrawSurface4Impl_BltFast,
+    IDirectDrawSurface4Impl_DeleteAttachedSurface,
+    IDirectDrawSurface4Impl_EnumAttachedSurfaces,
+    IDirectDrawSurface4Impl_EnumOverlayZOrders,
+    IDirectDrawSurface4Impl_Flip,
+    IDirectDrawSurface4Impl_GetAttachedSurface,
+    IDirectDrawSurface4Impl_GetBltStatus,
+    IDirectDrawSurface4Impl_GetCaps,
+    IDirectDrawSurface4Impl_GetClipper,
+    IDirectDrawSurface4Impl_GetColorKey,
+    IDirectDrawSurface4Impl_GetDC,
+    IDirectDrawSurface4Impl_GetFlipStatus,
+    IDirectDrawSurface4Impl_GetOverlayPosition,
+    IDirectDrawSurface4Impl_GetPalette,
+    IDirectDrawSurface4Impl_GetPixelFormat,
+    IDirectDrawSurface4Impl_GetSurfaceDesc,
+    IDirectDrawSurface4Impl_Initialize,
+    IDirectDrawSurface4Impl_IsLost,
+    IDirectDrawSurface4Impl_Lock,
+    IDirectDrawSurface4Impl_ReleaseDC,
+    IDirectDrawSurface4Impl_Restore,
+    IDirectDrawSurface4Impl_SetClipper,
+    IDirectDrawSurface4Impl_SetColorKey,
+    IDirectDrawSurface4Impl_SetOverlayPosition,
+    IDirectDrawSurface4Impl_SetPalette,
+    IDirectDrawSurface4Impl_Unlock,
+    IDirectDrawSurface4Impl_UpdateOverlay,
+    IDirectDrawSurface4Impl_UpdateOverlayDisplay,
+    IDirectDrawSurface4Impl_UpdateOverlayZOrder,
+    /*** IDirectDrawSurface2 ***/
+    IDirectDrawSurface4Impl_GetDDInterface,
+    IDirectDrawSurface4Impl_PageLock,
+    IDirectDrawSurface4Impl_PageUnlock,
+    /*** IDirectDrawSurface3 ***/
+    IDirectDrawSurface4Impl_SetSurfaceDesc,
+    /*** IDirectDrawSurface4 ***/
+    IDirectDrawSurface4Impl_SetPrivateData,
+    IDirectDrawSurface4Impl_GetPrivateData,
+    IDirectDrawSurface4Impl_FreePrivateData,
+    IDirectDrawSurface4Impl_GetUniquenessValue,
+    IDirectDrawSurface4Impl_ChangeUniquenessValue
+};
-- 
1.6.0.4

