/*
 * 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
 */
#include "wine/debug.h"

#define COBJMACROS

#include "winbase.h"
#include "wingdi.h"

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

#include "ddrawex_private.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->ddpfPixelFormat = in->ddpfPixelFormat;
    if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
    if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch;
    if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
    if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwMipMapCount = in->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->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->dwMipMapCount = in->dwMipMapCount;
    if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate;
    if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->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->ddpfPixelFormat;
    if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
    if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch;
    if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
    if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwZBufferBitDepth = in->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->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->dwMipMapCount = in->dwMipMapCount;
    if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate;
    if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->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);
    IDirectDrawSurface4 *inner;
    HRESULT hr;
    TRACE("(%p)->(%p, %p)\n", This, hdc, Surface);
    hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, &inner);
    if(SUCCEEDED(hr))
    {
        *Surface = dds_get_outer(inner);
        IDirectDrawSurface4_AddRef(*Surface);
        IDirectDrawSurface4_Release(inner);
    }
    else
    {
        *Surface = NULL;
    }

    return hr;
}

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

    hr = IDirectDraw4_GetSurfaceFromDC(dd4_from_impl(This), hdc, &surf4);
    if(FAILED(hr))
    {
        *Surface = NULL;
        return hr;
    }
    IDirectDrawSurface4_QueryInterface(surf4, &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;
}
