From 2bf901db95854a20ea6d2fdd1a8edc4bd08b1937 Mon Sep 17 00:00:00 2001
From: Luke Benstead <kazade@gmail.com>
Date: Sun, 24 May 2009 08:40:31 +0100
Subject: Split off IDirectDrawSurface2 thunks

---
 dlls/ddraw/ddraw.c          |    1 +
 dlls/ddraw/ddraw_private.h  |    7 +
 dlls/ddraw/ddraw_thunks.c   |   19 ++-
 dlls/ddraw/surface.c        |   10 +-
 dlls/ddraw/surface_thunks.c |  433 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 464 insertions(+), 6 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 03c9237..ac4bd4c 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1976,6 +1976,7 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
     }
     (*ppSurf)->lpVtbl = &IDirectDrawSurface7_Vtbl;
     (*ppSurf)->IDirectDrawSurface3_vtbl = &IDirectDrawSurface3_Vtbl;
+    (*ppSurf)->IDirectDrawSurface2_vtbl = &IDirectDrawSurface2_Vtbl;
     (*ppSurf)->IDirectDrawSurface_vtbl = &IDirectDrawSurface_Vtbl;
     (*ppSurf)->IDirectDrawGammaControl_vtbl = &IDirectDrawGammaControl_Vtbl;
     (*ppSurf)->IDirect3DTexture2_vtbl = &IDirect3DTexture2_Vtbl;
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index d802ccb..9ad5b26 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -259,6 +259,7 @@ struct IDirectDrawSurfaceImpl
     /* IUnknown fields */
     const IDirectDrawSurface7Vtbl *lpVtbl;
     const IDirectDrawSurface3Vtbl *IDirectDrawSurface3_vtbl;
+    const IDirectDrawSurface2Vtbl *IDirectDrawSurface2_vtbl;
     const IDirectDrawSurfaceVtbl *IDirectDrawSurface_vtbl;
     const IDirectDrawGammaControlVtbl *IDirectDrawGammaControl_vtbl;
     const IDirect3DTexture2Vtbl *IDirect3DTexture2_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 IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl;
+extern const IDirectDrawSurface2Vtbl IDirectDrawSurface2_Vtbl;
 extern const IDirectDrawSurfaceVtbl IDirectDrawSurface_Vtbl;
 extern const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl;
 extern const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl;
@@ -337,6 +339,11 @@ static inline IDirectDrawSurfaceImpl *surface_from_surface1(IDirectDrawSurface *
     return (IDirectDrawSurfaceImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawSurfaceImpl, IDirectDrawSurface_vtbl));
 }
 
+static inline IDirectDrawSurfaceImpl *surface_from_surface2(IDirectDrawSurface2 *iface)
+{
+    return (IDirectDrawSurfaceImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawSurfaceImpl, IDirectDrawSurface2_vtbl));
+}
+
 static inline IDirectDrawSurfaceImpl *surface_from_surface3(IDirectDrawSurface3 *iface)
 {
     return (IDirectDrawSurfaceImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawSurfaceImpl, IDirectDrawSurface3_vtbl));
