/*
 * Copyright 2008 Stefan Dösinger for CodeWeavers
 *
 * 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
 */

#define COBJMACROS
#define NONAMELESSUNION

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"

#include "ddraw.h"
#include "d3d.h"

#include "ddrawex_private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);

/******************************************************************************
 * Helper functions for COM management
 ******************************************************************************/
static IDirectDrawImpl *impl_from_dd1(IDirectDraw *iface)
{
    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw_Vtbl));
}
static IDirectDraw *dd1_from_impl(IDirectDrawImpl *This)
{
    return (IDirectDraw *) &This->IDirectDraw_Vtbl;
}

static IDirectDrawImpl *impl_from_dd2(IDirectDraw2 *iface)
{
    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw2_Vtbl));
}
static IDirectDraw2 *dd2_from_impl(IDirectDrawImpl *This)
{
    return (IDirectDraw2 *) &This->IDirectDraw2_Vtbl;
}

static IDirectDrawImpl *impl_from_dd3(IDirectDraw3 *iface)
{
    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw3_Vtbl));
}
static IDirectDraw3 *dd3_from_impl(IDirectDrawImpl *This)
{
    return (IDirectDraw3 *) &This->IDirectDraw3_Vtbl;
}

static IDirectDrawImpl *impl_from_dd4(IDirectDraw4 *iface)
{
    return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw4_Vtbl));
}
static IDirectDraw4 *dd4_from_impl(IDirectDrawImpl *This)
{
    return (IDirectDraw4 *) &This->IDirectDraw4_Vtbl;
}

/******************************************************************************
 * IDirectDraw4 -> ddraw.dll wrappers
 ******************************************************************************/
static HRESULT WINAPI
IDirectDraw4Impl_QueryInterface(IDirectDraw4 *iface,
                                REFIID refiid,
                                void **obj)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);

    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
    *obj = NULL;

    if(!refiid)
    {
        return DDERR_INVALIDPARAMS;
    }

    if (IsEqualGUID( &IID_IDirectDraw7, refiid ) )
    {
        WARN("IDirectDraw7 not allowed in ddrawex.dll\n");
        return E_NOINTERFACE;
    }
    else if ( IsEqualGUID( &IID_IUnknown, refiid ) ||
              IsEqualGUID( &IID_IDirectDraw4, refiid ) )
    {
        *obj = dd4_from_impl(This);
        TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
        IDirectDraw4_AddRef((IDirectDraw4 *) *obj);
    }
    else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) )
    {
        *obj = dd3_from_impl(This);
        TRACE("(%p) Returning IDirectDraw3 interface at %p\n", This, *obj);
        IDirectDraw3_AddRef((IDirectDraw3 *) *obj);
    }
    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
    {
        *obj = dd2_from_impl(This);
        TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
        IDirectDraw2_AddRef((IDirectDraw2 *) *obj);
    }
    else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
    {
        *obj = dd1_from_impl(This);
        TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
        IDirectDraw_AddRef((IDirectDraw *) *obj);
    }
    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
              IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
              IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
              IsEqualGUID( &IID_IDirect3D7 , refiid ) )
    {
        WARN("Direct3D not allowed in ddrawex.dll\n");
        return E_NOINTERFACE;
    }
    /* Unknown interface */
    else
    {
        ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
        return E_NOINTERFACE;
    }
    TRACE("Returning S_OK\n");
    return S_OK;
}

static HRESULT WINAPI
IDirectDraw3Impl_QueryInterface(IDirectDraw3 *iface,
                                REFIID refiid,
                                void **obj)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
}

static HRESULT WINAPI
IDirectDraw2Impl_QueryInterface(IDirectDraw2 *iface,
                                REFIID refiid,
                                void **obj)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
}

static HRESULT WINAPI
IDirectDrawImpl_QueryInterface(IDirectDraw *iface,
                               REFIID refiid,
                               void **obj)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
}

static ULONG WINAPI
IDirectDraw4Impl_AddRef(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) : incrementing refcount from %u.\n", This, ref - 1);

    return ref;
}

static ULONG WINAPI
IDirectDraw3Impl_AddRef(IDirectDraw3 *iface)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_AddRef(dd4_from_impl(This));
}

static ULONG WINAPI
IDirectDraw2Impl_AddRef(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_AddRef(dd4_from_impl(This));
}

static ULONG WINAPI
IDirectDrawImpl_AddRef(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_AddRef(dd4_from_impl(This));
}

