[PATCH 1/4] ddraw: Merge the ddraw thunks into ddraw.c.

Henri Verbeet hverbeet at codeweavers.com
Mon Jul 19 11:36:19 CDT 2010


Note how both ddraw 1 and ddraw 7 used the same IDirectDrawImpl_XXX naming
convention.
---
 dlls/ddraw/Makefile.in     |    1 -
 dlls/ddraw/ddraw.c         | 1540 ++++++++++++++++++++++++++++++++++++++------
 dlls/ddraw/ddraw_private.h |   25 +-
 dlls/ddraw/ddraw_thunks.c  | 1201 ----------------------------------
 dlls/ddraw/device.c        |    6 +-
 dlls/ddraw/direct3d.c      |    5 +-
 dlls/ddraw/surface.c       |    4 +-
 7 files changed, 1340 insertions(+), 1442 deletions(-)
 delete mode 100644 dlls/ddraw/ddraw_thunks.c

diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in
index 32f1237..4e883c7 100644
--- a/dlls/ddraw/Makefile.in
+++ b/dlls/ddraw/Makefile.in
@@ -9,7 +9,6 @@ IMPORTS   = dxguid uuid ole32 user32 gdi32 advapi32 kernel32 ntdll
 C_SRCS = \
 	clipper.c \
 	ddraw.c \
-	ddraw_thunks.c \
 	device.c \
 	direct3d.c \
 	executebuffer.c \
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 05c8c62..e61d5e6 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -64,6 +64,26 @@ const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops =
     ddraw_null_wined3d_object_destroyed,
 };
 
+static inline IDirectDrawImpl *ddraw_from_ddraw1(IDirectDraw *iface)
+{
+    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw_vtbl));
+}
+
+static inline IDirectDrawImpl *ddraw_from_ddraw2(IDirectDraw2 *iface)
+{
+    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw2_vtbl));
+}
+
+static inline IDirectDrawImpl *ddraw_from_ddraw3(IDirectDraw3 *iface)
+{
+    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw3_vtbl));
+}
+
+static inline IDirectDrawImpl *ddraw_from_ddraw4(IDirectDraw4 *iface)
+{
+    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw4_vtbl));
+}
+
 /*****************************************************************************
  * IUnknown Methods
  *****************************************************************************/
@@ -88,10 +108,7 @@ const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops =
  *  E_NOINTERFACE if the requested interface wasn't found
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface,
-                               REFIID refiid,
-                               void **obj)
+static HRESULT WINAPI ddraw7_QueryInterface(IDirectDraw7 *iface, REFIID refiid, void **obj)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
 
@@ -215,6 +232,34 @@ IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface,
     return S_OK;
 }
 
+static HRESULT WINAPI ddraw4_QueryInterface(IDirectDraw4 *iface, REFIID riid, void **object)
+{
+    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
+
+    return ddraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw4(iface), riid, object);
+}
+
+static HRESULT WINAPI ddraw3_QueryInterface(IDirectDraw3 *iface, REFIID riid, void **object)
+{
+    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
+
+    return ddraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw3(iface), riid, object);
+}
+
+static HRESULT WINAPI ddraw2_QueryInterface(IDirectDraw2 *iface, REFIID riid, void **object)
+{
+    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
+
+    return ddraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw2(iface), riid, object);
+}
+
+static HRESULT WINAPI ddraw1_QueryInterface(IDirectDraw *iface, REFIID riid, void **object)
+{
+    TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
+
+    return ddraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw1(iface), riid, object);
+}
+
 /*****************************************************************************
  * IDirectDraw7::AddRef
  *
@@ -233,8 +278,7 @@ IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface,
  * Returns: The new refcount
  *
  *****************************************************************************/
-static ULONG WINAPI
-IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
+static ULONG WINAPI ddraw7_AddRef(IDirectDraw7 *iface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     ULONG ref = InterlockedIncrement(&This->ref7);
@@ -246,8 +290,56 @@ IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
     return ref;
 }
 
+static ULONG WINAPI ddraw4_AddRef(IDirectDraw4 *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw4(iface);
+    ULONG ref = InterlockedIncrement(&ddraw->ref4);
+
+    TRACE("%p increasing refcount to %u.\n", ddraw, ref);
+
+    if (ref == 1) InterlockedIncrement(&ddraw->numIfaces);
+
+    return ref;
+}
+
+static ULONG WINAPI ddraw3_AddRef(IDirectDraw3 *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw3(iface);
+    ULONG ref = InterlockedIncrement(&ddraw->ref3);
+
+    TRACE("%p increasing refcount to %u.\n", ddraw, ref);
+
+    if (ref == 1) InterlockedIncrement(&ddraw->numIfaces);
+
+    return ref;
+}
+
+static ULONG WINAPI ddraw2_AddRef(IDirectDraw2 *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw2(iface);
+    ULONG ref = InterlockedIncrement(&ddraw->ref2);
+
+    TRACE("%p increasing refcount to %u.\n", ddraw, ref);
+
+    if (ref == 1) InterlockedIncrement(&ddraw->numIfaces);
+
+    return ref;
+}
+
+static ULONG WINAPI ddraw1_AddRef(IDirectDraw *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw1(iface);
+    ULONG ref = InterlockedIncrement(&ddraw->ref1);
+
+    TRACE("%p increasing refcount to %u.\n", ddraw, ref);
+
+    if (ref == 1) InterlockedIncrement(&ddraw->numIfaces);
+
+    return ref;
+}
+
 /*****************************************************************************
- * IDirectDrawImpl_Destroy
+ * ddraw_destroy
  *
  * Destroys a ddraw object if all refcounts are 0. This is to share code
  * between the IDirectDrawX::Release functions
@@ -256,8 +348,7 @@ IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
  *  This: DirectDraw object to destroy
  *
  *****************************************************************************/
-void
-IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
+static void ddraw_destroy(IDirectDrawImpl *This)
 {
     IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)This, NULL, DDSCL_NORMAL);
     IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)This);
@@ -289,19 +380,67 @@ IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
  *
  * Returns: The new refcount
  *****************************************************************************/
-static ULONG WINAPI
-IDirectDrawImpl_Release(IDirectDraw7 *iface)
+static ULONG WINAPI ddraw7_Release(IDirectDraw7 *iface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     ULONG ref = InterlockedDecrement(&This->ref7);
 
     TRACE("(%p)->() decrementing IDirectDraw7 refcount from %u.\n", This, ref +1);
 
-    if(ref == 0)
-    {
-        ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
-        if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
-    }
+    if (!ref && !InterlockedDecrement(&This->numIfaces))
+        ddraw_destroy(This);
+
+    return ref;
+}
+
+static ULONG WINAPI ddraw4_Release(IDirectDraw4 *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw4(iface);
+    ULONG ref = InterlockedDecrement(&ddraw->ref4);
+
+    TRACE("%p decreasing refcount to %u.\n", ddraw, ref);
+
+    if (!ref && !InterlockedDecrement(&ddraw->numIfaces))
+        ddraw_destroy(ddraw);
+
+    return ref;
+}
+
+static ULONG WINAPI ddraw3_Release(IDirectDraw3 *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw3(iface);
+    ULONG ref = InterlockedDecrement(&ddraw->ref3);
+
+    TRACE("%p decreasing refcount to %u.\n", ddraw, ref);
+
+    if (!ref && !InterlockedDecrement(&ddraw->numIfaces))
+        ddraw_destroy(ddraw);
+
+    return ref;
+}
+
+static ULONG WINAPI ddraw2_Release(IDirectDraw2 *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw2(iface);
+    ULONG ref = InterlockedDecrement(&ddraw->ref2);
+
+    TRACE("%p decreasing refcount to %u.\n", ddraw, ref);
+
+    if (!ref && !InterlockedDecrement(&ddraw->numIfaces))
+        ddraw_destroy(ddraw);
+
+    return ref;
+}
+
+static ULONG WINAPI ddraw1_Release(IDirectDraw *iface)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw1(iface);
+    ULONG ref = InterlockedDecrement(&ddraw->ref1);
+
+    TRACE("%p decreasing refcount to %u.\n", ddraw, ref);
+
+    if (!ref && !InterlockedDecrement(&ddraw->numIfaces))
+        ddraw_destroy(ddraw);
 
     return ref;
 }
@@ -354,10 +493,7 @@ IDirectDrawImpl_Release(IDirectDraw7 *iface)
  *   (Probably others too, have to investigate)
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface,
-                                    HWND hwnd,
-                                    DWORD cooplevel)
+static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd, DWORD cooplevel)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     HWND window;
@@ -535,25 +671,48 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_SetCooperativeLevel(IDirectDraw4 *iface, HWND window, DWORD flags)
+{
+    TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
+
+    return ddraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw4(iface), window, flags);
+}
+
+static HRESULT WINAPI ddraw3_SetCooperativeLevel(IDirectDraw3 *iface, HWND window, DWORD flags)
+{
+    TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
+
+    return ddraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw3(iface), window, flags);
+}
+
+static HRESULT WINAPI ddraw2_SetCooperativeLevel(IDirectDraw2 *iface, HWND window, DWORD flags)
+{
+    TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
+
+    return ddraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw2(iface), window, flags);
+}
+
+static HRESULT WINAPI ddraw1_SetCooperativeLevel(IDirectDraw *iface, HWND window, DWORD flags)
+{
+    TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
+
+    return ddraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw1(iface), window, flags);
+}
+
 /*****************************************************************************
  *
  * Helper function for SetDisplayMode and RestoreDisplayMode
  *
  * Implements DirectDraw's SetDisplayMode, but ignores the value of
  * ForceRefreshRate, since it is already handled by
- * IDirectDrawImpl_SetDisplayMode.  RestoreDisplayMode can use this function
+ * ddraw7_SetDisplayMode.  RestoreDisplayMode can use this function
  * without worrying that ForceRefreshRate will override the refresh rate.  For
  * argument and return value documentation, see
- * IDirectDrawImpl_SetDisplayMode.
+ * ddraw7_SetDisplayMode.
  *
  *****************************************************************************/
-static HRESULT
-IDirectDrawImpl_SetDisplayModeNoOverride(IDirectDraw7 *iface,
-                                         DWORD Width,
-                                         DWORD Height,
-                                         DWORD BPP,
-                                         DWORD RefreshRate,
-                                         DWORD Flags)
+static HRESULT ddraw_set_display_mode(IDirectDraw7 *iface, DWORD Width, DWORD Height,
+        DWORD BPP, DWORD RefreshRate, DWORD Flags)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     WINED3DDISPLAYMODE Mode;
@@ -629,13 +788,8 @@ IDirectDrawImpl_SetDisplayModeNoOverride(IDirectDraw7 *iface,
  *  DD_OK on success
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_SetDisplayMode(IDirectDraw7 *iface,
-                               DWORD Width,
-                               DWORD Height,
-                               DWORD BPP,
-                               DWORD RefreshRate,
-                               DWORD Flags)
+static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD Width, DWORD Height,
+        DWORD BPP, DWORD RefreshRate, DWORD Flags)
 {
     if (force_refresh_rate != 0)
     {
@@ -643,8 +797,44 @@ IDirectDrawImpl_SetDisplayMode(IDirectDraw7 *iface,
         RefreshRate = force_refresh_rate;
     }
 
-    return IDirectDrawImpl_SetDisplayModeNoOverride(iface, Width, Height, BPP,
-                                                    RefreshRate, Flags);
+    return ddraw_set_display_mode(iface, Width, Height, BPP, RefreshRate, Flags);
+}
+
+static HRESULT WINAPI ddraw4_SetDisplayMode(IDirectDraw4 *iface,
+        DWORD width, DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
+{
+    TRACE("iface %p, width %u, height %u, bpp %u, refresh_rate %u, flags %#x.\n",
+            iface, width, height, bpp, refresh_rate, flags);
+
+    return ddraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(iface),
+            width, height, bpp, refresh_rate, flags);
+}
+
+static HRESULT WINAPI ddraw3_SetDisplayMode(IDirectDraw3 *iface,
+        DWORD width, DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
+{
+    TRACE("iface %p, width %u, height %u, bpp %u, refresh_rate %u, flags %#x.\n",
+            iface, width, height, bpp, refresh_rate, flags);
+
+    return ddraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(iface),
+            width, height, bpp, refresh_rate, flags);
+}
+
+static HRESULT WINAPI ddraw2_SetDisplayMode(IDirectDraw2 *iface,
+        DWORD width, DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
+{
+    TRACE("iface %p, width %u, height %u, bpp %u, refresh_rate %u, flags %#x.\n",
+            iface, width, height, bpp, refresh_rate, flags);
+
+    return ddraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(iface),
+            width, height, bpp, refresh_rate, flags);
+}
+
+static HRESULT WINAPI ddraw1_SetDisplayMode(IDirectDraw *iface, DWORD width, DWORD height, DWORD bpp)
+{
+    TRACE("iface %p, width %u, height %u, bpp %u.\n", iface, width, height, bpp);
+
+    return ddraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(iface), width, height, bpp, 0, 0);
 }
 
 /*****************************************************************************
@@ -668,14 +858,40 @@ IDirectDrawImpl_SetDisplayMode(IDirectDraw7 *iface,
  *  DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_RestoreDisplayMode(IDirectDraw7 *iface)
+static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)\n", This);
 
-    return IDirectDrawImpl_SetDisplayModeNoOverride(iface,
-            This->orig_width, This->orig_height, This->orig_bpp, 0, 0);
+    return ddraw_set_display_mode(iface, This->orig_width, This->orig_height, This->orig_bpp, 0, 0);
+}
+
+static HRESULT WINAPI ddraw4_RestoreDisplayMode(IDirectDraw4 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(iface));
+}
+
+static HRESULT WINAPI ddraw3_RestoreDisplayMode(IDirectDraw3 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(iface));
+}
+
+static HRESULT WINAPI ddraw2_RestoreDisplayMode(IDirectDraw2 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(iface));
+}
+
+static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(iface));
 }
 
 /*****************************************************************************
@@ -693,10 +909,7 @@ IDirectDrawImpl_RestoreDisplayMode(IDirectDraw7 *iface)
  *  This implementation returns DD_OK only
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetCaps(IDirectDraw7 *iface,
-                        DDCAPS *DriverCaps,
-                        DDCAPS *HELCaps)
+static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DDCAPS *HELCaps)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     DDCAPS caps;
@@ -708,7 +921,7 @@ IDirectDrawImpl_GetCaps(IDirectDraw7 *iface,
     /* One structure must be != NULL */
     if( (!DriverCaps) && (!HELCaps) )
     {
-        ERR("(%p) Invalid params to IDirectDrawImpl_GetCaps\n", This);
+        ERR("(%p) Invalid params to ddraw7_GetCaps\n", This);
         return DDERR_INVALIDPARAMS;
     }
 
