/*
 * 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_IDirectDraw(IDirectDraw *iface)
{
    return CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw_iface);
}

static IDirectDrawImpl *impl_from_IDirectDraw2(IDirectDraw2 *iface)
{
    return CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw2_iface);
}

static IDirectDrawImpl *impl_from_IDirectDraw3(IDirectDraw3 *iface)
{
    return CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw3_iface);
}

static IDirectDrawImpl *impl_from_IDirectDraw4(IDirectDraw4 *iface)
{
    return CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw4_iface);
}

/******************************************************************************
 * IDirectDraw4 -> ddraw.dll wrappers
 ******************************************************************************/
static HRESULT WINAPI IDirectDraw4Impl_QueryInterface(IDirectDraw4 *iface, REFIID refiid,
        void **obj)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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 = &This->IDirectDraw4_iface;
        TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
        IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
    }
    else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) )
    {
        *obj = &This->IDirectDraw3_iface;
        TRACE("(%p) Returning IDirectDraw3 interface at %p\n", This, *obj);
        IDirectDraw3_AddRef(&This->IDirectDraw3_iface);
    }
    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
    {
        *obj = &This->IDirectDraw2_iface;
        TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
        IDirectDraw2_AddRef(&This->IDirectDraw2_iface);
    }
    else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
    {
        *obj = &This->IDirectDraw_iface;
        TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
        IDirectDraw_AddRef(&This->IDirectDraw_iface);
    }
    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_IDirectDraw3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_QueryInterface(&This->IDirectDraw4_iface, refiid, obj);
}

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

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

static ULONG WINAPI IDirectDraw4Impl_AddRef(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
}

static ULONG WINAPI IDirectDraw2Impl_AddRef(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
}

static ULONG WINAPI IDirectDrawImpl_AddRef(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
}

static ULONG WINAPI IDirectDraw4Impl_Release(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Release(&This->IDirectDraw4_iface);
}

static ULONG WINAPI IDirectDraw2Impl_Release(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Release(&This->IDirectDraw4_iface);
}

static ULONG WINAPI IDirectDrawImpl_Release(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Release(&This->IDirectDraw4_iface);
}

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

    return IDirectDraw4_Compact(This->parent);
}

static HRESULT WINAPI IDirectDraw3Impl_Compact(IDirectDraw3 *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Compact(&This->IDirectDraw4_iface);
}

static HRESULT WINAPI IDirectDraw2Impl_Compact(IDirectDraw2 *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Compact(&This->IDirectDraw4_iface);
}

static HRESULT WINAPI IDirectDrawImpl_Compact(IDirectDraw *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_Compact(&This->IDirectDraw4_iface);
}