static ULONG WINAPI
IDirectDraw4Impl_Release(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) : decrementing refcount to %u.\n", This, ref);

    if(ref == 0)
    {
        TRACE("Destroying object\n");
        IDirectDraw4_Release(This->parent);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

static ULONG WINAPI
IDirectDraw3Impl_Release(IDirectDraw3 *iface)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Release(dd4_from_impl(This));
}

static ULONG WINAPI
IDirectDraw2Impl_Release(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Release(dd4_from_impl(This));
}

static ULONG WINAPI
IDirectDrawImpl_Release(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Release(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDraw4Impl_Compact(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)\n", This);

    return IDirectDraw4_Compact(This->parent);
}

static HRESULT WINAPI
IDirectDraw3Impl_Compact(IDirectDraw3 *iface)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Compact(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDraw2Impl_Compact(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Compact(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDrawImpl_Compact(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Compact(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDraw4Impl_CreateClipper(IDirectDraw4 *iface,
                               DWORD Flags,
                               IDirectDrawClipper **clipper,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(0x%08x, %p, %p)\n", This, Flags, clipper, UnkOuter);

    if(UnkOuter != NULL)
    {
        /* This may require a wrapper interface for clippers too which handles this */
        FIXME("Test and implement Aggregation for ddrawex clippers\n");
    }

    return IDirectDraw4_CreateClipper(This->parent, Flags, clipper, UnkOuter);
}

static HRESULT WINAPI
IDirectDraw3Impl_CreateClipper(IDirectDraw3 *iface,
                               DWORD Flags,
                               IDirectDrawClipper **clipper,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
}

static HRESULT WINAPI
IDirectDraw2Impl_CreateClipper(IDirectDraw2 *iface,
                               DWORD Flags,
                               IDirectDrawClipper **clipper,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
}

static HRESULT WINAPI
IDirectDrawImpl_CreateClipper(IDirectDraw *iface,
                              DWORD Flags,
                              IDirectDrawClipper **clipper,
                              IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
}

static HRESULT WINAPI
IDirectDraw4Impl_CreatePalette(IDirectDraw4 *iface,
                               DWORD Flags,
                               PALETTEENTRY *ColorTable,
                               IDirectDrawPalette **Palette,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)(0x%08x,%p,%p,%p)\n", This, Flags, ColorTable, Palette, UnkOuter);

    if(UnkOuter != NULL)
    {
        /* This may require a wrapper interface for palettes too which handles this */
        FIXME("Test and implement Aggregation for ddrawex palettes\n");
    }

    return IDirectDraw4_CreatePalette(This->parent, Flags, ColorTable, Palette, UnkOuter);
}

static HRESULT WINAPI
IDirectDraw3Impl_CreatePalette(IDirectDraw3 *iface,
                               DWORD Flags,
                               PALETTEENTRY *ColorTable,
                               IDirectDrawPalette **Palette,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
}

static HRESULT WINAPI
IDirectDraw2Impl_CreatePalette(IDirectDraw2 *iface,
                               DWORD Flags,
                               PALETTEENTRY *ColorTable,
                               IDirectDrawPalette **Palette,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
}

static HRESULT WINAPI
IDirectDrawImpl_CreatePalette(IDirectDraw *iface,
                              DWORD Flags,
                              PALETTEENTRY *ColorTable,
                              IDirectDrawPalette **Palette,
                              IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
}

static HRESULT WINAPI
IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface,
                               DDSURFACEDESC2 *DDSD,
                               IDirectDrawSurface4 **Surf,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    HRESULT hr;
    const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
    BOOL permanent_dc;
    TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter);

    if(UnkOuter != NULL)
    {
        /* Handle this in this dll. Don't forward the UnkOuter to ddraw.dll */
        FIXME("Implement aggregation for ddrawex surfaces\n");
    }

    /* plain ddraw.dll refuses to create a surface that has both VIDMEM and SYSMEM flags
     * set. In ddrawex this succeeds, and the GetDC() call changes the behavior. The DC
     * is permanently valid, and the surface can be locked between GetDC() and ReleaseDC()
     * calls. GetDC() can be called more than once too
     */
    if((DDSD->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags)
    {
        permanent_dc = TRUE;
        DDSD->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
        DDSD->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
    }
    else
    {
        permanent_dc = FALSE;
    }

    hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter);
    *Surf = dds_get_outer(*Surf);
    if(permanent_dc) prepare_permanent_dc(*Surf);
    return hr;
}

void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
{
    memset(out, 0, sizeof(*out));
    out->dwSize = sizeof(*out);
    out->dwFlags = in->dwFlags;
    if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
    if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
    if(in->dwFlags & DDSD_PIXELFORMAT) out->u4.ddpfPixelFormat = in->ddpfPixelFormat;
    if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
    if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
    if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
    if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwMipMapCount = in->u2.dwZBufferBitDepth; /* same union */
    if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
    /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
    out->lpSurface = in->lpSurface;
    if(in->dwFlags & DDSD_CKDESTOVERLAY) out->u3.ddckCKDestOverlay = in->ddckCKDestOverlay;
    if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
    if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
    if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
    if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
    if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
    if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
    /* Does not exist in DDSURFACEDESC:
     * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
     */
}

void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
{
    memset(out, 0, sizeof(*out));
    out->dwSize = sizeof(*out);
    out->dwFlags = in->dwFlags;
    if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
    if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
    if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->u4.ddpfPixelFormat;
    if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
    if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
    if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
    if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwZBufferBitDepth = in->u2.dwMipMapCount; /* same union */
    if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
    /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
    out->lpSurface = in->lpSurface;
    if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->u3.ddckCKDestOverlay;
    if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
    if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
    if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
    if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
    if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
    if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
    /* Does not exist in DDSURFACEDESC:
     * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
     */
    if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n");
    if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n");
    if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n");
    out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE);
}

static HRESULT WINAPI
IDirectDraw3Impl_CreateSurface(IDirectDraw3 *iface,
                               DDSURFACEDESC *DDSD,
                               IDirectDrawSurface **Surf,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    DDSURFACEDESC2 ddsd2;
    IDirectDrawSurface4 *surf4 = NULL;
    HRESULT hr;
    TRACE("Thunking to IDirectDraw4\n");

    DDSD_to_DDSD2(DDSD, &ddsd2);

    hr = IDirectDraw4_CreateSurface(dd4_from_impl(This), &ddsd2, &surf4, UnkOuter);
    if(FAILED(hr))
    {
        *Surf = NULL;
        return hr;
    }

    TRACE("Got surface %p\n", surf4);
    IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf);
    IDirectDrawSurface4_Release(surf4);
    return hr;
}

static HRESULT WINAPI
IDirectDraw2Impl_CreateSurface(IDirectDraw2 *iface,
                               DDSURFACEDESC *DDSD,
                               IDirectDrawSurface **Surf,
                               IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw3\n");
    return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter);
}