@@ -781,6 +994,34 @@ IDirectDrawImpl_GetCaps(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetCaps(IDirectDraw4 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
+{
+    TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
+
+    return ddraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw4(iface), driver_caps, hel_caps);
+}
+
+static HRESULT WINAPI ddraw3_GetCaps(IDirectDraw3 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
+{
+    TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
+
+    return ddraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw3(iface), driver_caps, hel_caps);
+}
+
+static HRESULT WINAPI ddraw2_GetCaps(IDirectDraw2 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
+{
+    TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
+
+    return ddraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw2(iface), driver_caps, hel_caps);
+}
+
+static HRESULT WINAPI ddraw1_GetCaps(IDirectDraw *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
+{
+    TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
+
+    return ddraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw1(iface), driver_caps, hel_caps);
+}
+
 /*****************************************************************************
  * IDirectDraw7::Compact
  *
@@ -790,8 +1031,7 @@ IDirectDrawImpl_GetCaps(IDirectDraw7 *iface,
  *  DD_OK, but this is unchecked
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_Compact(IDirectDraw7 *iface)
+static HRESULT WINAPI ddraw7_Compact(IDirectDraw7 *iface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)\n", This);
@@ -799,6 +1039,34 @@ IDirectDrawImpl_Compact(IDirectDraw7 *iface)
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_Compact(IDirectDraw4 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw4(iface));
+}
+
+static HRESULT WINAPI ddraw3_Compact(IDirectDraw3 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw3(iface));
+}
+
+static HRESULT WINAPI ddraw2_Compact(IDirectDraw2 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw2(iface));
+}
+
+static HRESULT WINAPI ddraw1_Compact(IDirectDraw *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw1(iface));
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetDisplayMode
  *
@@ -813,9 +1081,7 @@ IDirectDrawImpl_Compact(IDirectDraw7 *iface)
  *  DD_OK
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface,
-                               DDSURFACEDESC2 *DDSD)
+static HRESULT WINAPI ddraw7_GetDisplayMode(IDirectDraw7 *iface, DDSURFACEDESC2 *DDSD)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     HRESULT hr;
@@ -867,6 +1133,34 @@ IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 *surface_desc)
+{
+    TRACE("iface %p, surface_desc %p.\n", iface, surface_desc);
+
+    return ddraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(iface), surface_desc);
+}
+
+static HRESULT WINAPI ddraw3_GetDisplayMode(IDirectDraw3 *iface, DDSURFACEDESC *surface_desc)
+{
+    TRACE("iface %p, surface_desc %p.\n", iface, surface_desc);
+
+    return ddraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(iface), (DDSURFACEDESC2 *)surface_desc);
+}
+
+static HRESULT WINAPI ddraw2_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC *surface_desc)
+{
+    TRACE("iface %p, surface_desc %p.\n", iface, surface_desc);
+
+    return ddraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(iface), (DDSURFACEDESC2 *)surface_desc);
+}
+
+static HRESULT WINAPI ddraw1_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *surface_desc)
+{
+    TRACE("iface %p, surface_desc %p.\n", iface, surface_desc);
+
+    return ddraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(iface), (DDSURFACEDESC2 *)surface_desc);
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetFourCCCodes
  *
@@ -884,9 +1178,7 @@ IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface,
  *  Always returns DD_OK, as it's a stub for now
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface,
-                               DWORD *NumCodes, DWORD *Codes)
+static HRESULT WINAPI ddraw7_GetFourCCCodes(IDirectDraw7 *iface, DWORD *NumCodes, DWORD *Codes)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     WINED3DFORMAT formats[] = {
@@ -932,6 +1224,34 @@ IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetFourCCCodes(IDirectDraw4 *iface, DWORD *codes_count, DWORD *codes)
+{
+    TRACE("iface %p, codes_count %p, codes %p.\n", iface, codes_count, codes);
+
+    return ddraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw4(iface), codes_count, codes);
+}
+
+static HRESULT WINAPI ddraw3_GetFourCCCodes(IDirectDraw3 *iface, DWORD *codes_count, DWORD *codes)
+{
+    TRACE("iface %p, codes_count %p, codes %p.\n", iface, codes_count, codes);
+
+    return ddraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw3(iface), codes_count, codes);
+}
+
+static HRESULT WINAPI ddraw2_GetFourCCCodes(IDirectDraw2 *iface, DWORD *codes_count, DWORD *codes)
+{
+    TRACE("iface %p, codes_count %p, codes %p.\n", iface, codes_count, codes);
+
+    return ddraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw2(iface), codes_count, codes);
+}
+
+static HRESULT WINAPI ddraw1_GetFourCCCodes(IDirectDraw *iface, DWORD *codes_count, DWORD *codes)
+{
+    TRACE("iface %p, codes_count %p, codes %p.\n", iface, codes_count, codes);
+
+    return ddraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw1(iface), codes_count, codes);
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetMonitorFrequency
  *
@@ -946,9 +1266,7 @@ IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface,
  *  Always returns DD_OK
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetMonitorFrequency(IDirectDraw7 *iface,
-                                    DWORD *Freq)
+static HRESULT WINAPI ddraw7_GetMonitorFrequency(IDirectDraw7 *iface, DWORD *Freq)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)->(%p)\n", This, Freq);
@@ -960,6 +1278,34 @@ IDirectDrawImpl_GetMonitorFrequency(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetMonitorFrequency(IDirectDraw4 *iface, DWORD *frequency)
+{
+    TRACE("iface %p, frequency %p.\n", iface, frequency);
+
+    return ddraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw4(iface), frequency);
+}
+
+static HRESULT WINAPI ddraw3_GetMonitorFrequency(IDirectDraw3 *iface, DWORD *frequency)
+{
+    TRACE("iface %p, frequency %p.\n", iface, frequency);
+
+    return ddraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw3(iface), frequency);
+}
+
+static HRESULT WINAPI ddraw2_GetMonitorFrequency(IDirectDraw2 *iface, DWORD *frequency)
+{
+    TRACE("iface %p, frequency %p.\n", iface, frequency);
+
+    return ddraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw2(iface), frequency);
+}
+
+static HRESULT WINAPI ddraw1_GetMonitorFrequency(IDirectDraw *iface, DWORD *frequency)
+{
+    TRACE("iface %p, frequency %p.\n", iface, frequency);
+
+    return ddraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw1(iface), frequency);
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetVerticalBlankStatus
  *
@@ -974,9 +1320,7 @@ IDirectDrawImpl_GetMonitorFrequency(IDirectDraw7 *iface,
  *  DDERR_INVALIDPARAMS if status is NULL
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw7 *iface,
-                                       BOOL *status)
+static HRESULT WINAPI ddraw7_GetVerticalBlankStatus(IDirectDraw7 *iface, BOOL *status)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)->(%p)\n", This, status);
@@ -995,6 +1339,34 @@ IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetVerticalBlankStatus(IDirectDraw4 *iface, BOOL *status)
+{
+    TRACE("iface %p, status %p.\n", iface, status);
+
+    return ddraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw4(iface), status);
+}
+
+static HRESULT WINAPI ddraw3_GetVerticalBlankStatus(IDirectDraw3 *iface, BOOL *status)
+{
+    TRACE("iface %p, status %p.\n", iface, status);
+
+    return ddraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw3(iface), status);
+}
+
+static HRESULT WINAPI ddraw2_GetVerticalBlankStatus(IDirectDraw2 *iface, BOOL *status)
+{
+    TRACE("iface %p, status %p.\n", iface, status);
+
+    return ddraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw2(iface), status);
+}
+
+static HRESULT WINAPI ddraw1_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *status)
+{
+    TRACE("iface %p, status %p.\n", iface, status);
+
+    return ddraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw1(iface), status);
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetAvailableVidMem
  *
@@ -1010,8 +1382,7 @@ IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw7 *iface,
  *  DDERR_INVALIDPARAMS of free and total are NULL
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *total, DWORD *free)
+static HRESULT WINAPI ddraw7_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *total, DWORD *free)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
@@ -1041,6 +1412,36 @@ IDirectDrawImpl_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *t
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetAvailableVidMem(IDirectDraw4 *iface,
+        DDSCAPS2 *caps, DWORD *total, DWORD *free)
+{
+    TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
+
+    return ddraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw4(iface), caps, total, free);
+}
+
+static HRESULT WINAPI ddraw3_GetAvailableVidMem(IDirectDraw3 *iface,
+        DDSCAPS *caps, DWORD *total, DWORD *free)
+{
+    DDSCAPS2 caps2;
+
+    TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
+
+    DDRAW_Convert_DDSCAPS_1_To_2(caps, &caps2);
+    return ddraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw3(iface), &caps2, total, free);
+}
+
+static HRESULT WINAPI ddraw2_GetAvailableVidMem(IDirectDraw2 *iface,
+        DDSCAPS *caps, DWORD *total, DWORD *free)
+{
+    DDSCAPS2 caps2;
+
+    TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
+
+    DDRAW_Convert_DDSCAPS_1_To_2(caps, &caps2);
+    return ddraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw2(iface), &caps2, total, free);
+}
+
 /*****************************************************************************
  * IDirectDraw7::Initialize
  *
@@ -1055,9 +1456,7 @@ IDirectDrawImpl_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *t
  *  DDERR_ALREADYINITIALIZED on repeated calls
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_Initialize(IDirectDraw7 *iface,
-                           GUID *Guid)
+static HRESULT WINAPI ddraw7_Initialize(IDirectDraw7 *iface, GUID *Guid)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)->(%s): No-op\n", This, debugstr_guid(Guid));
@@ -1072,6 +1471,34 @@ IDirectDrawImpl_Initialize(IDirectDraw7 *iface,
     }
 }
 
+static HRESULT WINAPI ddraw4_Initialize(IDirectDraw4 *iface, GUID *guid)
+{
+    TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+    return ddraw7_Initialize((IDirectDraw7 *)ddraw_from_ddraw4(iface), guid);
+}
+
+static HRESULT WINAPI ddraw3_Initialize(IDirectDraw3 *iface, GUID *guid)
+{
+    TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+    return ddraw7_Initialize((IDirectDraw7 *)ddraw_from_ddraw3(iface), guid);
+}
+
+static HRESULT WINAPI ddraw2_Initialize(IDirectDraw2 *iface, GUID *guid)
+{
+    TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+    return ddraw7_Initialize((IDirectDraw7 *)ddraw_from_ddraw2(iface), guid);
+}
+
+static HRESULT WINAPI ddraw1_Initialize(IDirectDraw *iface, GUID *guid)
+{
+    TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+    return ddraw7_Initialize((IDirectDraw7 *)ddraw_from_ddraw1(iface), guid);
+}
+
 /*****************************************************************************
  * IDirectDraw7::FlipToGDISurface
  *
@@ -1085,8 +1512,7 @@ IDirectDrawImpl_Initialize(IDirectDraw7 *iface,
  *  Always returns DD_OK
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_FlipToGDISurface(IDirectDraw7 *iface)
+static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)\n", This);
@@ -1094,6 +1520,34 @@ IDirectDrawImpl_FlipToGDISurface(IDirectDraw7 *iface)
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_FlipToGDISurface(IDirectDraw4 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw4(iface));
+}
+
+static HRESULT WINAPI ddraw3_FlipToGDISurface(IDirectDraw3 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw3(iface));
+}
+
+static HRESULT WINAPI ddraw2_FlipToGDISurface(IDirectDraw2 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw2(iface));
+}
+
+static HRESULT WINAPI ddraw1_FlipToGDISurface(IDirectDraw *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw1(iface));
+}
+
 /*****************************************************************************
  * IDirectDraw7::WaitForVerticalBlank
  *
@@ -1111,10 +1565,7 @@ IDirectDrawImpl_FlipToGDISurface(IDirectDraw7 *iface)
  *  Always returns DD_OK
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
-                                     DWORD Flags,
-                                     HANDLE h)
+static HRESULT WINAPI ddraw7_WaitForVerticalBlank(IDirectDraw7 *iface, DWORD Flags, HANDLE h)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     static BOOL hide = FALSE;
@@ -1133,6 +1584,34 @@ IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_WaitForVerticalBlank(IDirectDraw4 *iface, DWORD flags, HANDLE event)
+{
+    TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
+
+    return ddraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw4(iface), flags, event);
+}
+
+static HRESULT WINAPI ddraw3_WaitForVerticalBlank(IDirectDraw3 *iface, DWORD flags, HANDLE event)
+{
+    TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
+
+    return ddraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw3(iface), flags, event);
+}
+
+static HRESULT WINAPI ddraw2_WaitForVerticalBlank(IDirectDraw2 *iface, DWORD flags, HANDLE event)
+{
+    TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
+
+    return ddraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw2(iface), flags, event);
+}
+
+static HRESULT WINAPI ddraw1_WaitForVerticalBlank(IDirectDraw *iface, DWORD flags, HANDLE event)
+{
+    TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
+
+    return ddraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw1(iface), flags, event);
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetScanLine
  *
@@ -1145,7 +1624,7 @@ IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
  *  Always returns DD_OK
  *
  *****************************************************************************/
-static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
+static HRESULT WINAPI ddraw7_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     static BOOL hide = FALSE;
@@ -1174,6 +1653,34 @@ static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Sc
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetScanLine(IDirectDraw4 *iface, DWORD *line)
+{
+    TRACE("iface %p, line %p.\n", iface, line);
+
+    return ddraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw4(iface), line);
+}
+
+static HRESULT WINAPI ddraw3_GetScanLine(IDirectDraw3 *iface, DWORD *line)
+{
+    TRACE("iface %p, line %p.\n", iface, line);
+
+    return ddraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw3(iface), line);
+}
+
+static HRESULT WINAPI ddraw2_GetScanLine(IDirectDraw2 *iface, DWORD *line)
+{
+    TRACE("iface %p, line %p.\n", iface, line);
+
+    return ddraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw2(iface), line);
+}
+
+static HRESULT WINAPI ddraw1_GetScanLine(IDirectDraw *iface, DWORD *line)
+{
+    TRACE("iface %p, line %p.\n", iface, line);
+
+    return ddraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw1(iface), line);
+}
+
 /*****************************************************************************
  * IDirectDraw7::TestCooperativeLevel
  *
@@ -1186,14 +1693,20 @@ static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Sc
  *  if the state is not correct(See below)
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
+static HRESULT WINAPI ddraw7_TestCooperativeLevel(IDirectDraw7 *iface)
 {
     TRACE("iface %p.\n", iface);
 
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_TestCooperativeLevel(IDirectDraw4 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_TestCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw4(iface));
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetGDISurface
  *
@@ -1208,9 +1721,7 @@ IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
  *  DDERR_NOTFOUND if the GDI surface wasn't found
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
-                              IDirectDrawSurface7 **GDISurface)
+static HRESULT WINAPI ddraw7_GetGDISurface(IDirectDraw7 *iface, IDirectDrawSurface7 **GDISurface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     IWineD3DSurface *Surf;
@@ -1259,6 +1770,69 @@ IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
     return hr;
 }
 
+static HRESULT WINAPI ddraw4_GetGDISurface(IDirectDraw4 *iface, IDirectDrawSurface4 **surface)
+{
+    TRACE("iface %p, surface %p.\n", iface, surface);
+
+    return ddraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw4(iface), (IDirectDrawSurface7 **)surface);
+}
+
+static HRESULT WINAPI ddraw3_GetGDISurface(IDirectDraw3 *iface, IDirectDrawSurface **surface)
+{
+    IDirectDrawSurface7 *surface7;
+    HRESULT hr;
+
+    TRACE("iface %p, surface %p.\n", iface, surface);
+
+    hr = ddraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw3(iface), &surface7);
+    *surface = surface7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)surface7)->IDirectDrawSurface3_vtbl : NULL;
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw2_GetGDISurface(IDirectDraw2 *iface, IDirectDrawSurface **surface)
+{
+    IDirectDrawSurface7 *surface7;
+    HRESULT hr;
+
+    TRACE("iface %p, surface %p.\n", iface, surface);
+
+    hr = ddraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw2(iface), &surface7);
+    *surface = surface7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)surface7)->IDirectDrawSurface3_vtbl : NULL;
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw1_GetGDISurface(IDirectDraw *iface, IDirectDrawSurface **surface)
+{
+    IDirectDrawSurface7 *surface7;
+    HRESULT hr;
+
+    TRACE("iface %p, surface %p.\n", iface, surface);
+
+    hr = ddraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw1(iface), &surface7);
+    *surface = surface7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)surface7)->IDirectDrawSurface3_vtbl : NULL;
+
+    return hr;
+}
+
+struct displaymodescallback_context
+{
+    LPDDENUMMODESCALLBACK func;
+    void *context;
+};
+
+static HRESULT CALLBACK EnumDisplayModesCallbackThunk(DDSURFACEDESC2 *surface_desc, void *context)
+{
+    struct displaymodescallback_context *cbcontext = context;
+    DDSURFACEDESC desc;
+
+    memcpy(&desc, surface_desc, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+
+    return cbcontext->func(&desc, cbcontext->context);
+}
+
 /*****************************************************************************
  * IDirectDraw7::EnumDisplayModes
  *
@@ -1276,12 +1850,8 @@ IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
  *  DDERR_INVALIDPARAMS if the callback wasn't set
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
-                                 DWORD Flags,
-                                 DDSURFACEDESC2 *DDSD,
-                                 void *Context,
-                                 LPDDENUMMODESCALLBACK2 cb)
+static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
+        DDSURFACEDESC2 *DDSD, void *Context, LPDDENUMMODESCALLBACK2 cb)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     unsigned int modenum, fmt;
@@ -1430,6 +2000,61 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_EnumDisplayModes(IDirectDraw4 *iface, DWORD flags,
+        DDSURFACEDESC2 *surface_desc, void *context, LPDDENUMMODESCALLBACK2 callback)
+{
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    return ddraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw4(iface), flags,
+            surface_desc, context, callback);
+}
+
+static HRESULT WINAPI ddraw3_EnumDisplayModes(IDirectDraw3 *iface, DWORD flags,
+        DDSURFACEDESC *surface_desc, void *context, LPDDENUMMODESCALLBACK callback)
+{
+    struct displaymodescallback_context cbcontext;
+
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    cbcontext.func = callback;
+    cbcontext.context = context;
+
+    return ddraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw3(iface), flags,
+            (DDSURFACEDESC2 *)surface_desc, &cbcontext, EnumDisplayModesCallbackThunk);
+}
+
+static HRESULT WINAPI ddraw2_EnumDisplayModes(IDirectDraw2 *iface, DWORD flags,
+        DDSURFACEDESC *surface_desc, void *context, LPDDENUMMODESCALLBACK callback)
+{
+    struct displaymodescallback_context cbcontext;
+
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    cbcontext.func = callback;
+    cbcontext.context = context;
+
+    return ddraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw2(iface), flags,
+            (DDSURFACEDESC2 *)surface_desc, &cbcontext, EnumDisplayModesCallbackThunk);
+}
+
+static HRESULT WINAPI ddraw1_EnumDisplayModes(IDirectDraw *iface, DWORD flags,
+        DDSURFACEDESC *surface_desc, void *context, LPDDENUMMODESCALLBACK callback)
+{
+    struct displaymodescallback_context cbcontext;
+
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    cbcontext.func = callback;
+    cbcontext.context = context;
+
+    return ddraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw1(iface), flags,
+            (DDSURFACEDESC2 *)surface_desc, &cbcontext, EnumDisplayModesCallbackThunk);
+}
+
 /*****************************************************************************
  * IDirectDraw7::EvaluateMode
  *
@@ -1446,10 +2071,7 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
  *  This implementation always DD_OK, because it's a stub
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_EvaluateMode(IDirectDraw7 *iface,
-                             DWORD Flags,
-                             DWORD *Timeout)
+static HRESULT WINAPI ddraw7_EvaluateMode(IDirectDraw7 *iface, DWORD Flags, DWORD *Timeout)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     FIXME("(%p)->(%d,%p): Stub!\n", This, Flags, Timeout);
@@ -1474,10 +2096,8 @@ IDirectDrawImpl_EvaluateMode(IDirectDraw7 *iface,
  *  DDERR_INVALIDPARAMS if DDDI is NULL
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetDeviceIdentifier(IDirectDraw7 *iface,
-                                    DDDEVICEIDENTIFIER2 *DDDI,
-                                    DWORD Flags)
+static HRESULT WINAPI ddraw7_GetDeviceIdentifier(IDirectDraw7 *iface,
+        DDDEVICEIDENTIFIER2 *DDDI, DWORD Flags)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)->(%p,%08x)\n", This, DDDI, Flags);
@@ -1496,6 +2116,20 @@ IDirectDrawImpl_GetDeviceIdentifier(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetDeviceIdentifier(IDirectDraw4 *iface,
+        DDDEVICEIDENTIFIER *identifier, DWORD flags)
+{
+    DDDEVICEIDENTIFIER2 identifier2;
+    HRESULT hr;
+
+    TRACE("iface %p, identifier %p, flags %#x.\n", iface, identifier, flags);
+
+    hr = ddraw7_GetDeviceIdentifier((IDirectDraw7 *)ddraw_from_ddraw4(iface), &identifier2, flags);
+    DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(&identifier2, identifier);
+
+    return hr;
+}
+
 /*****************************************************************************
  * IDirectDraw7::GetSurfaceFromDC
  *
@@ -1510,10 +2144,7 @@ IDirectDrawImpl_GetDeviceIdentifier(IDirectDraw7 *iface,
  *  Always returns DD_OK because it's a stub
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface,
-                                 HDC hdc,
-                                 IDirectDrawSurface7 **Surface)
+static HRESULT WINAPI ddraw7_GetSurfaceFromDC(IDirectDraw7 *iface, HDC hdc, IDirectDrawSurface7 **Surface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     IWineD3DSurface *wined3d_surface;
@@ -1536,6 +2167,29 @@ IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_GetSurfaceFromDC(IDirectDraw4 *iface, HDC dc, IDirectDrawSurface4 **surface)
+{
+    IDirectDrawSurface7 *surface7;
+    HRESULT hr;
+
+    TRACE("iface %p, dc %p, surface %p.\n", iface, dc, surface);
+
+    if (!surface) return E_INVALIDARG;
+
+    hr = ddraw7_GetSurfaceFromDC((IDirectDraw7 *)ddraw_from_ddraw4(iface), dc, &surface7);
+    *surface = surface7 ? (IDirectDrawSurface4 *)&((IDirectDrawSurfaceImpl *)surface7)->IDirectDrawSurface3_vtbl : NULL;
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw3_GetSurfaceFromDC(IDirectDraw3 *iface, HDC dc, IDirectDrawSurface **surface)
+{
+    TRACE("iface %p, dc %p, surface %p.\n", iface, dc, surface);
+
+    return ddraw7_GetSurfaceFromDC((IDirectDraw7 *)ddraw_from_ddraw3(iface),
+            dc, (IDirectDrawSurface7 **)surface);
+}
+
 /*****************************************************************************
  * IDirectDraw7::RestoreAllSurfaces
  *
@@ -1547,8 +2201,7 @@ IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface,
  *  Always returns DD_OK because it's a stub
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_RestoreAllSurfaces(IDirectDraw7 *iface)
+static HRESULT WINAPI ddraw7_RestoreAllSurfaces(IDirectDraw7 *iface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     FIXME("(%p): Stub\n", This);
@@ -1561,6 +2214,13 @@ IDirectDrawImpl_RestoreAllSurfaces(IDirectDraw7 *iface)
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_RestoreAllSurfaces(IDirectDraw4 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return ddraw7_RestoreAllSurfaces((IDirectDraw7 *)ddraw_from_ddraw4(iface));
+}
+
 /*****************************************************************************
  * IDirectDraw7::StartModeTest
  *
@@ -1583,11 +2243,7 @@ IDirectDrawImpl_RestoreAllSurfaces(IDirectDraw7 *iface)
  *  otherwise DD_OK
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_StartModeTest(IDirectDraw7 *iface,
-                              SIZE *Modes,
-                              DWORD NumModes,
-                              DWORD Flags)
+static HRESULT WINAPI ddraw7_StartModeTest(IDirectDraw7 *iface, SIZE *Modes, DWORD NumModes, DWORD Flags)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     WARN("(%p)->(%p, %d, %x): Semi-Stub, most likely harmless\n", This, Modes, NumModes, Flags);
@@ -1607,16 +2263,13 @@ IDirectDrawImpl_StartModeTest(IDirectDraw7 *iface,
 }
 
 /*****************************************************************************
- * IDirectDrawImpl_RecreateSurfacesCallback
+ * ddraw_recreate_surfaces_cb
  *
- * Enumeration callback for IDirectDrawImpl_RecreateAllSurfaces.
+ * Enumeration callback for ddraw_recreate_surface.
  * It re-recreates the WineD3DSurface. It's pretty straightforward
  *
  *****************************************************************************/
