/*
 * 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);
    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;
}