static HRESULT WINAPI IDirectDraw4Impl_CreateClipper(IDirectDraw4 *iface, DWORD Flags,
        IDirectDrawClipper **clipper, IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreateClipper(&This->IDirectDraw4_iface, Flags, clipper, UnkOuter);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_CreatePalette(IDirectDraw4 *iface, DWORD Flags,
        PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("Thunking to IDirectDraw4\n");
    return IDirectDraw4_CreatePalette(&This->IDirectDraw4_iface, Flags, ColorTable, Palette,
            UnkOuter);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface, DDSURFACEDESC2 *DDSD,
        IDirectDrawSurface4 **Surf, IUnknown *UnkOuter)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    DDSURFACEDESC2 ddsd2;
    IDirectDrawSurface4 *surf4 = NULL;
    HRESULT hr;
    TRACE("Thunking to IDirectDraw4\n");

    DDSD_to_DDSD2(DDSD, &ddsd2);

    hr = IDirectDraw4_CreateSurface(&This->IDirectDraw4_iface, &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_IDirectDraw2(iface);
    TRACE("Thunking to IDirectDraw3\n");
    return IDirectDraw3_CreateSurface(&This->IDirectDraw3_iface, DDSD, Surf, UnkOuter);
}

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

static HRESULT WINAPI IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface,
        IDirectDrawSurface4 *src, IDirectDrawSurface4 **dst)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(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(&This->IDirectDraw4_iface, 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_IDirectDraw2(iface);
    TRACE("Thunking to IDirectDraw3\n");
    return IDirectDraw3_DuplicateSurface(&This->IDirectDraw3_iface, src, dst);
}

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

static HRESULT WINAPI IDirectDraw4Impl_EnumDisplayModes(IDirectDraw4 *iface, DWORD Flags,
        DDSURFACEDESC2 *DDSD, void *Context, LPDDENUMMODESCALLBACK2 cb)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(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(&This->IDirectDraw4_iface, 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_IDirectDraw2(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
    return IDirectDraw3_EnumDisplayModes(&This->IDirectDraw3_iface, Flags, DDSD, Context, cb);
}

static HRESULT WINAPI IDirectDrawImpl_EnumDisplayModes(IDirectDraw *iface, DWORD Flags,
        DDSURFACEDESC *DDSD, void *Context, LPDDENUMMODESCALLBACK cb)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
    return IDirectDraw3_EnumDisplayModes(&This->IDirectDraw3_iface, 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_IDirectDraw4(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_IDirectDraw3(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(&This->IDirectDraw4_iface, 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_IDirectDraw2(iface);
    TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
    return IDirectDraw3_EnumSurfaces(&This->IDirectDraw3_iface, Flags, DDSD, Context, Callback);
}

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

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

    return IDirectDraw4_FlipToGDISurface(This->parent);
}

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

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

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

static HRESULT WINAPI IDirectDraw4Impl_GetCaps(IDirectDraw4 *iface, DDCAPS *DriverCaps,
        DDCAPS *HELCaps)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
    return IDirectDraw4_GetCaps(&This->IDirectDraw4_iface, DriverCaps, HELCaps);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 *DDSD)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    DDSURFACEDESC2 ddsd2;
    HRESULT hr;

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

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

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

static HRESULT WINAPI IDirectDraw4Impl_GetFourCCCodes(IDirectDraw4 *iface, DWORD *NumCodes,
        DWORD *Codes)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
    return IDirectDraw4_GetFourCCCodes(&This->IDirectDraw4_iface, NumCodes, Codes);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface,
        IDirectDrawSurface4 **GDISurface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    IDirectDrawSurface4 *surf4;
    HRESULT hr;
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, GDISurface);

    hr = IDirectDraw4_GetGDISurface(&This->IDirectDraw4_iface, &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_IDirectDraw2(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
    return IDirectDraw3_GetGDISurface(&This->IDirectDraw3_iface, GDISurface);
}

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

static HRESULT WINAPI IDirectDraw4Impl_GetMonitorFrequency(IDirectDraw4 *iface, DWORD *Freq)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
    return IDirectDraw4_GetMonitorFrequency(&This->IDirectDraw4_iface, Freq);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_GetScanLine(IDirectDraw4 *iface, DWORD *Scanline)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
    return IDirectDraw4_GetScanLine(&This->IDirectDraw4_iface, Scanline);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_GetVerticalBlankStatus(IDirectDraw4 *iface, BOOL *status)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
    return IDirectDraw4_GetVerticalBlankStatus(&This->IDirectDraw4_iface, status);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_Initialize(IDirectDraw4 *iface, GUID *Guid)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
    return IDirectDraw4_Initialize(&This->IDirectDraw4_iface, Guid);
}

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

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

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

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

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

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

static HRESULT WINAPI IDirectDraw4Impl_SetCooperativeLevel(IDirectDraw4 *iface, HWND hwnd,
        DWORD cooplevel)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
    return IDirectDraw4_SetCooperativeLevel(&This->IDirectDraw4_iface, hwnd, cooplevel);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_SetDisplayMode(IDirectDraw4 *iface, DWORD Width,
        DWORD Height, DWORD BPP, DWORD RefreshRate, DWORD Flags)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
    return IDirectDraw3_SetDisplayMode(&This->IDirectDraw4_iface, 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_IDirectDraw2(iface);
    TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
    return IDirectDraw3_SetDisplayMode(&This->IDirectDraw4_iface, Width, Height, BPP, RefreshRate,
            Flags);
}

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

static HRESULT WINAPI IDirectDraw4Impl_WaitForVerticalBlank(IDirectDraw4 *iface, DWORD Flags,
        HANDLE h)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(iface);
    TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
    return IDirectDraw4_WaitForVerticalBlank(&This->IDirectDraw4_iface, Flags, h);
}

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

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

static HRESULT WINAPI IDirectDraw4Impl_GetAvailableVidMem(IDirectDraw4 *iface, DDSCAPS2 *Caps,
        DWORD *total, DWORD *free)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw3(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(&This->IDirectDraw4_iface, &caps2, total, free);
}

static HRESULT WINAPI IDirectDraw2Impl_GetAvailableVidMem(IDirectDraw2 *iface, DDSCAPS *Caps,
        DWORD *total, DWORD *free)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw2(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(&This->IDirectDraw4_iface, &caps2, total, free);
}

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

    return hr;
}

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

    if (!Surface) return E_POINTER;

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

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

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

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

static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(IDirectDraw4 *iface)
{
    IDirectDrawImpl *This = impl_from_IDirectDraw4(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_IDirectDraw4(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_iface.lpVtbl = &IDirectDraw1_Vtbl;
    object->IDirectDraw2_iface.lpVtbl = &IDirectDraw2_Vtbl;
    object->IDirectDraw3_iface.lpVtbl = &IDirectDraw3_Vtbl;
    object->IDirectDraw4_iface.lpVtbl = &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(&object->IDirectDraw_iface, hWnd, dwCoopLevelFlags);
    if (FAILED(hr)) goto err;

    *ppDirectDraw = &object->IDirectDraw_iface;
    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_IDirectDraw4(outer);

    if (outer->lpVtbl != &IDirectDraw4_Vtbl) return NULL;
    return This->parent;
}