-HRESULT WINAPI
-IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
-                                         DDSURFACEDESC2 *desc,
-                                         void *Context)
+HRESULT WINAPI ddraw_recreate_surfaces_cb(IDirectDrawSurface7 *surf, DDSURFACEDESC2 *desc, void *Context)
 {
     IDirectDrawSurfaceImpl *surfImpl = (IDirectDrawSurfaceImpl *)surf;
     IDirectDrawImpl *This = surfImpl->ddraw;
@@ -1708,15 +2361,14 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
 }
 
 /*****************************************************************************
- * IDirectDrawImpl_RecreateAllSurfaces
+ * ddraw_recreate_surfaces
  *
  * A function, that converts all wineD3DSurfaces to the new implementation type
  * It enumerates all surfaces with IWineD3DDevice::EnumSurfaces, creates a
  * new WineD3DSurface, copies the content and releases the old surface
  *
  *****************************************************************************/
-static HRESULT
-IDirectDrawImpl_RecreateAllSurfaces(IDirectDrawImpl *This)
+static HRESULT ddraw_recreate_surfaces(IDirectDrawImpl *This)
 {
     DDSURFACEDESC2 desc;
     TRACE("(%p): Switch to implementation %d\n", This, This->ImplType);
@@ -1733,7 +2385,7 @@ IDirectDrawImpl_RecreateAllSurfaces(IDirectDrawImpl *This)
     memset(&desc, 0, sizeof(desc));
     desc.dwSize = sizeof(desc);
 
-    return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)This, 0, &desc, This, IDirectDrawImpl_RecreateSurfacesCallback);
+    return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)This, 0, &desc, This, ddraw_recreate_surfaces_cb);
 }
 
 ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
@@ -1746,7 +2398,7 @@ ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
 }
 
 /*****************************************************************************
- * IDirectDrawImpl_CreateNewSurface
+ * ddraw_create_surface
  *
  * A helper function for IDirectDraw7::CreateSurface. It creates a new surface
  * with the passed parameters.
@@ -1759,11 +2411,8 @@ ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
  *  DD_OK on success
  *
  *****************************************************************************/