static HRESULT WINAPI
IDirectDrawImpl_CreateSurface(IDirectDraw *iface,
                              DDSURFACEDESC *DDSD,
                              IDirectDrawSurface **Surf,
                              IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw3\n");
    return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter);
}

static HRESULT WINAPI
IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface,
                                  IDirectDrawSurface4 *src,
                                  IDirectDrawSurface4 **dst)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst);

    return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(src), dst);
}

static HRESULT WINAPI
IDirectDraw3Impl_DuplicateSurface(IDirectDraw3 *iface,
                                  IDirectDrawSurface *src,
                                  IDirectDrawSurface **dst)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    IDirectDrawSurface4 *src_4;
    IDirectDrawSurface4 *dst_4;
    HRESULT hr;

    TRACE("Thunking to IDirectDraw4\n");
    IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **) &src_4);
    hr = IDirectDraw4_DuplicateSurface(dd4_from_impl(This), src_4, &dst_4);
    IDirectDrawSurface4_Release(src_4);

    if(FAILED(hr))
    {
        *dst = NULL;
        return hr;
    }
    IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **) dst);
    IDirectDrawSurface4_Release(dst_4);
    return hr;
}

static HRESULT WINAPI
IDirectDraw2Impl_DuplicateSurface(IDirectDraw2 *iface,
                                  IDirectDrawSurface *src,
                                  IDirectDrawSurface **dst)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("Thunking to IDirectDraw3\n");
    return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst);
}

static HRESULT WINAPI
IDirectDrawImpl_DuplicateSurface(IDirectDraw *iface,
                                 IDirectDrawSurface *src,
                                 IDirectDrawSurface **dst)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("Thunking to IDirectDraw3\n");
    return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst);
}