diff --git a/dlls/ddraw/ddraw_thunks.c b/dlls/ddraw/ddraw_thunks.c
index 914fac1..15b2754 100644
--- a/dlls/ddraw/ddraw_thunks.c
+++ b/dlls/ddraw/ddraw_thunks.c
@@ -374,10 +374,8 @@ IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
     hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw2(This),
             (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
 
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
     *ppSurface = pSurface7 ?
-            (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurface7)->IDirectDrawSurface3_vtbl : NULL;
+            (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurface7)->IDirectDrawSurface2_vtbl : NULL;
 
     impl = (IDirectDrawSurfaceImpl *)pSurface7;
     if(SUCCEEDED(hr) && impl)
@@ -588,6 +586,19 @@ EnumSurfacesCallbackThunk(LPDIRECTDRAWSURFACE7 pSurf, LPDDSURFACEDESC2 pDDSD,
 }
 
 static HRESULT CALLBACK
+EnumSurfacesCallbackThunk2(LPDIRECTDRAWSURFACE7 pSurf, LPDDSURFACEDESC2 pDDSD,
+			  LPVOID context)
+{
+    struct surfacescallback_context *cbcontext = context;
+
+    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
+     * IDirectDrawSurface vtable layout at the beginning  */
+    return cbcontext->func(
+            pSurf ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf)->IDirectDrawSurface2_vtbl : NULL,
+            (LPDDSURFACEDESC)pDDSD, cbcontext->context);
+}
+
+static HRESULT CALLBACK
 EnumSurfacesCallbackThunk3(LPDIRECTDRAWSURFACE7 pSurf, LPDDSURFACEDESC2 pDDSD,
 			  LPVOID context)
 {
@@ -625,7 +636,7 @@ IDirectDraw2Impl_EnumSurfaces(LPDIRECTDRAW2 This, DWORD dwFlags,
     cbcontext.context = context;
 
     return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw2(This),
-            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk3);
+            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk2);
 }
 
 static HRESULT WINAPI
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 2d5901a..b7bd788 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -93,14 +93,20 @@ IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7 *iface,
         TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj);
         return S_OK;
     }
-    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3)
-          || IsEqualGUID(riid, &IID_IDirectDrawSurface2) )
+    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3) )
     {
         IUnknown_AddRef(iface);
         *obj = &This->IDirectDrawSurface3_vtbl;
         TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj);
         return S_OK;
     }
+    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface2) )
+    {
+        IUnknown_AddRef(iface);
+        *obj = &This->IDirectDrawSurface2_vtbl;
+        TRACE("(%p) returning IDirectDrawSurface2 interface at %p\n", This, *obj);
+        return S_OK;
+    }
     else if( IsEqualGUID(riid, &IID_IDirectDrawSurface) )
     {
         *obj = &This->IDirectDrawSurface_vtbl;
diff --git a/dlls/ddraw/surface_thunks.c b/dlls/ddraw/surface_thunks.c
index fb0114b..c64c88e 100644
--- a/dlls/ddraw/surface_thunks.c
+++ b/dlls/ddraw/surface_thunks.c
@@ -113,6 +113,21 @@ EnumCallback(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD,
 }
 
 static HRESULT CALLBACK
+EnumCallback2(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD,
+         LPVOID context)
+{
+    const struct callback_info* info = context;
+
+    /* This is an outgoing conversion so we have to do it. */
+    DDSURFACEDESC ddsd;
+    DDSD2_to_DDSD(pDDSD, &ddsd);
+
+    return info->callback(iface ?
+            (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)iface)->IDirectDrawSurface2_vtbl : NULL,
+            &ddsd, info->context);
+}
+
+static HRESULT CALLBACK
 EnumCallback3(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD,
          LPVOID context)
 {
@@ -484,6 +499,381 @@ IDirectDrawSurface1Impl_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE This,
             pSurfReference ? (IDirectDrawSurface7 *)surface_from_surface1(pSurfReference) : NULL);
 }
 