-static HRESULT
-IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
-                                 DDSURFACEDESC2 *pDDSD,
-                                 IDirectDrawSurfaceImpl **ppSurf,
-                                 UINT level)
+static HRESULT ddraw_create_surface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD,
+        IDirectDrawSurfaceImpl **ppSurf, UINT level)
 {
     HRESULT hr;
     UINT Width, Height;
@@ -1824,7 +2473,7 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
             ImplType = SURFACE_OPENGL;
             This->ImplType = ImplType;
             TRACE("(%p) Re-creating all surfaces\n", This);
-            IDirectDrawImpl_RecreateAllSurfaces(This);
+            ddraw_recreate_surfaces(This);
             TRACE("(%p) Done recreating all surfaces\n", This);
         }
         else if(This->ImplType != SURFACE_OPENGL && pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
@@ -2070,10 +2719,7 @@ CreateAdditionalSurfaces(IDirectDrawImpl *This,
         }
         CubeFaceRoot = FALSE;
 
-        hr = IDirectDrawImpl_CreateNewSurface(This,
-                                              &DDSD,
-                                              &object2,
-                                              level);
+        hr = ddraw_create_surface(This, &DDSD, &object2, level);
         if(hr != DD_OK)
         {
             return hr;
@@ -2097,8 +2743,27 @@ CreateAdditionalSurfaces(IDirectDrawImpl *This,
     return DD_OK;
 }
 
+/* Must set all attached surfaces (e.g. mipmaps) versions as well */
+static void ddraw_set_surface_version(IDirectDrawSurfaceImpl *surface, UINT version)
+{
+    unsigned int i;
+
+    TRACE("surface %p, version %u -> %u.\n", surface, surface->version, version);
+
+    surface->version = version;
+    for (i = 0; i < MAX_COMPLEX_ATTACHED; ++i)
+    {
+        if (!surface->complex_array[i]) break;
+        ddraw_set_surface_version(surface->complex_array[i], version);
+    }
+    while ((surface = surface->next_attached))
+    {
+        ddraw_set_surface_version(surface, version);
+    }
+}
+
 /*****************************************************************************
- * IDirectDrawImpl_AttachD3DDevice
+ * ddraw_attach_d3d_device
  *
  * Initializes the D3D capabilities of WineD3D
  *
@@ -2110,7 +2775,7 @@ CreateAdditionalSurfaces(IDirectDrawImpl *This,
  *  DDERR_* otherwise
  *
  *****************************************************************************/
-static HRESULT IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *primary)
+static HRESULT ddraw_attach_d3d_device(IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *primary)
 {
     WINED3DPRESENT_PARAMETERS localParameters;
     HWND window = ddraw->dest_window;
@@ -2185,7 +2850,7 @@ static HRESULT IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *ddraw, IDirectDr
     return DD_OK;
 }
 
-static HRESULT IDirectDrawImpl_CreateGDISwapChain(IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *primary)
+static HRESULT ddraw_create_gdi_swapchain(IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *primary)
 {
     WINED3DPRESENT_PARAMETERS presentation_parameters;
     HWND window;
@@ -2302,11 +2967,8 @@ static HRESULT IDirectDrawImpl_CreateGDISwapChain(IDirectDrawImpl *ddraw, IDirec
  *  DDERR_* if an error occurs
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
-                              DDSURFACEDESC2 *DDSD,
-                              IDirectDrawSurface7 **Surf,
-                              IUnknown *UnkOuter)
+static HRESULT WINAPI ddraw7_CreateSurface(IDirectDraw7 *iface,
+        DDSURFACEDESC2 *DDSD, IDirectDrawSurface7 **Surf, IUnknown *UnkOuter)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     IDirectDrawSurfaceImpl *object = NULL;
@@ -2560,10 +3222,10 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
     }
 
     /* Create the first surface */
-    hr = IDirectDrawImpl_CreateNewSurface(This, &desc2, &object, 0);
+    hr = ddraw_create_surface(This, &desc2, &object, 0);
     if( hr != DD_OK)
     {
-        ERR("IDirectDrawImpl_CreateNewSurface failed with %08x\n", hr);
+        ERR("ddraw_create_surface failed, hr %#x.\n", hr);
         LeaveCriticalSection(&ddraw_cs);
         return hr;
     }
@@ -2644,11 +3306,11 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
         }
 
         TRACE("(%p) Attaching a D3DDevice, rendertarget = %p\n", This, target);
-        hr = IDirectDrawImpl_AttachD3DDevice(This, target);
-        if(hr != D3D_OK)
+        hr = ddraw_attach_d3d_device(This, target);
+        if (hr != D3D_OK)
         {
             IDirectDrawSurfaceImpl *release_surf;
-            ERR("IDirectDrawImpl_AttachD3DDevice failed, hr = %x\n", hr);
+            ERR("ddraw_attach_d3d_device failed, hr %#x\n", hr);
             *Surf = NULL;
 
             /* The before created surface structures are in an incomplete state here.
@@ -2667,8 +3329,10 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
             LeaveCriticalSection(&ddraw_cs);
             return hr;
         }
-    } else if(!(This->d3d_initialized) && desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) {
-        IDirectDrawImpl_CreateGDISwapChain(This, object);
+    }
+    else if(!(This->d3d_initialized) && desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+    {
+        ddraw_create_gdi_swapchain(This, object);
     }
 
     /* Addref the ddraw interface to keep an reference for each surface */
@@ -2727,6 +3391,114 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
     return hr;
 }
 