static HRESULT WINAPI
IDirectDraw4Impl_EnumDisplayModes(IDirectDraw4 *iface,
                                  DWORD Flags,
                                  DDSURFACEDESC2 *DDSD,
                                  void *Context,
                                  LPDDENUMMODESCALLBACK2 cb)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, cb);

    return IDirectDraw4_EnumDisplayModes(This->parent, Flags, DDSD, Context, cb);
}

struct enummodes_ctx
{
    LPDDENUMMODESCALLBACK orig_cb;
    void *orig_ctx;
};

static HRESULT WINAPI
enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx)
{
    struct enummodes_ctx *ctx = vctx;
    DDSURFACEDESC ddsd;

    DDSD2_to_DDSD(ddsd2, &ddsd);
    return ctx->orig_cb(&ddsd, ctx->orig_ctx);
}

static HRESULT WINAPI
IDirectDraw3Impl_EnumDisplayModes(IDirectDraw3 *iface,
                                  DWORD Flags,
                                  DDSURFACEDESC *DDSD,
                                  void *Context,
                                  LPDDENUMMODESCALLBACK cb)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    DDSURFACEDESC2 ddsd2;
    struct enummodes_ctx ctx;
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, cb);

    DDSD_to_DDSD2(DDSD, &ddsd2);
    ctx.orig_cb = cb;
    ctx.orig_ctx = Context;
    return IDirectDraw4_EnumDisplayModes(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_modes_cb2);
}

static HRESULT WINAPI
IDirectDraw2Impl_EnumDisplayModes(IDirectDraw2 *iface,
                                  DWORD Flags,
                                  DDSURFACEDESC *DDSD,
                                  void *Context,
                                  LPDDENUMMODESCALLBACK cb)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
    return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb);
}

static HRESULT WINAPI
IDirectDrawImpl_EnumDisplayModes(IDirectDraw *iface,
                                 DWORD Flags,
                                 DDSURFACEDESC *DDSD,
                                 void *Context,
                                 LPDDENUMMODESCALLBACK cb)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
    return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb);
}

struct enumsurfaces4_ctx
{
    LPDDENUMSURFACESCALLBACK2 orig_cb;
    void *orig_ctx;
};

static HRESULT WINAPI
enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
{
    struct enumsurfaces4_ctx *ctx = vctx;
    IDirectDrawSurface4 *outer = dds_get_outer(surf4);
    IDirectDrawSurface4_AddRef(outer);
    IDirectDrawSurface4_Release(surf4);
    TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4);
    return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx);
}

static HRESULT WINAPI
IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface,
                              DWORD Flags,
                              DDSURFACEDESC2 *DDSD,
                              void *Context,
                              LPDDENUMSURFACESCALLBACK2 Callback)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    struct enumsurfaces4_ctx ctx;
    TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback);

    ctx.orig_cb = Callback;
    ctx.orig_ctx = Context;
    return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, &ctx, enum_surfaces_wrapper);
}

struct enumsurfaces_ctx
{
    LPDDENUMSURFACESCALLBACK orig_cb;
    void *orig_ctx;
};

static HRESULT WINAPI
enum_surfaces_cb2(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
{
    struct enumsurfaces_ctx *ctx = vctx;
    IDirectDrawSurface *surf1;
    DDSURFACEDESC ddsd;

    /* Keep the reference, it goes to the application */
    IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) &surf1);
    /* Release the reference this function got */
    IDirectDrawSurface4_Release(surf4);

    DDSD2_to_DDSD(ddsd2, &ddsd);
    return ctx->orig_cb(surf1, &ddsd, ctx->orig_ctx);
}

static HRESULT WINAPI
IDirectDraw3Impl_EnumSurfaces(IDirectDraw3 *iface,
                              DWORD Flags,
                              DDSURFACEDESC *DDSD,
                              void *Context,
                              LPDDENUMSURFACESCALLBACK Callback)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    DDSURFACEDESC2 ddsd2;
    struct enumsurfaces_ctx ctx;
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, Callback);

    DDSD_to_DDSD2(DDSD, &ddsd2);
    ctx.orig_cb = Callback;
    ctx.orig_ctx = Context;
    return IDirectDraw4_EnumSurfaces(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_surfaces_cb2);
}

static HRESULT WINAPI
IDirectDraw2Impl_EnumSurfaces(IDirectDraw2 *iface,
                              DWORD Flags,
                              DDSURFACEDESC *DDSD,
                              void *Context,
                              LPDDENUMSURFACESCALLBACK Callback)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
    return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback);
}