+/* IDirectDrawSurface2 thunks below */
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_QueryInterface(LPDIRECTDRAWSURFACE2 This, REFIID iid,
+                       LPVOID *ppObj)
+{
+    return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)surface_from_surface2(This), iid, ppObj);
+}
+
+static ULONG WINAPI
+IDirectDrawSurface2Impl_AddRef(LPDIRECTDRAWSURFACE2 This)
+{
+    return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)surface_from_surface2(This));
+}
+
+static ULONG WINAPI
+IDirectDrawSurface2Impl_Release(LPDIRECTDRAWSURFACE2 iface)
+{
+    IDirectDrawSurfaceImpl *This = surface_from_surface2(iface);
+    TRACE("(%p)\n", This);
+    return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)surface_from_surface2(iface));
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_AddAttachedSurface(LPDIRECTDRAWSURFACE2 iface,
+                       LPDIRECTDRAWSURFACE2 pAttach)
+{
+    IDirectDrawSurfaceImpl *This = surface_from_surface2(iface);
+    IDirectDrawSurfaceImpl *Surf = surface_from_surface2(pAttach);
+    TRACE("(%p)->(%p)\n", This, Surf);
+
+    /* Tests suggest that
+     * -> offscreen plain surfaces can be attached to other offscreen plain surfaces
+     * -> offscreen plain surfaces can be attached to primaries
+     * -> primaries can be attached to offscreen plain surfaces
+     * -> z buffers can be attached to primaries
+     *
+     */
+    if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN) &&
+       Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN))
+    {
+        /* Sizes have to match */
+        if(Surf->surface_desc.dwWidth != This->surface_desc.dwWidth ||
+        Surf->surface_desc.dwHeight != This->surface_desc.dwHeight)
+        {
+            WARN("Surface sizes do not match\n");
+            return DDERR_CANNOTATTACHSURFACE;
+        }
+        /* OK */
+    }
+    else if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE) &&
+            Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER))
+    {
+        /* OK */
+    }
+    else
+    {
+        WARN("Invalid attachment combination\n");
+        return DDERR_CANNOTATTACHSURFACE;
+    }
+
+    return IDirectDrawSurfaceImpl_AddAttachedSurface(This,
+                                                     Surf);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE2 This,
+                        LPRECT pRect)
+{
+    return IDirectDrawSurface7_AddOverlayDirtyRect((IDirectDrawSurface7 *)surface_from_surface2(This), pRect);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_Blt(LPDIRECTDRAWSURFACE2 This, LPRECT prcDst,
+                LPDIRECTDRAWSURFACE2 pSrcSurf, LPRECT prcSrc,
+                DWORD dwFlags, LPDDBLTFX pFX)
+{
+    return IDirectDrawSurface7_Blt((IDirectDrawSurface7 *)surface_from_surface2(This), prcDst,
+            pSrcSurf ? (IDirectDrawSurface7 *)surface_from_surface2(pSrcSurf) : NULL, prcSrc, dwFlags, pFX);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_BltBatch(LPDIRECTDRAWSURFACE2 This,
+                 LPDDBLTBATCH pBatch, DWORD dwCount,
+                 DWORD dwFlags)
+{
+    return IDirectDrawSurface7_BltBatch((IDirectDrawSurface7 *)surface_from_surface2(This), pBatch, dwCount, dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_BltFast(LPDIRECTDRAWSURFACE2 This, DWORD x, DWORD y,
+                LPDIRECTDRAWSURFACE2 pSrcSurf, LPRECT prcSrc,
+                DWORD dwTrans)
+{
+    return IDirectDrawSurface7_BltFast((IDirectDrawSurface7 *)surface_from_surface2(This), x, y,
+            pSrcSurf ? (IDirectDrawSurface7 *)surface_from_surface2(pSrcSurf) : NULL, prcSrc, dwTrans);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_DeleteAttachedSurface(LPDIRECTDRAWSURFACE2 This,
+                          DWORD dwFlags,
+                          LPDIRECTDRAWSURFACE2 pAttached)
+{
+    return IDirectDrawSurface7_DeleteAttachedSurface((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags,
+            pAttached ? (IDirectDrawSurface7 *)surface_from_surface2(pAttached) : NULL);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 This,
+                         LPVOID context,
+                         LPDDENUMSURFACESCALLBACK callback)
+{
+    struct callback_info info;
+
+    info.callback = callback;
+    info.context  = context;
+
+    return IDirectDrawSurface7_EnumAttachedSurfaces((IDirectDrawSurface7 *)surface_from_surface2(This),
+            &info, EnumCallback2);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_EnumOverlayZOrders(LPDIRECTDRAWSURFACE2 This,
+                       DWORD dwFlags, LPVOID context,
+                       LPDDENUMSURFACESCALLBACK callback)
+{
+    struct callback_info info;
+
+    info.callback = callback;
+    info.context  = context;
+
+    return IDirectDrawSurface7_EnumOverlayZOrders((IDirectDrawSurface7 *)surface_from_surface2(This),
+            dwFlags, &info, EnumCallback2);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_Flip(LPDIRECTDRAWSURFACE2 This,
+                 LPDIRECTDRAWSURFACE2 pOverride, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_Flip((IDirectDrawSurface7 *)surface_from_surface2(This),
+            pOverride ? (IDirectDrawSurface7 *)surface_from_surface2(pOverride) : NULL, dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetAttachedSurface(LPDIRECTDRAWSURFACE2 This,
+                       LPDDSCAPS pCaps,
+                       LPDIRECTDRAWSURFACE2* 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_surface2(This), &caps, &pAttached7);
+    if (FAILED(hr)) *ppAttached = NULL;
+    else *ppAttached = pAttached7 ?
+            (IDirectDrawSurface2 *)&((IDirectDrawSurfaceImpl *)pAttached7)->IDirectDrawSurface2_vtbl : NULL;
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetBltStatus(LPDIRECTDRAWSURFACE2 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_GetBltStatus((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetCaps(LPDIRECTDRAWSURFACE2 This, LPDDSCAPS pCaps)
+{
+    DDSCAPS2 caps;
+    HRESULT hr;
+
+    hr = IDirectDrawSurface7_GetCaps((IDirectDrawSurface7 *)surface_from_surface2(This), &caps);
+    if (FAILED(hr)) return hr;
+
+    pCaps->dwCaps = caps.dwCaps;
+    return hr;
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetClipper(LPDIRECTDRAWSURFACE2 This,
+                   LPDIRECTDRAWCLIPPER* ppClipper)
+{
+    return IDirectDrawSurface7_GetClipper((IDirectDrawSurface7 *)surface_from_surface2(This), ppClipper);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetColorKey(LPDIRECTDRAWSURFACE2 This, DWORD dwFlags,
+                    LPDDCOLORKEY pCKey)
+{
+    return IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags, pCKey);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetDC(LPDIRECTDRAWSURFACE2 This, HDC* phDC)
+{
+    return IDirectDrawSurface7_GetDC((IDirectDrawSurface7 *)surface_from_surface2(This), phDC);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetFlipStatus(LPDIRECTDRAWSURFACE2 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_GetFlipStatus((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetOverlayPosition(LPDIRECTDRAWSURFACE2 This, LPLONG pX,
+                       LPLONG pY)
+{
+    return IDirectDrawSurface7_GetOverlayPosition((IDirectDrawSurface7 *)surface_from_surface2(This), pX, pY);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetPalette(LPDIRECTDRAWSURFACE2 This,
+                   LPDIRECTDRAWPALETTE* ppPalette)
+{
+    return IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)surface_from_surface2(This), ppPalette);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetPixelFormat(LPDIRECTDRAWSURFACE2 This,
+                       LPDDPIXELFORMAT pPixelFormat)
+{
+    return IDirectDrawSurface7_GetPixelFormat((IDirectDrawSurface7 *)surface_from_surface2(This), pPixelFormat);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetSurfaceDesc(LPDIRECTDRAWSURFACE2 iface,
+                       LPDDSURFACEDESC pDDSD)
+{
+    IDirectDrawSurfaceImpl *This = surface_from_surface2(iface);
+    DDSURFACEDESC2 DDSD2;
+    HRESULT result;
+    
+    if(!pDDSD)
+        return DDERR_INVALIDPARAMS;
+
+    if (pDDSD->dwSize != sizeof(DDSURFACEDESC))
+    {
+        WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",pDDSD->dwSize);
+        return DDERR_INVALIDPARAMS;
+    }
+    
+    /* Convert the surface desc to version 2 */
+    DDSD_to_DDSD2(pDDSD, &DDSD2);
+    
+    /* Call the 7 version of GetSurfaceDesc */
+    result = IDirectDrawSurface7_GetSurfaceDesc((IDirectDrawSurface7 *)This, &DDSD2);
+    
+    if (SUCCEEDED(result))
+    {
+        /* Copy the result back */
+        DDSD2_to_DDSD(&DDSD2, pDDSD);
+    }
+    
+    return result;
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_Initialize(LPDIRECTDRAWSURFACE2 This, LPDIRECTDRAW pDD,
+                   LPDDSURFACEDESC pDDSD)
+{
+    return IDirectDrawSurface7_Initialize((IDirectDrawSurface7 *)surface_from_surface2(This),
+            pDD, (LPDDSURFACEDESC2)pDDSD);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_IsLost(LPDIRECTDRAWSURFACE2 This)
+{
+    return IDirectDrawSurface7_IsLost((IDirectDrawSurface7 *)surface_from_surface2(This));
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_Lock(LPDIRECTDRAWSURFACE2 This, LPRECT pRect,
+                 LPDDSURFACEDESC pDDSD, DWORD dwFlags, HANDLE h)
+{
+    return IDirectDrawSurface7_Lock((IDirectDrawSurface7 *)surface_from_surface2(This),
+            pRect, (LPDDSURFACEDESC2)pDDSD, dwFlags, h);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_ReleaseDC(LPDIRECTDRAWSURFACE2 This, HDC hDC)
+{
+    return IDirectDrawSurface7_ReleaseDC((IDirectDrawSurface7 *)surface_from_surface2(This), hDC);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_Restore(LPDIRECTDRAWSURFACE2 This)
+{
+    return IDirectDrawSurface7_Restore((IDirectDrawSurface7 *)surface_from_surface2(This));
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_SetClipper(LPDIRECTDRAWSURFACE2 This,
+                   LPDIRECTDRAWCLIPPER pClipper)
+{
+    return IDirectDrawSurface7_SetClipper((IDirectDrawSurface7 *)surface_from_surface2(This), pClipper);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_SetColorKey(LPDIRECTDRAWSURFACE2 This, DWORD dwFlags,
+                    LPDDCOLORKEY pCKey)
+{
+    return IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags, pCKey);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_SetOverlayPosition(LPDIRECTDRAWSURFACE2 This, LONG x,
+                       LONG y)
+{
+    return IDirectDrawSurface7_SetOverlayPosition((IDirectDrawSurface7 *)surface_from_surface2(This), x, y);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_SetPalette(LPDIRECTDRAWSURFACE2 This,
+                   LPDIRECTDRAWPALETTE pPalette)
+{
+    return IDirectDrawSurface7_SetPalette((IDirectDrawSurface7 *)surface_from_surface2(This), pPalette);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_Unlock(LPDIRECTDRAWSURFACE2 This, LPVOID data)
+{
+    /* data might not be the LPRECT of later versions, so drop it. */
+    return IDirectDrawSurface7_Unlock((IDirectDrawSurface7 *)surface_from_surface2(This), NULL);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_UpdateOverlay(LPDIRECTDRAWSURFACE2 This, LPRECT prcSrc,
+                      LPDIRECTDRAWSURFACE2 pDstSurf,
+                      LPRECT prcDst, DWORD dwFlags,
+                      LPDDOVERLAYFX pFX)
+{
+    return IDirectDrawSurface7_UpdateOverlay((IDirectDrawSurface7 *)surface_from_surface2(This), prcSrc,
+            pDstSurf ? (IDirectDrawSurface7 *)surface_from_surface2(pDstSurf) : NULL, prcDst, dwFlags, pFX);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE2 This,
+                         DWORD dwFlags)
+{
+    return IDirectDrawSurface7_UpdateOverlayDisplay((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE2 This,
+                        DWORD dwFlags,
+                        LPDIRECTDRAWSURFACE2 pSurfReference)
+{
+    return IDirectDrawSurface7_UpdateOverlayZOrder((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags,
+            pSurfReference ? (IDirectDrawSurface7 *)surface_from_surface2(pSurfReference) : NULL);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_GetDDInterface(LPDIRECTDRAWSURFACE2 This, LPVOID* ppDD)
+{
+    return IDirectDrawSurface7_GetDDInterface((IDirectDrawSurface7 *)surface_from_surface2(This), ppDD);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_PageLock(LPDIRECTDRAWSURFACE2 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_PageLock((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags);
+}
+
+static HRESULT WINAPI
+IDirectDrawSurface2Impl_PageUnlock(LPDIRECTDRAWSURFACE2 This, DWORD dwFlags)
+{
+    return IDirectDrawSurface7_PageUnlock((IDirectDrawSurface7 *)surface_from_surface2(This), dwFlags);
+}
+
 /* IDirectDrawSurface3 thunks below */
 
 static HRESULT WINAPI
@@ -905,6 +1295,49 @@ const IDirectDrawSurfaceVtbl IDirectDrawSurface_Vtbl =
     IDirectDrawSurface1Impl_UpdateOverlayZOrder
 };
 
+const IDirectDrawSurface2Vtbl IDirectDrawSurface2_Vtbl = 
+{
+    IDirectDrawSurface2Impl_QueryInterface,
+    IDirectDrawSurface2Impl_AddRef,
+    IDirectDrawSurface2Impl_Release,
+    IDirectDrawSurface2Impl_AddAttachedSurface,
+    IDirectDrawSurface2Impl_AddOverlayDirtyRect,
+    IDirectDrawSurface2Impl_Blt,
+    IDirectDrawSurface2Impl_BltBatch,
+    IDirectDrawSurface2Impl_BltFast,
+    IDirectDrawSurface2Impl_DeleteAttachedSurface,
+    IDirectDrawSurface2Impl_EnumAttachedSurfaces,
+    IDirectDrawSurface2Impl_EnumOverlayZOrders,
+    IDirectDrawSurface2Impl_Flip,
+    IDirectDrawSurface2Impl_GetAttachedSurface,
+    IDirectDrawSurface2Impl_GetBltStatus,
+    IDirectDrawSurface2Impl_GetCaps,
+    IDirectDrawSurface2Impl_GetClipper,
+    IDirectDrawSurface2Impl_GetColorKey,
+    IDirectDrawSurface2Impl_GetDC,
+    IDirectDrawSurface2Impl_GetFlipStatus,
+    IDirectDrawSurface2Impl_GetOverlayPosition,
+    IDirectDrawSurface2Impl_GetPalette,
+    IDirectDrawSurface2Impl_GetPixelFormat,
+    IDirectDrawSurface2Impl_GetSurfaceDesc,
+    IDirectDrawSurface2Impl_Initialize,
+    IDirectDrawSurface2Impl_IsLost,
+    IDirectDrawSurface2Impl_Lock,
+    IDirectDrawSurface2Impl_ReleaseDC,
+    IDirectDrawSurface2Impl_Restore,
+    IDirectDrawSurface2Impl_SetClipper,
+    IDirectDrawSurface2Impl_SetColorKey,
+    IDirectDrawSurface2Impl_SetOverlayPosition,
+    IDirectDrawSurface2Impl_SetPalette,
+    IDirectDrawSurface2Impl_Unlock,
+    IDirectDrawSurface2Impl_UpdateOverlay,
+    IDirectDrawSurface2Impl_UpdateOverlayDisplay,
+    IDirectDrawSurface2Impl_UpdateOverlayZOrder,
+    IDirectDrawSurface2Impl_GetDDInterface,
+    IDirectDrawSurface2Impl_PageLock,
+    IDirectDrawSurface2Impl_PageUnlock
+};
+
 const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
 {
     IDirectDrawSurface3Impl_QueryInterface,
-- 
1.6.0.4