+static HRESULT WINAPI ddraw4_CreateSurface(IDirectDraw4 *iface,
+        DDSURFACEDESC2 *surface_desc, IDirectDrawSurface4 **surface, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw4(iface);
+    IDirectDrawSurfaceImpl *impl;
+    HRESULT hr;
+
+    TRACE("iface %p, surface_desc %p, surface %p, outer_unknown %p.\n",
+            iface, surface_desc, surface, outer_unknown);
+
+    hr = ddraw7_CreateSurface((IDirectDraw7 *)ddraw, surface_desc, (IDirectDrawSurface7 **)surface, outer_unknown);
+    impl = (IDirectDrawSurfaceImpl *)*surface;
+    if (SUCCEEDED(hr) && impl)
+    {
+        ddraw_set_surface_version(impl, 4);
+        IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+        IDirectDraw4_AddRef(iface);
+        impl->ifaceToRelease = (IUnknown *)iface;
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw3_CreateSurface(IDirectDraw3 *iface,
+        DDSURFACEDESC *surface_desc, IDirectDrawSurface **surface, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw3(iface);
+    IDirectDrawSurface7 *surface7;
+    IDirectDrawSurfaceImpl *impl;
+    HRESULT hr;
+
+    TRACE("iface %p, surface_desc %p, surface %p, outer_unknown %p.\n",
+            iface, surface_desc, surface, outer_unknown);
+
+    hr = ddraw7_CreateSurface((IDirectDraw7 *)ddraw, (DDSURFACEDESC2 *)surface_desc, &surface7, outer_unknown);
+    if (FAILED(hr))
+    {
+        *surface = NULL;
+        return hr;
+    }
+
+    impl = (IDirectDrawSurfaceImpl *)surface7;
+    *surface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
+    ddraw_set_surface_version(impl, 3);
+    IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+    IDirectDraw3_AddRef(iface);
+    impl->ifaceToRelease = (IUnknown *)iface;
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw2_CreateSurface(IDirectDraw2 *iface,
+        DDSURFACEDESC *surface_desc, IDirectDrawSurface **surface, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw2(iface);
+    IDirectDrawSurface7 *surface7;
+    IDirectDrawSurfaceImpl *impl;
+    HRESULT hr;
+
+    TRACE("iface %p, surface_desc %p, surface %p, outer_unknown %p.\n",
+            iface, surface_desc, surface, outer_unknown);
+
+    hr = ddraw7_CreateSurface((IDirectDraw7 *)ddraw, (DDSURFACEDESC2 *)surface_desc, &surface7, outer_unknown);
+    if (FAILED(hr))
+    {
+        *surface = NULL;
+        return hr;
+    }
+
+    impl = (IDirectDrawSurfaceImpl *)surface7;
+    *surface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
+    ddraw_set_surface_version(impl, 2);
+    IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+    impl->ifaceToRelease = NULL;
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw1_CreateSurface(IDirectDraw *iface,
+        DDSURFACEDESC *surface_desc, IDirectDrawSurface **surface, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw1(iface);
+    IDirectDrawSurface7 *surface7;
+    IDirectDrawSurfaceImpl *impl;
+    HRESULT hr;
+
+    TRACE("iface %p, surface_desc %p, surface %p, outer_unknown %p.\n",
+            iface, surface_desc, surface, outer_unknown);
+
+    /* Remove front buffer flag, this causes failure in v7, and its added to normal
+     * primaries anyway. */
+    surface_desc->ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
+    hr = ddraw7_CreateSurface((IDirectDraw7 *)ddraw, (DDSURFACEDESC2 *)surface_desc, &surface7, outer_unknown);
+    if (FAILED(hr))
+    {
+        *surface = NULL;
+        return hr;
+    }
+
+    impl = (IDirectDrawSurfaceImpl *)surface7;
+    *surface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
+    ddraw_set_surface_version(impl, 1);
+    IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+    impl->ifaceToRelease = NULL;
+
+    return hr;
+}
+
 #define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST)
 #define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH)
 
@@ -2776,9 +3548,7 @@ Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested,
     return TRUE;
 }
 
-static BOOL
-IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested,
-                           const DDSURFACEDESC2* provided)
+static BOOL ddraw_match_surface_desc(const DDSURFACEDESC2 *requested, const DDSURFACEDESC2 *provided)
 {
     struct compare_info
     {
@@ -2841,6 +3611,21 @@ IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested,
 #undef DDENUMSURFACES_SEARCHTYPE
 #undef DDENUMSURFACES_MATCHTYPE
 
+struct surfacescallback_context
+{
+    LPDDENUMSURFACESCALLBACK func;
+    void *context;
+};
+
+static HRESULT CALLBACK EnumSurfacesCallbackThunk(IDirectDrawSurface7 *surface,
+        DDSURFACEDESC2 *surface_desc, void *context)
+{
+    struct surfacescallback_context *cbcontext = context;
+
+    return cbcontext->func((IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)surface)->IDirectDrawSurface3_vtbl,
+            (DDSURFACEDESC *)surface_desc, cbcontext->context);
+}
+
 /*****************************************************************************
  * IDirectDraw7::EnumSurfaces
  *
@@ -2860,12 +3645,8 @@ IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested,
  *  DD_OK on success
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_EnumSurfaces(IDirectDraw7 *iface,
-                             DWORD Flags,
-                             DDSURFACEDESC2 *DDSD,
-                             void *Context,
-                             LPDDENUMSURFACESCALLBACK7 Callback)
+static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags,
+        DDSURFACEDESC2 *DDSD, void *Context, LPDDENUMSURFACESCALLBACK7 Callback)
 {
     /* The surface enumeration is handled by WineDDraw,
      * because it keeps track of all surfaces attached to
@@ -2895,7 +3676,7 @@ IDirectDrawImpl_EnumSurfaces(IDirectDraw7 *iface,
     LIST_FOR_EACH_SAFE(entry, entry2, &This->surface_list)
     {
         surf = LIST_ENTRY(entry, IDirectDrawSurfaceImpl, surface_list_entry);
-        if (all || (nomatch != IDirectDrawImpl_DDSD_Match(DDSD, &surf->surface_desc)))
+        if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc)))
         {
             desc = surf->surface_desc;
             IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)surf);
@@ -2910,6 +3691,61 @@ IDirectDrawImpl_EnumSurfaces(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_EnumSurfaces(IDirectDraw4 *iface, DWORD flags,
+        DDSURFACEDESC2 *surface_desc, void *context, LPDDENUMSURFACESCALLBACK2 callback)
+{
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    return ddraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw4(iface),
+            flags, surface_desc, context, (LPDDENUMSURFACESCALLBACK7)callback);
+}
+
+static HRESULT WINAPI ddraw3_EnumSurfaces(IDirectDraw3 *iface, DWORD flags,
+        DDSURFACEDESC *surface_desc, void *context, LPDDENUMSURFACESCALLBACK callback)
+{
+    struct surfacescallback_context cbcontext;
+
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    cbcontext.func = callback;
+    cbcontext.context = context;
+
+    return ddraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw3(iface), flags,
+            (DDSURFACEDESC2 *)surface_desc, &cbcontext, EnumSurfacesCallbackThunk);
+}
+
+static HRESULT WINAPI ddraw2_EnumSurfaces(IDirectDraw2 *iface, DWORD flags,
+        DDSURFACEDESC *surface_desc, void *context, LPDDENUMSURFACESCALLBACK callback)
+{
+    struct surfacescallback_context cbcontext;
+
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    cbcontext.func = callback;
+    cbcontext.context = context;
+
+    return ddraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw2(iface), flags,
+            (DDSURFACEDESC2 *)surface_desc, &cbcontext, EnumSurfacesCallbackThunk);
+}
+
+static HRESULT WINAPI ddraw1_EnumSurfaces(IDirectDraw *iface, DWORD flags,
+        DDSURFACEDESC *surface_desc, void *context, LPDDENUMSURFACESCALLBACK callback)
+{
+    struct surfacescallback_context cbcontext;
+
+    TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n",
+            iface, flags, surface_desc, context, callback);
+
+    cbcontext.func = callback;
+    cbcontext.context = context;
+
+    return ddraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw1(iface), flags,
+            (DDSURFACEDESC2 *)surface_desc, &cbcontext, EnumSurfacesCallbackThunk);
+}
+
 /*****************************************************************************
  * DirectDrawCreateClipper (DDRAW.@)
  *
@@ -2975,17 +3811,50 @@ DirectDrawCreateClipper(DWORD Flags,
  * Creates a DDraw clipper. See DirectDrawCreateClipper for details
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_CreateClipper(IDirectDraw7 *iface,
-                              DWORD Flags,
-                              IDirectDrawClipper **Clipper,
-                              IUnknown *UnkOuter)
+static HRESULT WINAPI ddraw7_CreateClipper(IDirectDraw7 *iface, DWORD Flags,
+        IDirectDrawClipper **Clipper, IUnknown *UnkOuter)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     TRACE("(%p)->(%x,%p,%p)\n", This, Flags, Clipper, UnkOuter);
     return DirectDrawCreateClipper(Flags, Clipper, UnkOuter);
 }
 
+static HRESULT WINAPI ddraw4_CreateClipper(IDirectDraw4 *iface,
+        DWORD flags, IDirectDrawClipper **clipper, IUnknown *outer_unknown)
+{
+    TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
+            iface, flags, clipper, outer_unknown);
+
+    return ddraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw4(iface), flags, clipper, outer_unknown);
+}
+
+static HRESULT WINAPI ddraw3_CreateClipper(IDirectDraw3 *iface,
+        DWORD flags, IDirectDrawClipper **clipper, IUnknown *outer_unknown)
+{
+    TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
+            iface, flags, clipper, outer_unknown);
+
+    return ddraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw3(iface), flags, clipper, outer_unknown);
+}
+
+static HRESULT WINAPI ddraw2_CreateClipper(IDirectDraw2 *iface,
+        DWORD flags, IDirectDrawClipper **clipper, IUnknown *outer_unknown)
+{
+    TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
+            iface, flags, clipper, outer_unknown);
+
+    return ddraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw2(iface), flags, clipper, outer_unknown);
+}
+
+static HRESULT WINAPI ddraw1_CreateClipper(IDirectDraw *iface,
+        DWORD flags, IDirectDrawClipper **clipper, IUnknown *outer_unknown)
+{
+    TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
+            iface, flags, clipper, outer_unknown);
+
+    return ddraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw1(iface), flags, clipper, outer_unknown);
+}
+
 /*****************************************************************************
  * IDirectDraw7::CreatePalette
  *
@@ -3003,12 +3872,8 @@ IDirectDrawImpl_CreateClipper(IDirectDraw7 *iface,
  *  E_OUTOFMEMORY if allocating the object failed
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_CreatePalette(IDirectDraw7 *iface,
-                              DWORD Flags,
-                              PALETTEENTRY *ColorTable,
-                              IDirectDrawPalette **Palette,
-                              IUnknown *pUnkOuter)
+static HRESULT WINAPI ddraw7_CreatePalette(IDirectDraw7 *iface, DWORD Flags,
+        PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *pUnkOuter)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     IDirectDrawPaletteImpl *object;
@@ -3058,6 +3923,87 @@ IDirectDrawImpl_CreatePalette(IDirectDraw7 *iface,
     return DD_OK;
 }
 
+static HRESULT WINAPI ddraw4_CreatePalette(IDirectDraw4 *iface, DWORD flags,
+        PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw4(iface);
+    HRESULT hr;
+
+    TRACE("iface %p, flags %#x, entries %p, palette %p, outer_unknown %p.\n",
+            iface, flags, entries, palette, outer_unknown);
+
+    hr = ddraw7_CreatePalette((IDirectDraw7 *)ddraw, flags, entries, palette, outer_unknown);
+    if (SUCCEEDED(hr) && *palette)
+    {
+        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*palette;
+        IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+        IDirectDraw4_AddRef(iface);
+        impl->ifaceToRelease = (IUnknown *)iface;
+    }
+    return hr;
+}
+
+static HRESULT WINAPI ddraw3_CreatePalette(IDirectDraw3 *iface, DWORD flags,
+        PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw3(iface);
+    HRESULT hr;
+
+    TRACE("iface %p, flags %#x, entries %p, palette %p, outer_unknown %p.\n",
+            iface, flags, entries, palette, outer_unknown);
+
+    hr = ddraw7_CreatePalette((IDirectDraw7 *)ddraw, flags, entries, palette, outer_unknown);
+    if (SUCCEEDED(hr) && *palette)
+    {
+        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*palette;
+        IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+        IDirectDraw4_AddRef(iface);
+        impl->ifaceToRelease = (IUnknown *)iface;
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw2_CreatePalette(IDirectDraw2 *iface, DWORD flags,
+        PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw2(iface);
+    HRESULT hr;
+
+    TRACE("iface %p, flags %#x, entries %p, palette %p, outer_unknown %p.\n",
+            iface, flags, entries, palette, outer_unknown);
+
+    hr = ddraw7_CreatePalette((IDirectDraw7 *)ddraw, flags, entries, palette, outer_unknown);
+    if (SUCCEEDED(hr) && *palette)
+    {
+        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*palette;
+        IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+        impl->ifaceToRelease = NULL;
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw1_CreatePalette(IDirectDraw *iface, DWORD flags,
+        PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
+{
+    IDirectDrawImpl *ddraw = ddraw_from_ddraw1(iface);
+    HRESULT hr;
+
+    TRACE("iface %p, flags %#x, entries %p, palette %p, outer_unknown %p.\n",
+            iface, flags, entries, palette, outer_unknown);
+
+    hr = ddraw7_CreatePalette((IDirectDraw7 *)ddraw, flags, entries, palette, outer_unknown);
+    if (SUCCEEDED(hr) && *palette)
+    {
+        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*palette;
+        IDirectDraw7_Release((IDirectDraw7 *)ddraw);
+        impl->ifaceToRelease = NULL;
+    }
+
+    return hr;
+}
+
 /*****************************************************************************
  * IDirectDraw7::DuplicateSurface
  *
@@ -3075,10 +4021,8 @@ IDirectDrawImpl_CreatePalette(IDirectDraw7 *iface,
  *  See IDirectDraw7::CreateSurface
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirectDrawImpl_DuplicateSurface(IDirectDraw7 *iface,
-                                 IDirectDrawSurface7 *Src,
-                                 IDirectDrawSurface7 **Dest)
+static HRESULT WINAPI ddraw7_DuplicateSurface(IDirectDraw7 *iface,
+        IDirectDrawSurface7 *Src, IDirectDrawSurface7 **Dest)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
     IDirectDrawSurfaceImpl *Surf = (IDirectDrawSurfaceImpl *)Src;
@@ -3092,51 +4036,235 @@ IDirectDrawImpl_DuplicateSurface(IDirectDraw7 *iface,
                                       NULL);
 }
 
+static HRESULT WINAPI ddraw4_DuplicateSurface(IDirectDraw4 *iface,
+        IDirectDrawSurface4 *src, IDirectDrawSurface4 **dst)
+{
+    TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
+
+    return ddraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw4(iface),
+            (IDirectDrawSurface7 *)src, (IDirectDrawSurface7 **)dst);
+}
+
+static HRESULT WINAPI ddraw3_DuplicateSurface(IDirectDraw3 *iface,
+        IDirectDrawSurface *src, IDirectDrawSurface **dst)
+{
+    IDirectDrawSurface7 *src7, *dst7;
+    HRESULT hr;
+
+    TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
+
+    src7 = src ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)src) : NULL;
+    hr = ddraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw3(iface), src7, &dst7);
+    *dst = dst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)dst7)->IDirectDrawSurface3_vtbl : NULL;
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw2_DuplicateSurface(IDirectDraw2 *iface,
+        IDirectDrawSurface *src, IDirectDrawSurface **dst)
+{
+    IDirectDrawSurface7 *src7, *dst7;
+    HRESULT hr;
+
+    TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
+
+    src7 = src ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)src) : NULL;
+    hr = ddraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw2(iface), src7, &dst7);
+    *dst = dst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)dst7)->IDirectDrawSurface3_vtbl : NULL;
+
+    return hr;
+}
+
+static HRESULT WINAPI ddraw1_DuplicateSurface(IDirectDraw *iface,
+        IDirectDrawSurface *src, IDirectDrawSurface **dst)
+{
+    IDirectDrawSurface7 *src7, *dst7;
+    HRESULT hr;
+
+    TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
+
+    src7 = src ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)src) : NULL;
+    hr = ddraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw1(iface), src7, &dst7);
+    *dst = dst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)dst7)->IDirectDrawSurface3_vtbl : NULL;
+
+    return hr;
+}
+
 /*****************************************************************************
  * IDirectDraw7 VTable
  *****************************************************************************/
 const IDirectDraw7Vtbl IDirectDraw7_Vtbl =
 {
-    /*** IUnknown ***/
-    IDirectDrawImpl_QueryInterface,
-    IDirectDrawImpl_AddRef,
-    IDirectDrawImpl_Release,
-    /*** IDirectDraw ***/
-    IDirectDrawImpl_Compact,
-    IDirectDrawImpl_CreateClipper,
-    IDirectDrawImpl_CreatePalette,
-    IDirectDrawImpl_CreateSurface,
-    IDirectDrawImpl_DuplicateSurface,
-    IDirectDrawImpl_EnumDisplayModes,
-    IDirectDrawImpl_EnumSurfaces,
-    IDirectDrawImpl_FlipToGDISurface,
-    IDirectDrawImpl_GetCaps,
-    IDirectDrawImpl_GetDisplayMode,
-    IDirectDrawImpl_GetFourCCCodes,
-    IDirectDrawImpl_GetGDISurface,
-    IDirectDrawImpl_GetMonitorFrequency,
-    IDirectDrawImpl_GetScanLine,
-    IDirectDrawImpl_GetVerticalBlankStatus,
-    IDirectDrawImpl_Initialize,
-    IDirectDrawImpl_RestoreDisplayMode,
-    IDirectDrawImpl_SetCooperativeLevel,
-    IDirectDrawImpl_SetDisplayMode,
-    IDirectDrawImpl_WaitForVerticalBlank,
-    /*** IDirectDraw2 ***/
-    IDirectDrawImpl_GetAvailableVidMem,
-    /*** IDirectDraw3 ***/
-    IDirectDrawImpl_GetSurfaceFromDC,
-    /*** IDirectDraw4 ***/
-    IDirectDrawImpl_RestoreAllSurfaces,
-    IDirectDrawImpl_TestCooperativeLevel,
-    IDirectDrawImpl_GetDeviceIdentifier,
-    /*** IDirectDraw7 ***/
-    IDirectDrawImpl_StartModeTest,
-    IDirectDrawImpl_EvaluateMode
+    /* IUnknown */
+    ddraw7_QueryInterface,
+    ddraw7_AddRef,
+    ddraw7_Release,
+    /* IDirectDraw */
+    ddraw7_Compact,
+    ddraw7_CreateClipper,
+    ddraw7_CreatePalette,
+    ddraw7_CreateSurface,
+    ddraw7_DuplicateSurface,
+    ddraw7_EnumDisplayModes,
+    ddraw7_EnumSurfaces,
+    ddraw7_FlipToGDISurface,
+    ddraw7_GetCaps,
+    ddraw7_GetDisplayMode,
+    ddraw7_GetFourCCCodes,
+    ddraw7_GetGDISurface,
+    ddraw7_GetMonitorFrequency,
+    ddraw7_GetScanLine,
+    ddraw7_GetVerticalBlankStatus,
+    ddraw7_Initialize,
+    ddraw7_RestoreDisplayMode,
+    ddraw7_SetCooperativeLevel,
+    ddraw7_SetDisplayMode,
+    ddraw7_WaitForVerticalBlank,
+    /* IDirectDraw2 */
+    ddraw7_GetAvailableVidMem,
+    /* IDirectDraw3 */
+    ddraw7_GetSurfaceFromDC,
+    /* IDirectDraw4 */
+    ddraw7_RestoreAllSurfaces,
+    ddraw7_TestCooperativeLevel,
+    ddraw7_GetDeviceIdentifier,
+    /* IDirectDraw7 */
+    ddraw7_StartModeTest,
+    ddraw7_EvaluateMode
+};
+
+const struct IDirectDraw4Vtbl IDirectDraw4_Vtbl =
+{
+    /* IUnknown */
+    ddraw4_QueryInterface,
+    ddraw4_AddRef,
+    ddraw4_Release,
+    /* IDirectDraw */
+    ddraw4_Compact,
+    ddraw4_CreateClipper,
+    ddraw4_CreatePalette,
+    ddraw4_CreateSurface,
+    ddraw4_DuplicateSurface,
+    ddraw4_EnumDisplayModes,
+    ddraw4_EnumSurfaces,
+    ddraw4_FlipToGDISurface,
+    ddraw4_GetCaps,
+    ddraw4_GetDisplayMode,
+    ddraw4_GetFourCCCodes,
+    ddraw4_GetGDISurface,
+    ddraw4_GetMonitorFrequency,
+    ddraw4_GetScanLine,
+    ddraw4_GetVerticalBlankStatus,
+    ddraw4_Initialize,
+    ddraw4_RestoreDisplayMode,
+    ddraw4_SetCooperativeLevel,
+    ddraw4_SetDisplayMode,
+    ddraw4_WaitForVerticalBlank,
+    /* IDirectDraw2 */
+    ddraw4_GetAvailableVidMem,
+    /* IDirectDraw3 */
+    ddraw4_GetSurfaceFromDC,
+    /* IDirectDraw4 */
+    ddraw4_RestoreAllSurfaces,
+    ddraw4_TestCooperativeLevel,
+    ddraw4_GetDeviceIdentifier,
+};
+
+const struct IDirectDraw3Vtbl IDirectDraw3_Vtbl =
+{
+    /* IUnknown */
+    ddraw3_QueryInterface,
+    ddraw3_AddRef,
+    ddraw3_Release,
+    /* IDirectDraw */
+    ddraw3_Compact,
+    ddraw3_CreateClipper,
+    ddraw3_CreatePalette,
+    ddraw3_CreateSurface,
+    ddraw3_DuplicateSurface,
+    ddraw3_EnumDisplayModes,
+    ddraw3_EnumSurfaces,
+    ddraw3_FlipToGDISurface,
+    ddraw3_GetCaps,
+    ddraw3_GetDisplayMode,
+    ddraw3_GetFourCCCodes,
+    ddraw3_GetGDISurface,
+    ddraw3_GetMonitorFrequency,
+    ddraw3_GetScanLine,
+    ddraw3_GetVerticalBlankStatus,
+    ddraw3_Initialize,
+    ddraw3_RestoreDisplayMode,
+    ddraw3_SetCooperativeLevel,
+    ddraw3_SetDisplayMode,
+    ddraw3_WaitForVerticalBlank,
+    /* IDirectDraw2 */
+    ddraw3_GetAvailableVidMem,
+    /* IDirectDraw3 */
+    ddraw3_GetSurfaceFromDC,
+};
+
+const struct IDirectDraw2Vtbl IDirectDraw2_Vtbl =
+{
+    /* IUnknown */
+    ddraw2_QueryInterface,
+    ddraw2_AddRef,
+    ddraw2_Release,
+    /* IDirectDraw */
+    ddraw2_Compact,
+    ddraw2_CreateClipper,
+    ddraw2_CreatePalette,
+    ddraw2_CreateSurface,
+    ddraw2_DuplicateSurface,
+    ddraw2_EnumDisplayModes,
+    ddraw2_EnumSurfaces,
+    ddraw2_FlipToGDISurface,
+    ddraw2_GetCaps,
+    ddraw2_GetDisplayMode,
+    ddraw2_GetFourCCCodes,
+    ddraw2_GetGDISurface,
+    ddraw2_GetMonitorFrequency,
+    ddraw2_GetScanLine,
+    ddraw2_GetVerticalBlankStatus,
+    ddraw2_Initialize,
+    ddraw2_RestoreDisplayMode,
+    ddraw2_SetCooperativeLevel,
+    ddraw2_SetDisplayMode,
+    ddraw2_WaitForVerticalBlank,
+    /* IDirectDraw2 */
+    ddraw2_GetAvailableVidMem,
+};
+
+const struct IDirectDrawVtbl IDirectDraw1_Vtbl =
+{
+    /* IUnknown */
+    ddraw1_QueryInterface,
+    ddraw1_AddRef,
+    ddraw1_Release,
+    /* IDirectDraw */
+    ddraw1_Compact,
+    ddraw1_CreateClipper,
+    ddraw1_CreatePalette,
+    ddraw1_CreateSurface,
+    ddraw1_DuplicateSurface,
+    ddraw1_EnumDisplayModes,
+    ddraw1_EnumSurfaces,
+    ddraw1_FlipToGDISurface,
+    ddraw1_GetCaps,
+    ddraw1_GetDisplayMode,
+    ddraw1_GetFourCCCodes,
+    ddraw1_GetGDISurface,
+    ddraw1_GetMonitorFrequency,
+    ddraw1_GetScanLine,
+    ddraw1_GetVerticalBlankStatus,
+    ddraw1_Initialize,
+    ddraw1_RestoreDisplayMode,
+    ddraw1_SetCooperativeLevel,
+    ddraw1_SetDisplayMode,
+    ddraw1_WaitForVerticalBlank,
 };
 
 /*****************************************************************************
- * IDirectDrawImpl_FindDecl
+ * ddraw_find_decl
  *
  * Finds the WineD3D vertex declaration for a specific fvf, and creates one
  * if none was found.
@@ -3155,9 +4283,7 @@ const IDirectDraw7Vtbl IDirectDraw7_Vtbl =
  *  fvf otherwise.
  *
  *****************************************************************************/
-IWineD3DVertexDeclaration *
-IDirectDrawImpl_FindDecl(IDirectDrawImpl *This,
-                         DWORD fvf)
+IWineD3DVertexDeclaration *ddraw_find_decl(IDirectDrawImpl *This, DWORD fvf)
 {
     HRESULT hr;
     IWineD3DVertexDeclaration* pDecl = NULL;
@@ -3218,19 +4344,19 @@ static inline struct IDirectDrawImpl *ddraw_from_device_parent(IWineD3DDevicePar
 static HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object)
 {
     struct IDirectDrawImpl *This = ddraw_from_device_parent(iface);
-    return IDirectDrawImpl_QueryInterface((IDirectDraw7 *)This, riid, object);
+    return ddraw7_QueryInterface((IDirectDraw7 *)This, riid, object);
 }
 
 static ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface)
 {
     struct IDirectDrawImpl *This = ddraw_from_device_parent(iface);
-    return IDirectDrawImpl_AddRef((IDirectDraw7 *)This);
+    return ddraw7_AddRef((IDirectDraw7 *)This);
 }
 
 static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface)
 {
     struct IDirectDrawImpl *This = ddraw_from_device_parent(iface);
-    return IDirectDrawImpl_Release((IDirectDraw7 *)This);
+    return ddraw7_Release((IDirectDraw7 *)This);
 }
 
 /* IWineD3DDeviceParent methods */
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 3de8668..d48eba5 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -188,10 +188,9 @@ typedef struct EnumSurfacesCBS
 /* Utility functions */
 void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS *pIn, DDSCAPS2 *pOut) DECLSPEC_HIDDEN;
 void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2 *pIn, DDDEVICEIDENTIFIER *pOut) DECLSPEC_HIDDEN;