static HRESULT WINAPI
IDirectDrawImpl_EnumSurfaces(IDirectDraw *iface,
                             DWORD Flags,
                             DDSURFACEDESC *DDSD,
                             void *Context,
                             LPDDENUMSURFACESCALLBACK Callback)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
    return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback);
}

static HRESULT WINAPI
IDirectDraw4Impl_FlipToGDISurface(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)\n", This);

    return IDirectDraw4_FlipToGDISurface(This->parent);
}

static HRESULT WINAPI
IDirectDraw3Impl_FlipToGDISurface(IDirectDraw3 *iface)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p). Thunking to IDirectDraw4\n", This);
    return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDraw2Impl_FlipToGDISurface(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p). Thunking to IDirectDraw4\n", This);
    return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDrawImpl_FlipToGDISurface(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p). Thunking to IDirectDraw4\n", This);
    return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDraw4Impl_GetCaps(IDirectDraw4 *iface,
                         DDCAPS *DriverCaps,
                         DDCAPS *HELCaps)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps);
    return IDirectDraw4_GetCaps(This->parent, DriverCaps, HELCaps);
}

static HRESULT WINAPI
IDirectDraw3Impl_GetCaps(IDirectDraw3 *iface,
                         DDCAPS *DriverCaps,
                         DDCAPS *HELCaps)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
    return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
}

static HRESULT WINAPI
IDirectDraw2Impl_GetCaps(IDirectDraw2 *iface,
                         DDCAPS *DriverCaps,
                         DDCAPS *HELCaps)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
    return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
}

static HRESULT WINAPI
IDirectDrawImpl_GetCaps(IDirectDraw *iface,
                        DDCAPS *DriverCaps,
                        DDCAPS *HELCaps)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
    return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetDisplayMode(IDirectDraw4 *iface,
                                DDSURFACEDESC2 *DDSD)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p)\n", This, DDSD);
    return IDirectDraw4_GetDisplayMode(This->parent, DDSD);
}

static HRESULT WINAPI
IDirectDraw3Impl_GetDisplayMode(IDirectDraw3 *iface,
                                DDSURFACEDESC *DDSD)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    DDSURFACEDESC2 ddsd2;
    HRESULT hr;

    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, DDSD);
    hr = IDirectDraw4_GetDisplayMode(dd4_from_impl(This), &ddsd2);
    DDSD2_to_DDSD(&ddsd2, DDSD);
    return hr;
}

static HRESULT WINAPI
IDirectDraw2Impl_GetDisplayMode(IDirectDraw2 *iface,
                                DDSURFACEDESC *DDSD)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
    return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD);
}

static HRESULT WINAPI
IDirectDrawImpl_GetDisplayMode(IDirectDraw *iface,
                               DDSURFACEDESC *DDSD)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
    return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetFourCCCodes(IDirectDraw4 *iface,
                                DWORD *NumCodes,
                                DWORD *Codes)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p, %p):\n", This, NumCodes, Codes);
    return IDirectDraw4_GetFourCCCodes(This->parent, NumCodes, Codes);
}

static HRESULT WINAPI
IDirectDraw3Impl_GetFourCCCodes(IDirectDraw3 *iface,
                                DWORD *NumCodes,
                                DWORD *Codes)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
    return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
}

static HRESULT WINAPI
IDirectDraw2Impl_GetFourCCCodes(IDirectDraw2 *iface,
                                DWORD *NumCodes,
                                DWORD *Codes)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
    return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
}

static HRESULT WINAPI
IDirectDrawImpl_GetFourCCCodes(IDirectDraw *iface,
                               DWORD *NumCodes,
                               DWORD *Codes)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
    return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface,
                               IDirectDrawSurface4 **GDISurface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    IDirectDrawSurface4 *inner = NULL;
    HRESULT hr;
    TRACE("(%p)->(%p)\n", This, GDISurface);

    hr = IDirectDraw4_GetGDISurface(This->parent, &inner);
    if(SUCCEEDED(hr))
    {
        *GDISurface = dds_get_outer(inner);
        IDirectDrawSurface4_AddRef(*GDISurface);
        IDirectDrawSurface4_Release(inner);
    }
    else
    {
        *GDISurface = NULL;
    }
    return hr;
}

static HRESULT WINAPI
IDirectDraw3Impl_GetGDISurface(IDirectDraw3 *iface,
                               IDirectDrawSurface **GDISurface)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    IDirectDrawSurface4 *surf4;
    HRESULT hr;
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, GDISurface);

    hr = IDirectDraw4_GetGDISurface(dd4_from_impl(This), &surf4);
    if(FAILED(hr)) {
        *GDISurface = NULL;
        return hr;
    }

    /* Release the reference we got from the DDraw4 call, and pass a reference to the caller */
    IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) GDISurface);
    IDirectDrawSurface4_Release(surf4);
    return hr;
}

static HRESULT WINAPI
IDirectDraw2Impl_GetGDISurface(IDirectDraw2 *iface,
                               IDirectDrawSurface **GDISurface)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
    return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface);
}

static HRESULT WINAPI
IDirectDrawImpl_GetGDISurface(IDirectDraw *iface,
                              IDirectDrawSurface **GDISurface)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
    return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetMonitorFrequency(IDirectDraw4 *iface,
                                     DWORD *Freq)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p)\n", This, Freq);
    return IDirectDraw4_GetMonitorFrequency(This->parent, Freq);
}

static HRESULT WINAPI
IDirectDraw3Impl_GetMonitorFrequency(IDirectDraw3 *iface,
                                     DWORD *Freq)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
    return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
}

static HRESULT WINAPI
IDirectDraw2Impl_GetMonitorFrequency(IDirectDraw2 *iface,
                                     DWORD *Freq)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
    return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
}

static HRESULT WINAPI
IDirectDrawImpl_GetMonitorFrequency(IDirectDraw *iface,
                                    DWORD *Freq)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
    return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetScanLine(IDirectDraw4 *iface,
                             DWORD *Scanline)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p)\n", This, Scanline);
    return IDirectDraw4_GetScanLine(This->parent, Scanline);
}

static HRESULT WINAPI
IDirectDraw3Impl_GetScanLine(IDirectDraw3 *iface,
                             DWORD *Scanline)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
    return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
}

static HRESULT WINAPI
IDirectDraw2Impl_GetScanLine(IDirectDraw2 *iface,
                             DWORD *Scanline)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
    return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
}

static HRESULT WINAPI
IDirectDrawImpl_GetScanLine(IDirectDraw *iface,
                            DWORD *Scanline)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
    return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetVerticalBlankStatus(IDirectDraw4 *iface,
                                        BOOL *status)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p)\n", This, status);
    return IDirectDraw4_GetVerticalBlankStatus(This->parent, status);
}

static HRESULT WINAPI
IDirectDraw3Impl_GetVerticalBlankStatus(IDirectDraw3 *iface,
                                        BOOL *status)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
    return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
}

static HRESULT WINAPI
IDirectDraw2Impl_GetVerticalBlankStatus(IDirectDraw2 *iface,
                                        BOOL *status)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
    return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
}

static HRESULT WINAPI
IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw *iface,
                                       BOOL *status)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
    return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
}

static HRESULT WINAPI
IDirectDraw4Impl_Initialize(IDirectDraw4 *iface,
                            GUID *Guid)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_guid(Guid));
    return IDirectDraw4_Initialize(This->parent, Guid);
}

static HRESULT WINAPI
IDirectDraw3Impl_Initialize(IDirectDraw3 *iface,
                            GUID *Guid)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
    return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
}

static HRESULT WINAPI
IDirectDraw2Impl_Initialize(IDirectDraw2 *iface,
                            GUID *Guid)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
    return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
}

static HRESULT WINAPI
IDirectDrawImpl_Initialize(IDirectDraw *iface,
                           GUID *Guid)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
    return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
}

static HRESULT WINAPI
IDirectDraw4Impl_RestoreDisplayMode(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)\n", This);
    return IDirectDraw4_RestoreDisplayMode(This->parent);
}

static HRESULT WINAPI
IDirectDraw3Impl_RestoreDisplayMode(IDirectDraw3 *iface)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p): Thunking to IDirectDraw4\n", This);
    return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDraw2Impl_RestoreDisplayMode(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p): Thunking to IDirectDraw4\n", This);
    return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDrawImpl_RestoreDisplayMode(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p): Thunking to IDirectDraw4\n", This);
    return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
}

static HRESULT WINAPI
IDirectDraw4Impl_SetCooperativeLevel(IDirectDraw4 *iface,
                                     HWND hwnd,
                                     DWORD cooplevel)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p, 0x%08x)\n", This, hwnd, cooplevel);
    return IDirectDraw4_SetCooperativeLevel(This->parent, hwnd, cooplevel);
}