-void IDirectDrawImpl_Destroy(IDirectDrawImpl *This) DECLSPEC_HIDDEN;
-HRESULT WINAPI IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
+HRESULT WINAPI ddraw_recreate_surfaces_cb(IDirectDrawSurface7 *surf,
         DDSURFACEDESC2 *desc, void *Context) DECLSPEC_HIDDEN;
-IWineD3DVertexDeclaration *IDirectDrawImpl_FindDecl(IDirectDrawImpl *This, DWORD fvf) DECLSPEC_HIDDEN;
+IWineD3DVertexDeclaration *ddraw_find_decl(IDirectDrawImpl *This, DWORD fvf) DECLSPEC_HIDDEN;
 
 static inline IDirectDrawImpl *ddraw_from_d3d1(IDirect3D *iface)
 {
@@ -213,26 +212,6 @@ static inline IDirectDrawImpl *ddraw_from_d3d7(IDirect3D7 *iface)
     return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirect3D7_vtbl));
 }
 
-static inline IDirectDrawImpl *ddraw_from_ddraw1(IDirectDraw *iface)
-{
-    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw_vtbl));
-}
-
-static inline IDirectDrawImpl *ddraw_from_ddraw2(IDirectDraw2 *iface)
-{
-    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw2_vtbl));
-}
-
-static inline IDirectDrawImpl *ddraw_from_ddraw3(IDirectDraw3 *iface)
-{
-    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw3_vtbl));
-}
-
-static inline IDirectDrawImpl *ddraw_from_ddraw4(IDirectDraw4 *iface)
-{
-    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw4_vtbl));
-}
-
 /* The default surface type */
 extern WINED3DSURFTYPE DefaultSurfaceType DECLSPEC_HIDDEN;
 
diff --git a/dlls/ddraw/ddraw_thunks.c b/dlls/ddraw/ddraw_thunks.c
deleted file mode 100644
index 2c205e9..0000000
--- a/dlls/ddraw/ddraw_thunks.c
+++ /dev/null
@@ -1,1201 +0,0 @@
-/* Direct Draw Thunks and old vtables
- * Copyright 2000 TransGaming Technologies Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wingdi.h"
-#include "wine/exception.h"
-
-#include "ddraw.h"
-#include "d3d.h"
-
-#include "ddraw_private.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ddraw_thunk);
-WINE_DECLARE_DEBUG_CHANNEL(ddraw);
-
-static HRESULT WINAPI
-IDirectDrawImpl_QueryInterface(LPDIRECTDRAW This, REFIID iid, LPVOID *ppObj)
-{
-    return IDirectDraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw1(This), iid, ppObj);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_QueryInterface(LPDIRECTDRAW2 This, REFIID iid, LPVOID *ppObj)
-{
-    return IDirectDraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw2(This), iid, ppObj);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_QueryInterface(LPDIRECTDRAW3 This, REFIID iid, LPVOID *ppObj)
-{
-    return IDirectDraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw3(This), iid, ppObj);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_QueryInterface(LPDIRECTDRAW4 This, REFIID iid, LPVOID *ppObj)
-{
-    return IDirectDraw7_QueryInterface((IDirectDraw7 *)ddraw_from_ddraw4(This), iid, ppObj);
-}
-
-static ULONG WINAPI
-IDirectDrawImpl_AddRef(LPDIRECTDRAW iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw1(iface);
-    ULONG ref = InterlockedIncrement(&This->ref1);
-
-    TRACE("(%p) : incrementing IDirectDraw refcount from %u.\n", This, ref -1);
-
-    if(ref == 1) InterlockedIncrement(&This->numIfaces);
-
-    return ref;
-}
-
-static ULONG WINAPI
-IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw2(iface);
-    ULONG ref = InterlockedIncrement(&This->ref2);
-
-    TRACE("(%p) : incrementing IDirectDraw2 refcount from %u.\n", This, ref -1);
-
-    if(ref == 1) InterlockedIncrement(&This->numIfaces);
-
-    return ref;
-}
-
-static ULONG WINAPI
-IDirectDraw3Impl_AddRef(LPDIRECTDRAW3 iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw3(iface);
-    ULONG ref = InterlockedIncrement(&This->ref3);
-
-    TRACE("(%p) : incrementing IDirectDraw3 refcount from %u.\n", This, ref -1);
-
-    if(ref == 1) InterlockedIncrement(&This->numIfaces);
-
-    return ref;
-}
-
-static ULONG WINAPI
-IDirectDraw4Impl_AddRef(LPDIRECTDRAW4 iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw4(iface);
-    ULONG ref = InterlockedIncrement(&This->ref4);
-
-    TRACE("(%p) : incrementing IDirectDraw4 refcount from %u.\n", This, ref -1);
-
-    if(ref == 1) InterlockedIncrement(&This->numIfaces);
-
-    return ref;
-}
-
-static ULONG WINAPI
-IDirectDrawImpl_Release(LPDIRECTDRAW iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw1(iface);
-    ULONG ref = InterlockedDecrement(&This->ref1);
-
-    TRACE_(ddraw)("(%p)->() decrementing IDirectDraw refcount from %u.\n", This, ref +1);
-
-    if(ref == 0)
-    {
-        ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
-        if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
-    }
-
-    return ref;
-}
-
-static ULONG WINAPI
-IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw2(iface);
-    ULONG ref = InterlockedDecrement(&This->ref2);
-
-    TRACE_(ddraw)("(%p)->() decrementing IDirectDraw2 refcount from %u.\n", This, ref +1);
-
-    if(ref == 0)
-    {
-        ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
-        if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
-    }
-
-    return ref;
-}
-
-static ULONG WINAPI
-IDirectDraw3Impl_Release(LPDIRECTDRAW3 iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw3(iface);
-    ULONG ref = InterlockedDecrement(&This->ref3);
-
-    TRACE_(ddraw)("(%p)->() decrementing IDirectDraw3 refcount from %u.\n", This, ref +1);
-
-    if(ref == 0)
-    {
-        ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
-        if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
-    }
-
-    return ref;
-}
-
-static ULONG WINAPI
-IDirectDraw4Impl_Release(LPDIRECTDRAW4 iface)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw4(iface);
-    ULONG ref = InterlockedDecrement(&This->ref4);
-
-    TRACE_(ddraw)("(%p)->() decrementing IDirectDraw4 refcount from %u.\n", This, ref +1);
-
-    if(ref == 0)
-    {
-        ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
-        if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
-    }
-
-    return ref;
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_Compact(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw1(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_Compact(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw2(This));
-}
-
-    static HRESULT WINAPI
-IDirectDraw3Impl_Compact(LPDIRECTDRAW3 This)
-{
-    return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw3(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_Compact(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_Compact((IDirectDraw7 *)ddraw_from_ddraw4(This));
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_CreateClipper(LPDIRECTDRAW This, DWORD dwFlags,
-			      LPDIRECTDRAWCLIPPER *ppClipper,
-			      IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw1(This), dwFlags, ppClipper, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_CreateClipper(LPDIRECTDRAW2 This, DWORD dwFlags,
-			       LPDIRECTDRAWCLIPPER *ppClipper,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw2(This), dwFlags, ppClipper, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_CreateClipper(LPDIRECTDRAW3 This, DWORD dwFlags,
-			       LPDIRECTDRAWCLIPPER *ppClipper,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw3(This), dwFlags, ppClipper, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_CreateClipper(LPDIRECTDRAW4 This, DWORD dwFlags,
-			       LPDIRECTDRAWCLIPPER *ppClipper,
-			       IUnknown *pUnkOuter)
-{
-    return IDirectDraw7_CreateClipper((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, ppClipper, pUnkOuter);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_CreatePalette(LPDIRECTDRAW This, DWORD dwFlags,
-			      LPPALETTEENTRY pEntries,
-			      LPDIRECTDRAWPALETTE *ppPalette,
-			      IUnknown *pUnkOuter)
-{
-    HRESULT hr;
-    hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw1(This), dwFlags, pEntries, ppPalette, pUnkOuter);
-    if(SUCCEEDED(hr) && *ppPalette)
-    {
-        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
-        IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This));
-        impl->ifaceToRelease = NULL;
-
-    }
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_CreatePalette(LPDIRECTDRAW2 This, DWORD dwFlags,
-			       LPPALETTEENTRY pEntries,
-			       LPDIRECTDRAWPALETTE *ppPalette,
-			       IUnknown *pUnkOuter)
-{
-    HRESULT hr;
-    hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw2(This), dwFlags, pEntries, ppPalette, pUnkOuter);
-    if(SUCCEEDED(hr) && *ppPalette)
-    {
-        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
-        IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This));
-        impl->ifaceToRelease = NULL;
-    }
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_CreatePalette(LPDIRECTDRAW3 This, DWORD dwFlags,
-			       LPPALETTEENTRY pEntries,
-			       LPDIRECTDRAWPALETTE *ppPalette,
-			       IUnknown *pUnkOuter)
-{
-    HRESULT hr;
-    hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw3(This), dwFlags, pEntries, ppPalette, pUnkOuter);
-    if(SUCCEEDED(hr) && *ppPalette)
-    {
-        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
-        IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw3(This));
-        IDirectDraw4_AddRef(This);
-        impl->ifaceToRelease = (IUnknown *) This;
-    }
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_CreatePalette(LPDIRECTDRAW4 This, DWORD dwFlags,
-			       LPPALETTEENTRY pEntries,
-			       LPDIRECTDRAWPALETTE *ppPalette,
-			       IUnknown *pUnkOuter)
-{
-    HRESULT hr;
-    hr = IDirectDraw7_CreatePalette((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, pEntries, ppPalette, pUnkOuter);
-    if(SUCCEEDED(hr) && *ppPalette)
-    {
-        IDirectDrawPaletteImpl *impl = (IDirectDrawPaletteImpl *)*ppPalette;
-        IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw4(This));
-        IDirectDraw4_AddRef(This);
-        impl->ifaceToRelease = (IUnknown *) This;
-    }
-    return hr;
-}
-
-/* Must set all attached surfaces (e.g. mipmaps) versions as well */
-static void set_surf_version(IDirectDrawSurfaceImpl *surf, int version)
-{
-    int i;
-    TRACE("%p->version(%d) = %d\n", surf, surf->version, version);
-    surf->version = version;
-    for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
-    {
-        if(!surf->complex_array[i]) break;
-        set_surf_version(surf->complex_array[i], version);
-    }
-    while( (surf = surf->next_attached) )
-    {
-        set_surf_version(surf, version);
-    }
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
-			      LPDIRECTDRAWSURFACE *ppSurface,
-			      IUnknown *pUnkOuter)
-{
-    LPDIRECTDRAWSURFACE7 pSurface7;
-    IDirectDrawSurfaceImpl *impl;
-    HRESULT hr;
-
-    /* Remove front buffer flag, this causes failure in v7, and its added to normal
-     * primaries anyway
-     */
-    pSDesc->ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
-    /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok,
-     * since the data layout is the same */
-    hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw1(This),
-            (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
-    if (FAILED(hr))
-    {
-        *ppSurface = NULL;
-        return hr;
-    }
-
-    impl = (IDirectDrawSurfaceImpl *)pSurface7;
-    *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
-    set_surf_version(impl, 1);
-    IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This));
-    impl->ifaceToRelease = NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc,
-			       LPDIRECTDRAWSURFACE *ppSurface,
-			       IUnknown *pUnkOuter)
-{
-    LPDIRECTDRAWSURFACE7 pSurface7;
-    IDirectDrawSurfaceImpl *impl;
-    HRESULT hr;
-
-    hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw2(This),
-            (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
-    if (FAILED(hr))
-    {
-        *ppSurface = NULL;
-        return hr;
-    }
-
-    impl = (IDirectDrawSurfaceImpl *)pSurface7;
-    *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
-    set_surf_version(impl, 2);
-    IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This));
-    impl->ifaceToRelease = NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_CreateSurface(LPDIRECTDRAW3 This, LPDDSURFACEDESC pSDesc,
-			       LPDIRECTDRAWSURFACE *ppSurface,
-			       IUnknown *pUnkOuter)
-{
-    LPDIRECTDRAWSURFACE7 pSurface7;
-    IDirectDrawSurfaceImpl *impl;
-    HRESULT hr;
-
-    hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw3(This),
-            (LPDDSURFACEDESC2)pSDesc, &pSurface7, pUnkOuter);
-    if (FAILED(hr))
-    {
-        *ppSurface = NULL;
-        return hr;
-    }
-
-    impl = (IDirectDrawSurfaceImpl *)pSurface7;
-    *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl;
-    set_surf_version(impl, 3);
-    IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw3(This));
-    IDirectDraw3_AddRef(This);
-    impl->ifaceToRelease = (IUnknown *) This;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc,
-			       LPDIRECTDRAWSURFACE4 *ppSurface,
-			       IUnknown *pUnkOuter)
-{
-    HRESULT hr;
-    IDirectDrawSurfaceImpl *impl;
-
-    hr = IDirectDraw7_CreateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
-            pSDesc, (LPDIRECTDRAWSURFACE7 *)ppSurface, pUnkOuter);
-    impl = (IDirectDrawSurfaceImpl *)*ppSurface;
-    if(SUCCEEDED(hr) && impl)
-    {
-        set_surf_version(impl, 4);
-        IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw4(This));
-        IDirectDraw4_AddRef(This);
-        impl->ifaceToRelease = (IUnknown *) This;
-    }
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_DuplicateSurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE pSrc,
-				 LPDIRECTDRAWSURFACE *ppDst)
-{
-    LPDIRECTDRAWSURFACE7 pDst7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw1(This),
-            pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_DuplicateSurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE pSrc,
-				  LPDIRECTDRAWSURFACE *ppDst)
-{
-    LPDIRECTDRAWSURFACE7 pDst7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw2(This),
-            pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_DuplicateSurface(LPDIRECTDRAW3 This, LPDIRECTDRAWSURFACE pSrc,
-				  LPDIRECTDRAWSURFACE *ppDst)
-{
-    LPDIRECTDRAWSURFACE7 pDst7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw3(This),
-            pSrc ? (IDirectDrawSurface7 *)surface_from_surface3((IDirectDrawSurface3 *)pSrc) : NULL, &pDst7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppDst = pDst7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pDst7)->IDirectDrawSurface3_vtbl : NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_DuplicateSurface(LPDIRECTDRAW4 This,
-				  LPDIRECTDRAWSURFACE4 pSrc,
-				  LPDIRECTDRAWSURFACE4 *ppDst)
-{
-    return IDirectDraw7_DuplicateSurface((IDirectDraw7 *)ddraw_from_ddraw4(This),
-            (LPDIRECTDRAWSURFACE7)pSrc, (LPDIRECTDRAWSURFACE7 *)ppDst);
-}
-
-struct displaymodescallback_context
-{
-    LPDDENUMMODESCALLBACK func;
-    LPVOID context;
-};
-
-static HRESULT CALLBACK
-EnumDisplayModesCallbackThunk(LPDDSURFACEDESC2 pDDSD2, LPVOID context)
-{
-    DDSURFACEDESC DDSD;
-    struct displaymodescallback_context *cbcontext = context;
-
-    memcpy(&DDSD,pDDSD2,sizeof(DDSD));
-    DDSD.dwSize = sizeof(DDSD);
-
-    return cbcontext->func(&DDSD, cbcontext->context);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_EnumDisplayModes(LPDIRECTDRAW This, DWORD dwFlags,
-				 LPDDSURFACEDESC pDDSD, LPVOID context,
-				 LPDDENUMMODESCALLBACK cb)
-{
-    struct displaymodescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw1(This),
-            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumDisplayModesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_EnumDisplayModes(LPDIRECTDRAW2 This, DWORD dwFlags,
-				  LPDDSURFACEDESC pDDSD, LPVOID context,
-				  LPDDENUMMODESCALLBACK cb)
-{
-    struct displaymodescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw2(This),
-            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumDisplayModesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_EnumDisplayModes(LPDIRECTDRAW3 This, DWORD dwFlags,
-				  LPDDSURFACEDESC pDDSD, LPVOID context,
-				  LPDDENUMMODESCALLBACK cb)
-{
-    struct displaymodescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw3(This),
-            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumDisplayModesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_EnumDisplayModes(LPDIRECTDRAW4 This, DWORD dwFlags,
-				  LPDDSURFACEDESC2 pDDSD, LPVOID context,
-				  LPDDENUMMODESCALLBACK2 cb)
-{
-    return IDirectDraw7_EnumDisplayModes((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, pDDSD, context, cb);
-}
-
-struct surfacescallback_context
-{
-    LPDDENUMSURFACESCALLBACK func;
-    LPVOID context;
-};
-
-static HRESULT CALLBACK
-EnumSurfacesCallbackThunk(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((IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf)->IDirectDrawSurface3_vtbl,
-            (DDSURFACEDESC *)pDDSD, cbcontext->context);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_EnumSurfaces(LPDIRECTDRAW This, DWORD dwFlags,
-			     LPDDSURFACEDESC pDDSD, LPVOID context,
-			     LPDDENUMSURFACESCALLBACK cb)
-{
-    struct surfacescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw1(This),
-            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_EnumSurfaces(LPDIRECTDRAW2 This, DWORD dwFlags,
-			      LPDDSURFACEDESC pDDSD, LPVOID context,
-			      LPDDENUMSURFACESCALLBACK cb)
-{
-    struct surfacescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw2(This),
-            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_EnumSurfaces(LPDIRECTDRAW3 This, DWORD dwFlags,
-			      LPDDSURFACEDESC pDDSD, LPVOID context,
-			      LPDDENUMSURFACESCALLBACK cb)
-{
-    struct surfacescallback_context cbcontext;
-
-    cbcontext.func    = cb;
-    cbcontext.context = context;
-
-    return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw3(This),
-            dwFlags, (LPDDSURFACEDESC2)pDDSD, &cbcontext, EnumSurfacesCallbackThunk);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_EnumSurfaces(LPDIRECTDRAW4 This, DWORD dwFlags,
-			      LPDDSURFACEDESC2 pDDSD, LPVOID context,
-			      LPDDENUMSURFACESCALLBACK2 cb)
-{
-    return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)ddraw_from_ddraw4(This),
-            dwFlags, pDDSD, context, (LPDDENUMSURFACESCALLBACK7)cb);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_FlipToGDISurface(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw1(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw2(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_FlipToGDISurface(LPDIRECTDRAW3 This)
-{
-    return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw3(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_FlipToGDISurface(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_FlipToGDISurface((IDirectDraw7 *)ddraw_from_ddraw4(This));
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetCaps(LPDIRECTDRAW This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
-{
-    return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw1(This), pDDC1, pDDC2);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetCaps(LPDIRECTDRAW2 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
-{
-    return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw2(This), pDDC1, pDDC2);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetCaps(LPDIRECTDRAW3 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
-{
-    return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw3(This), pDDC1, pDDC2);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetCaps(LPDIRECTDRAW4 This, LPDDCAPS pDDC1, LPDDCAPS pDDC2)
-{
-    return IDirectDraw7_GetCaps((IDirectDraw7 *)ddraw_from_ddraw4(This), pDDC1, pDDC2);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetDisplayMode(LPDIRECTDRAW This, LPDDSURFACEDESC pDDSD)
-{
-    return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(This), (LPDDSURFACEDESC2)pDDSD);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetDisplayMode(LPDIRECTDRAW2 This, LPDDSURFACEDESC pDDSD)
-{
-    return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(This), (LPDDSURFACEDESC2)pDDSD);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetDisplayMode(LPDIRECTDRAW3 This, LPDDSURFACEDESC pDDSD)
-{
-    return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(This), (LPDDSURFACEDESC2)pDDSD);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetDisplayMode(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pDDSD)
-{
-    return IDirectDraw7_GetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(This), (LPDDSURFACEDESC2)pDDSD);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetFourCCCodes(LPDIRECTDRAW This, LPDWORD lpNumCodes,
-			       LPDWORD lpCodes)
-{
-    return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw1(This), lpNumCodes, lpCodes);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetFourCCCodes(LPDIRECTDRAW2 This, LPDWORD lpNumCodes,
-				LPDWORD lpCodes)
-{
-    return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw2(This), lpNumCodes, lpCodes);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetFourCCCodes(LPDIRECTDRAW3 This, LPDWORD lpNumCodes,
-				LPDWORD lpCodes)
-{
-    return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw3(This), lpNumCodes, lpCodes);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetFourCCCodes(LPDIRECTDRAW4 This, LPDWORD lpNumCodes,
-				LPDWORD lpCodes)
-{
-    return IDirectDraw7_GetFourCCCodes((IDirectDraw7 *)ddraw_from_ddraw4(This), lpNumCodes, lpCodes);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetGDISurface(LPDIRECTDRAW This, LPDIRECTDRAWSURFACE *ppSurf)
-{
-    LPDIRECTDRAWSURFACE7 pSurf7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw1(This), &pSurf7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 This, LPDIRECTDRAWSURFACE *ppSurf)
-{
-    LPDIRECTDRAWSURFACE7 pSurf7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw2(This), &pSurf7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetGDISurface(LPDIRECTDRAW3 This, LPDIRECTDRAWSURFACE *ppSurf)
-{
-    LPDIRECTDRAWSURFACE7 pSurf7;
-    HRESULT hr;
-
-    hr = IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw3(This), &pSurf7);
-
-    /* This coercion is safe, since the IDirectDrawSurface3 vtable has the
-     * IDirectDrawSurface vtable layout at the beginning  */
-    *ppSurf = pSurf7 ? (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)pSurf7)->IDirectDrawSurface3_vtbl : NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetGDISurface(LPDIRECTDRAW4 This,
-			       LPDIRECTDRAWSURFACE4 *ppSurf)
-{
-    return IDirectDraw7_GetGDISurface((IDirectDraw7 *)ddraw_from_ddraw4(This), (LPDIRECTDRAWSURFACE7 *)ppSurf);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetMonitorFrequency(LPDIRECTDRAW This, LPDWORD pdwFreq)
-{
-    return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw1(This), pdwFreq);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetMonitorFrequency(LPDIRECTDRAW2 This, LPDWORD pdwFreq)
-{
-    return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw2(This), pdwFreq);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetMonitorFrequency(LPDIRECTDRAW3 This, LPDWORD pdwFreq)
-{
-    return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw3(This), pdwFreq);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetMonitorFrequency(LPDIRECTDRAW4 This, LPDWORD pdwFreq)
-{
-    return IDirectDraw7_GetMonitorFrequency((IDirectDraw7 *)ddraw_from_ddraw4(This), pdwFreq);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetScanLine(LPDIRECTDRAW This, LPDWORD pdwLine)
-{
-    return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw1(This), pdwLine);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 This, LPDWORD pdwLine)
-{
-    return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw2(This), pdwLine);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetScanLine(LPDIRECTDRAW3 This, LPDWORD pdwLine)
-{
-    return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw3(This), pdwLine);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetScanLine(LPDIRECTDRAW4 This, LPDWORD pdwLine)
-{
-    return IDirectDraw7_GetScanLine((IDirectDraw7 *)ddraw_from_ddraw4(This), pdwLine);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_GetVerticalBlankStatus(LPDIRECTDRAW This, LPBOOL lpbIsInVB)
-{
-    return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw1(This), lpbIsInVB);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetVerticalBlankStatus(LPDIRECTDRAW2 This, LPBOOL lpbIsInVB)
-{
-    return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw2(This), lpbIsInVB);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetVerticalBlankStatus(LPDIRECTDRAW3 This, LPBOOL lpbIsInVB)
-{
-    return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw3(This), lpbIsInVB);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetVerticalBlankStatus(LPDIRECTDRAW4 This, LPBOOL lpbIsInVB)
-{
-    return IDirectDraw7_GetVerticalBlankStatus((IDirectDraw7 *)ddraw_from_ddraw4(This), lpbIsInVB);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_Initialize(LPDIRECTDRAW iface, LPGUID pGUID)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw1(iface);
-    HRESULT ret_value;
-
-    ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
-
-    return ret_value;
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, LPGUID pGUID)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw2(iface);
-    HRESULT ret_value;
-
-    ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
-
-    return ret_value;
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_Initialize(LPDIRECTDRAW3 iface, LPGUID pGUID)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw3(iface);
-    HRESULT ret_value;
-
-    ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
-
-    return ret_value;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_Initialize(LPDIRECTDRAW4 iface, LPGUID pGUID)
-{
-    IDirectDrawImpl *This = ddraw_from_ddraw4(iface);
-    HRESULT ret_value;
-
-    ret_value = IDirectDraw7_Initialize((IDirectDraw7 *)This, pGUID);
-
-    return ret_value;
-}
-
-
-static HRESULT WINAPI
-IDirectDrawImpl_RestoreDisplayMode(LPDIRECTDRAW This)
-{
-    return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 This)
-{
-    return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_RestoreDisplayMode(LPDIRECTDRAW3 This)
-{
-    return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_RestoreDisplayMode(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(This));
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_SetCooperativeLevel(LPDIRECTDRAW This, HWND hWnd,
-				    DWORD dwFlags)
-{
-    return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw1(This), hWnd, dwFlags);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_SetCooperativeLevel(LPDIRECTDRAW2 This, HWND hWnd,
-				     DWORD dwFlags)
-{
-    return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw2(This), hWnd, dwFlags);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_SetCooperativeLevel(LPDIRECTDRAW3 This, HWND hWnd,
-				     DWORD dwFlags)
-{
-    return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw3(This), hWnd, dwFlags);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_SetCooperativeLevel(LPDIRECTDRAW4 This, HWND hWnd,
-				     DWORD dwFlags)
-{
-    return IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw4(This), hWnd, dwFlags);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_SetDisplayMode(LPDIRECTDRAW This, DWORD a, DWORD b, DWORD c)
-{
-    return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw1(This), a, b, c, 0, 0);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_SetDisplayMode(LPDIRECTDRAW2 This, DWORD a, DWORD b, DWORD c,
-				DWORD d, DWORD e)
-{
-    return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw2(This), a, b, c, d, e);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_SetDisplayMode(LPDIRECTDRAW3 This, DWORD a, DWORD b, DWORD c,
-				DWORD d, DWORD e)
-{
-    return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw3(This), a, b, c, d, e);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_SetDisplayMode(LPDIRECTDRAW4 This, DWORD a, DWORD b, DWORD c,
-				DWORD d, DWORD e)
-{
-    return IDirectDraw7_SetDisplayMode((IDirectDraw7 *)ddraw_from_ddraw4(This), a, b, c, d, e);
-}
-
-static HRESULT WINAPI
-IDirectDrawImpl_WaitForVerticalBlank(LPDIRECTDRAW This, DWORD dwFlags,
-				     HANDLE hEvent)
-{
-    return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw1(This), dwFlags, hEvent);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_WaitForVerticalBlank(LPDIRECTDRAW2 This, DWORD dwFlags,
-				      HANDLE hEvent)
-{
-    return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw2(This), dwFlags, hEvent);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_WaitForVerticalBlank(LPDIRECTDRAW3 This, DWORD dwFlags,
-				      HANDLE hEvent)
-{
-    return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw3(This), dwFlags, hEvent);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_WaitForVerticalBlank(LPDIRECTDRAW4 This, DWORD dwFlags,
-				      HANDLE hEvent)
-{
-    return IDirectDraw7_WaitForVerticalBlank((IDirectDraw7 *)ddraw_from_ddraw4(This), dwFlags, hEvent);
-}
-
-static HRESULT WINAPI
-IDirectDraw2Impl_GetAvailableVidMem(LPDIRECTDRAW2 This, LPDDSCAPS pCaps,
-				    LPDWORD pdwTotal, LPDWORD pdwFree)
-{
-    DDSCAPS2 Caps2;
-    DDRAW_Convert_DDSCAPS_1_To_2(pCaps, &Caps2);
-
-    return IDirectDraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw2(This), &Caps2, pdwTotal, pdwFree);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetAvailableVidMem(LPDIRECTDRAW3 This, LPDDSCAPS pCaps,
-				    LPDWORD pdwTotal, LPDWORD pdwFree)
-{
-    DDSCAPS2 Caps2;
-    DDRAW_Convert_DDSCAPS_1_To_2(pCaps, &Caps2);
-
-    return IDirectDraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw3(This), &Caps2, pdwTotal, pdwFree);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetAvailableVidMem(LPDIRECTDRAW4 This, LPDDSCAPS2 pCaps,
-				    LPDWORD pdwTotal, LPDWORD pdwFree)
-{
-    return IDirectDraw7_GetAvailableVidMem((IDirectDraw7 *)ddraw_from_ddraw4(This), pCaps, pdwTotal, pdwFree);
-}
-
-static HRESULT WINAPI
-IDirectDraw3Impl_GetSurfaceFromDC(LPDIRECTDRAW3 This, HDC hDC,
-				  LPDIRECTDRAWSURFACE *pSurf)
-{
-    return IDirectDraw7_GetSurfaceFromDC((IDirectDraw7 *)ddraw_from_ddraw3(This), hDC, (LPDIRECTDRAWSURFACE7 *)pSurf);
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 This, HDC hDC,
-				  LPDIRECTDRAWSURFACE4 *pSurf)
-{
-    IDirectDrawSurface7 *surf7;
-    HRESULT hr;
-
-    if (!pSurf) return E_INVALIDARG;
-
-    hr = IDirectDraw7_GetSurfaceFromDC((IDirectDraw7 *)ddraw_from_ddraw4(This), hDC, &surf7);
-    *pSurf = surf7 ? (IDirectDrawSurface4 *)&((IDirectDrawSurfaceImpl *)surf7)->IDirectDrawSurface3_vtbl : NULL;
-
-    return hr;
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_RestoreAllSurfaces((IDirectDraw7 *)ddraw_from_ddraw4(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 This)
-{
-    return IDirectDraw7_TestCooperativeLevel((IDirectDraw7 *)ddraw_from_ddraw4(This));
-}
-
-static HRESULT WINAPI
-IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 This,
-				     LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags)
-{
-    DDDEVICEIDENTIFIER2 DDDI2;
-    HRESULT hr;
-
-    hr = IDirectDraw7_GetDeviceIdentifier((IDirectDraw7 *)ddraw_from_ddraw4(This), &DDDI2, dwFlags);
-
-    DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(&DDDI2, pDDDI);
-
-    return hr;
-}
-
-const IDirectDrawVtbl IDirectDraw1_Vtbl =
-{
-    IDirectDrawImpl_QueryInterface,
-    IDirectDrawImpl_AddRef,
-    IDirectDrawImpl_Release,
-    IDirectDrawImpl_Compact,
-    IDirectDrawImpl_CreateClipper,
-    IDirectDrawImpl_CreatePalette,
-    IDirectDrawImpl_CreateSurface,
-    IDirectDrawImpl_DuplicateSurface,
-    IDirectDrawImpl_EnumDisplayModes,
-    IDirectDrawImpl_EnumSurfaces,
-    IDirectDrawImpl_FlipToGDISurface,
-    IDirectDrawImpl_GetCaps,
-    IDirectDrawImpl_GetDisplayMode,
-    IDirectDrawImpl_GetFourCCCodes,
-    IDirectDrawImpl_GetGDISurface,
-    IDirectDrawImpl_GetMonitorFrequency,
-    IDirectDrawImpl_GetScanLine,
-    IDirectDrawImpl_GetVerticalBlankStatus,
-    IDirectDrawImpl_Initialize,
-    IDirectDrawImpl_RestoreDisplayMode,
-    IDirectDrawImpl_SetCooperativeLevel,
-    IDirectDrawImpl_SetDisplayMode,
-    IDirectDrawImpl_WaitForVerticalBlank,
-};
-
-const IDirectDraw2Vtbl IDirectDraw2_Vtbl =
-{
-    IDirectDraw2Impl_QueryInterface,
-    IDirectDraw2Impl_AddRef,
-    IDirectDraw2Impl_Release,
-    IDirectDraw2Impl_Compact,
-    IDirectDraw2Impl_CreateClipper,
-    IDirectDraw2Impl_CreatePalette,
-    IDirectDraw2Impl_CreateSurface,
-    IDirectDraw2Impl_DuplicateSurface,
-    IDirectDraw2Impl_EnumDisplayModes,
-    IDirectDraw2Impl_EnumSurfaces,
-    IDirectDraw2Impl_FlipToGDISurface,
-    IDirectDraw2Impl_GetCaps,
-    IDirectDraw2Impl_GetDisplayMode,
-    IDirectDraw2Impl_GetFourCCCodes,
-    IDirectDraw2Impl_GetGDISurface,
-    IDirectDraw2Impl_GetMonitorFrequency,
-    IDirectDraw2Impl_GetScanLine,
-    IDirectDraw2Impl_GetVerticalBlankStatus,
-    IDirectDraw2Impl_Initialize,
-    IDirectDraw2Impl_RestoreDisplayMode,
-    IDirectDraw2Impl_SetCooperativeLevel,
-    IDirectDraw2Impl_SetDisplayMode,
-    IDirectDraw2Impl_WaitForVerticalBlank,
-    IDirectDraw2Impl_GetAvailableVidMem
-};
-
-const IDirectDraw3Vtbl IDirectDraw3_Vtbl =
-{
-    IDirectDraw3Impl_QueryInterface,
-    IDirectDraw3Impl_AddRef,
-    IDirectDraw3Impl_Release,
-    IDirectDraw3Impl_Compact,
-    IDirectDraw3Impl_CreateClipper,
-    IDirectDraw3Impl_CreatePalette,
-    IDirectDraw3Impl_CreateSurface,
-    IDirectDraw3Impl_DuplicateSurface,
-    IDirectDraw3Impl_EnumDisplayModes,
-    IDirectDraw3Impl_EnumSurfaces,
-    IDirectDraw3Impl_FlipToGDISurface,
-    IDirectDraw3Impl_GetCaps,
-    IDirectDraw3Impl_GetDisplayMode,
-    IDirectDraw3Impl_GetFourCCCodes,
-    IDirectDraw3Impl_GetGDISurface,
-    IDirectDraw3Impl_GetMonitorFrequency,
-    IDirectDraw3Impl_GetScanLine,
-    IDirectDraw3Impl_GetVerticalBlankStatus,
-    IDirectDraw3Impl_Initialize,
-    IDirectDraw3Impl_RestoreDisplayMode,
-    IDirectDraw3Impl_SetCooperativeLevel,
-    IDirectDraw3Impl_SetDisplayMode,
-    IDirectDraw3Impl_WaitForVerticalBlank,
-    IDirectDraw3Impl_GetAvailableVidMem,
-    IDirectDraw3Impl_GetSurfaceFromDC,
-};
-
-const IDirectDraw4Vtbl IDirectDraw4_Vtbl =
-{
-    IDirectDraw4Impl_QueryInterface,
-    IDirectDraw4Impl_AddRef,
-    IDirectDraw4Impl_Release,
-    IDirectDraw4Impl_Compact,
-    IDirectDraw4Impl_CreateClipper,
-    IDirectDraw4Impl_CreatePalette,
-    IDirectDraw4Impl_CreateSurface,
-    IDirectDraw4Impl_DuplicateSurface,
-    IDirectDraw4Impl_EnumDisplayModes,
-    IDirectDraw4Impl_EnumSurfaces,
-    IDirectDraw4Impl_FlipToGDISurface,
-    IDirectDraw4Impl_GetCaps,
-    IDirectDraw4Impl_GetDisplayMode,
-    IDirectDraw4Impl_GetFourCCCodes,
-    IDirectDraw4Impl_GetGDISurface,
-    IDirectDraw4Impl_GetMonitorFrequency,
-    IDirectDraw4Impl_GetScanLine,
-    IDirectDraw4Impl_GetVerticalBlankStatus,
-    IDirectDraw4Impl_Initialize,
-    IDirectDraw4Impl_RestoreDisplayMode,
-    IDirectDraw4Impl_SetCooperativeLevel,
-    IDirectDraw4Impl_SetDisplayMode,
-    IDirectDraw4Impl_WaitForVerticalBlank,
-    IDirectDraw4Impl_GetAvailableVidMem,
-    IDirectDraw4Impl_GetSurfaceFromDC,
-    IDirectDraw4Impl_RestoreAllSurfaces,
-    IDirectDraw4Impl_TestCooperativeLevel,
-    IDirectDraw4Impl_GetDeviceIdentifier
-};
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 6b00d4f..f120bf3 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -3553,8 +3553,7 @@ IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
 
     /* Set the FVF */
     EnterCriticalSection(&ddraw_cs);
-    hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
-                                             IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
+    hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, ddraw_find_decl(This->ddraw, VertexType));
     if(hr != D3D_OK)
     {
         LeaveCriticalSection(&ddraw_cs);
@@ -3676,8 +3675,7 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
 
     /* Set the D3DDevice's FVF */
     EnterCriticalSection(&ddraw_cs);
-    hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
-                                             IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
+    hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, ddraw_find_decl(This->ddraw, VertexType));
     if(FAILED(hr))
     {
         ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c
index 15c30a5..a95965e 100644
--- a/dlls/ddraw/direct3d.c
+++ b/dlls/ddraw/direct3d.c
@@ -1036,9 +1036,8 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface,
             return hr;
     }
 
-    object->wineD3DVertexDeclaration = IDirectDrawImpl_FindDecl(This,
-                                                                Desc->dwFVF);
-    if(!object->wineD3DVertexDeclaration)
+    object->wineD3DVertexDeclaration = ddraw_find_decl(This, Desc->dwFVF);
+    if (!object->wineD3DVertexDeclaration)
     {
         ERR("Cannot find the vertex declaration for fvf %08x\n", Desc->dwFVF);
         IWineD3DBuffer_Release(object->wineD3DVertexBuffer);
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index e8372ba..e92ec70 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -1750,9 +1750,7 @@ IDirectDrawSurfaceImpl_Restore(IDirectDrawSurface7 *iface)
     {
         /* Call the recreation callback. Make sure to AddRef first */
         IDirectDrawSurface_AddRef(iface);
-        IDirectDrawImpl_RecreateSurfacesCallback(iface,
-                                                 &This->surface_desc,
-                                                 NULL /* Not needed */);
+        ddraw_recreate_surfaces_cb(iface, &This->surface_desc, NULL /* Not needed */);
     }
     hr = IWineD3DSurface_Restore(This->WineD3DSurface);
     LeaveCriticalSection(&ddraw_cs);
-- 
1.7.1




More information about the wine-patches mailing list