static HRESULT WINAPI
IDirectDraw3Impl_SetCooperativeLevel(IDirectDraw3 *iface,
                                     HWND hwnd,
                                     DWORD cooplevel)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
    return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
}

static HRESULT WINAPI
IDirectDraw2Impl_SetCooperativeLevel(IDirectDraw2 *iface,
                                     HWND hwnd,
                                     DWORD cooplevel)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
    return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
}

static HRESULT WINAPI
IDirectDrawImpl_SetCooperativeLevel(IDirectDraw *iface,
                                    HWND hwnd,
                                    DWORD cooplevel)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
    return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
}

static HRESULT WINAPI
IDirectDraw4Impl_SetDisplayMode(IDirectDraw4 *iface,
                                DWORD Width,
                                DWORD Height,
                                DWORD BPP,
                                DWORD RefreshRate,
                                DWORD Flags)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%u, %u, %u, %u, 0x%08x)\n", This, Width, Height, BPP, RefreshRate, Flags);
    return IDirectDraw4_SetDisplayMode(This->parent, Width, Height, BPP, RefreshRate, Flags);
}

static HRESULT WINAPI
IDirectDraw3Impl_SetDisplayMode(IDirectDraw3 *iface,
                                DWORD Width,
                                DWORD Height,
                                DWORD BPP,
                                DWORD RefreshRate,
                                DWORD Flags)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
    return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
}

static HRESULT WINAPI
IDirectDraw2Impl_SetDisplayMode(IDirectDraw2 *iface,
                                DWORD Width,
                                DWORD Height,
                                DWORD BPP,
                                DWORD RefreshRate,
                                DWORD Flags)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
    return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
}

static HRESULT WINAPI
IDirectDrawImpl_SetDisplayMode(IDirectDraw *iface,
                               DWORD Width,
                               DWORD Height,
                               DWORD BPP)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(%u, %u, %u): Thunking to IDirectDraw4\n", This, Width, Height, BPP);
    return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, 0, 0);
}

static HRESULT WINAPI
IDirectDraw4Impl_WaitForVerticalBlank(IDirectDraw4 *iface,
                                      DWORD Flags,
                                      HANDLE h)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(0x%08x, %p)\n", This, Flags, h);
    return IDirectDraw4_WaitForVerticalBlank(This->parent, Flags, h);
}

static HRESULT WINAPI
IDirectDraw3Impl_WaitForVerticalBlank(IDirectDraw3 *iface,
                                      DWORD Flags,
                                      HANDLE h)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
    return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
}

static HRESULT WINAPI
IDirectDraw2Impl_WaitForVerticalBlank(IDirectDraw2 *iface,
                                      DWORD Flags,
                                      HANDLE h)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
    return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
}

static HRESULT WINAPI
IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw *iface,
                                     DWORD Flags,
                                     HANDLE h)
{
    IDirectDrawImpl *This = impl_from_dd1(iface);
    TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
    return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetAvailableVidMem(IDirectDraw4 *iface,
                                    DDSCAPS2 *Caps,
                                    DWORD *total,
                                    DWORD *free)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
    return IDirectDraw4_GetAvailableVidMem(This->parent, Caps, total, free);
}

static HRESULT WINAPI
IDirectDraw3Impl_GetAvailableVidMem(IDirectDraw3 *iface,
                                    DDSCAPS *Caps,
                                    DWORD *total,
                                    DWORD *free)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    DDSCAPS2 caps2;
    TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
    memset(&caps2, 0, sizeof(caps2));
    caps2.dwCaps = Caps->dwCaps;
    return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
}

static HRESULT WINAPI
IDirectDraw2Impl_GetAvailableVidMem(IDirectDraw2 *iface,
                                    DDSCAPS *Caps,
                                    DWORD *total,
                                    DWORD *free)
{
    IDirectDrawImpl *This = impl_from_dd2(iface);
    DDSCAPS2 caps2;
    TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
    memset(&caps2, 0, sizeof(caps2));
    caps2.dwCaps = Caps->dwCaps;
    return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetSurfaceFromDC(IDirectDraw4 *iface,
                                  HDC hdc,
                                  IDirectDrawSurface4 **Surface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    HRESULT hr;
    TRACE("(%p)->(%p, %p)\n", This, hdc, Surface);
    hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, Surface);

    return hr;
}

static HRESULT WINAPI
IDirectDraw3Impl_GetSurfaceFromDC(IDirectDraw3 *iface,
                                  HDC hdc,
                                  IDirectDrawSurface **Surface)
{
    IDirectDrawImpl *This = impl_from_dd3(iface);
    IDirectDrawSurface4 *surf4, *outer;
    IDirectDrawSurface *inner;
    HRESULT hr;
    TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, hdc, Surface);

    if (!Surface) return E_POINTER;

    hr = IDirectDraw4_GetSurfaceFromDC(This->parent, hdc, (IDirectDrawSurface4 **)&inner);
    if(FAILED(hr))
    {
        *Surface = NULL;
        return hr;
    }

    hr = IDirectDrawSurface_QueryInterface(inner, &IID_IDirectDrawSurface4, (void **)&surf4);
    IDirectDrawSurface_Release(inner);
    if (FAILED(hr))
    {
        *Surface = NULL;
        return hr;
    }

    outer = dds_get_outer(surf4);
    hr = IDirectDrawSurface4_QueryInterface(outer, &IID_IDirectDrawSurface, (void **)Surface);
    IDirectDrawSurface4_Release(surf4);
    return hr;
}

static HRESULT WINAPI
IDirectDraw4Impl_RestoreAllSurfaces(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)\n", This);
    return IDirectDraw4_RestoreAllSurfaces(This->parent);
}

static HRESULT WINAPI
IDirectDraw4Impl_TestCooperativeLevel(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)\n", This);
    return IDirectDraw4_TestCooperativeLevel(This->parent);
}

static HRESULT WINAPI
IDirectDraw4Impl_GetDeviceIdentifier(IDirectDraw4 *iface,
                                     DDDEVICEIDENTIFIER *DDDI,
                                     DWORD Flags)
{
    IDirectDrawImpl *This = impl_from_dd4(iface);
    TRACE("(%p)->(%p,0x%08x)\n", This, DDDI, Flags);
    return IDirectDraw4_GetDeviceIdentifier(This->parent, DDDI, Flags);
}

static 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,
};

static 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
};

static 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,
};

static 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
};

/*******************************************************************************
 * IDirectDrawFactoryImpl_CreateDirectDraw
 *******************************************************************************/
HRESULT WINAPI
IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface,
                                        GUID * pGUID,
                                        HWND hWnd,
                                        DWORD dwCoopLevelFlags,
                                        DWORD dwReserved,
                                        IUnknown *pUnkOuter,
                                        IDirectDraw **ppDirectDraw)
{
    HRESULT hr;
    IDirectDrawImpl *object = NULL;
    IDirectDraw *parent = NULL;

    TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p,%p)\n", iface, debugstr_guid(pGUID), hWnd, dwCoopLevelFlags,
          dwReserved, pUnkOuter, ppDirectDraw);

    if(pUnkOuter)
    {
        FIXME("Implement aggregation in ddrawex's IDirectDraw interface\n");
    }

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if(!object)
    {
        ERR("Out of memory\n");
        hr = E_OUTOFMEMORY;
        goto err;
    }
    object->ref = 1;
    object->IDirectDraw_Vtbl  = &IDirectDraw1_Vtbl;
    object->IDirectDraw2_Vtbl = &IDirectDraw2_Vtbl;
    object->IDirectDraw3_Vtbl = &IDirectDraw3_Vtbl;
    object->IDirectDraw4_Vtbl = &IDirectDraw4_Vtbl;

    hr = DirectDrawCreate(pGUID, &parent, NULL);
    if (FAILED(hr)) goto err;

    hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **) &object->parent);
    if(FAILED(hr)) goto err;

    hr = IDirectDraw_SetCooperativeLevel(dd1_from_impl(object), hWnd, dwCoopLevelFlags);
    if (FAILED(hr)) goto err;

    *ppDirectDraw = dd1_from_impl(object);
    IDirectDraw_Release(parent);
    return DD_OK;

err:
    if(object && object->parent) IDirectDraw4_Release(object->parent);
    if(parent) IDirectDraw_Release(parent);
    HeapFree(GetProcessHeap(), 0, object);
    *ppDirectDraw = NULL;
    return hr;
}

IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
{
    IDirectDrawImpl *This = impl_from_dd4(outer);
    return This->parent;
}
