/*
 * Copyright 2008 Stefan Dösinger for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "wine/debug.h"

#define COBJMACROS

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

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

#include "ddrawex_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);

/******************************************************************************
 * Helper functions for COM management
 ******************************************************************************/
static IDirectDrawSurfaceImpl *impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface)
{
    return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface3_iface);
}

static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);

static IDirectDrawSurfaceImpl *impl_from_IDirectDrawSurface4(IDirectDrawSurface4 *iface)
{
    return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface4_iface);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(IDirectDrawSurface4 *iface,
        REFIID riid, void **obj)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);

    *obj = NULL;

    if(!riid)
        return DDERR_INVALIDPARAMS;

    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),obj);
    if (IsEqualGUID(riid, &IID_IUnknown)
     || IsEqualGUID(riid, &IID_IDirectDrawSurface4) )
    {
        *obj = &This->IDirectDrawSurface4_iface;
        IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface);
        TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This, *obj);
        return S_OK;
    }
    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3)
          || IsEqualGUID(riid, &IID_IDirectDrawSurface2)
          || IsEqualGUID(riid, &IID_IDirectDrawSurface) )
    {
        *obj = &This->IDirectDrawSurface3_iface;
        IDirectDrawSurface3_AddRef(&This->IDirectDrawSurface3_iface);
        TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj);
        return S_OK;
    }
    else if( IsEqualGUID(riid, &IID_IDirectDrawGammaControl) )
    {
        FIXME("Implement IDirectDrawGammaControl in ddrawex\n");
    }
    else if( IsEqualGUID(riid, &IID_IDirect3DHALDevice)||
             IsEqualGUID(riid, &IID_IDirect3DRGBDevice) )
    {
        /* Most likely not supported */
        FIXME("Test IDirect3DDevice in ddrawex\n");
    }
    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
             IsEqualGUID( &IID_IDirect3DTexture2, riid ))
    {
        FIXME("Implement IDirect3dTexture in ddrawex\n");
    }
    else
    {
        WARN("No interface\n");
    }

    return E_NOINTERFACE;
}

static HRESULT WINAPI IDirectDrawSurface3Impl_QueryInterface(IDirectDrawSurface3 *iface,
        REFIID riid, void **obj)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%s,%p): Thunking to IDirectDrawSurface4\n",This,debugstr_guid(riid),obj);
    return IDirectDrawSurface4_QueryInterface(&This->IDirectDrawSurface4_iface, riid, obj);
}

static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI IDirectDrawSurface3Impl_AddRef(IDirectDrawSurface3 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
    return IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface);
}

static ULONG WINAPI IDirectDrawSurface4Impl_Release(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

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

static ULONG WINAPI IDirectDrawSurface3Impl_Release(IDirectDrawSurface3 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
    return IDirectDrawSurface4_Release(&This->IDirectDrawSurface4_iface);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(IDirectDrawSurface4 *iface,
        IDirectDrawSurface4 *Attach_iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurfaceImpl *attach = unsafe_impl_from_IDirectDrawSurface4(Attach_iface);
    TRACE("(%p)->(%p)\n", This, attach);
    return IDirectDrawSurface4_AddAttachedSurface(This->parent, attach->parent);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_AddAttachedSurface(IDirectDrawSurface3 *iface,
        IDirectDrawSurface3 *Attach_iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurfaceImpl *attach = unsafe_impl_from_IDirectDrawSurface3(Attach_iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, attach);
    return IDirectDrawSurface4_AddAttachedSurface(&This->IDirectDrawSurface4_iface,
            attach ? &attach->IDirectDrawSurface4_iface : NULL);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(IDirectDrawSurface4 *iface,
        RECT *Rect)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, Rect);
    return IDirectDrawSurface4_AddOverlayDirtyRect(This->parent, Rect);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_AddOverlayDirtyRect(IDirectDrawSurface3 *iface,
        RECT *Rect)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Rect);
    return IDirectDrawSurface4_AddOverlayDirtyRect(&This->IDirectDrawSurface4_iface, Rect);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(IDirectDrawSurface4 *iface, RECT *DestRect,
        IDirectDrawSurface4 *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface4(SrcSurface);
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p)\n", This, DestRect, Src, SrcRect, Flags, DDBltFx);
    return IDirectDrawSurface4_Blt(This->parent, DestRect, Src ? Src->parent : NULL,
                                   SrcRect, Flags, DDBltFx);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_Blt(IDirectDrawSurface3 *iface, RECT *DestRect,
        IDirectDrawSurface3 *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface3(SrcSurface);
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, DestRect, Src, SrcRect, Flags, DDBltFx);
    return IDirectDrawSurface4_Blt(&This->IDirectDrawSurface4_iface, DestRect,
            Src ? &Src->IDirectDrawSurface4_iface : NULL, SrcRect, Flags, DDBltFx);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(IDirectDrawSurface4 *iface,
        DDBLTBATCH *Batch, DWORD Count, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p,%u,0x%08x)\n", This, Batch, Count, Flags);
    return IDirectDrawSurface4_BltBatch(This->parent, Batch, Count, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_BltBatch(IDirectDrawSurface3 *iface,
        DDBLTBATCH *Batch, DWORD Count, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p,%u,0x%08x): Thunking to IDirectDrawSurface4\n", This, Batch, Count, Flags);
    return IDirectDrawSurface4_BltBatch(&This->IDirectDrawSurface4_iface, Batch, Count, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(IDirectDrawSurface4 *iface, DWORD dstx,
        DWORD dsty, IDirectDrawSurface4 *Source, RECT *rsrc, DWORD trans)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface4(Source);
    TRACE("(%p)->(%u,%u,%p,%p,0x%08x)\n", This, dstx, dsty, Src, rsrc, trans);
    return IDirectDrawSurface4_BltFast(This->parent, dstx, dsty, Src ? Src->parent : NULL,
                                       rsrc, trans);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_BltFast(IDirectDrawSurface3 *iface, DWORD dstx,
        DWORD dsty, IDirectDrawSurface3 *Source, RECT *rsrc, DWORD trans)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface3(Source);
    TRACE("(%p)->(%u,%u,%p,%p,0x%08x): Thunking to IDirectDrawSurface4\n", This, dstx, dsty, Src, rsrc, trans);
    return IDirectDrawSurface4_BltFast(&This->IDirectDrawSurface4_iface, dstx, dsty,
            Src ? &Src->IDirectDrawSurface4_iface : NULL, rsrc, trans);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(IDirectDrawSurface4 *iface,
        DWORD Flags, IDirectDrawSurface4 *Attach)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurfaceImpl *Att = unsafe_impl_from_IDirectDrawSurface4(Attach);
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, Att);
    return IDirectDrawSurface4_DeleteAttachedSurface(This->parent, Flags,
                                                     Att ? Att->parent : NULL);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_DeleteAttachedSurface(IDirectDrawSurface3 *iface,
        DWORD Flags, IDirectDrawSurface3 *Attach)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurfaceImpl *Att = unsafe_impl_from_IDirectDrawSurface3(Attach);
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, Att);
    return IDirectDrawSurface4_DeleteAttachedSurface(&This->IDirectDrawSurface4_iface, Flags,
            Att ? &Att->IDirectDrawSurface4_iface : NULL);
}

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

static HRESULT WINAPI
enumsurfaces_wrap_cb(IDirectDrawSurface4 *surf, DDSURFACEDESC2 *desc, void *vctx)
{
    struct enumsurfaces_wrap *ctx = vctx;
    IDirectDrawSurface4 *outer = dds_get_outer(surf);

    TRACE("Returning outer surface %p for inner surface %p\n", outer, surf);
    IDirectDrawSurface4_AddRef(outer);
    IDirectDrawSurface4_Release(surf);
    return ctx->orig_cb(outer, desc, vctx);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(IDirectDrawSurface4 *iface,
        void *context, LPDDENUMSURFACESCALLBACK2 cb)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    struct enumsurfaces_wrap ctx;
    TRACE("(%p)->(%p,%p)\n", This, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
    return IDirectDrawSurface4_EnumAttachedSurfaces(This->parent, &ctx, enumsurfaces_wrap_cb);
}

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

static HRESULT WINAPI enumsurfaces_thunk_cb(IDirectDrawSurface4 *surf, DDSURFACEDESC2 *desc2,
        void *vctx)
{
    IDirectDrawSurfaceImpl *This = unsafe_impl_from_IDirectDrawSurface4(surf);
    struct enumsurfaces_thunk *ctx = vctx;
    DDSURFACEDESC desc;

    TRACE("Thunking back to IDirectDrawSurface3\n");
    IDirectDrawSurface3_AddRef(&This->IDirectDrawSurface3_iface);
    IDirectDrawSurface3_Release(surf);
    DDSD2_to_DDSD(desc2, &desc);
    return ctx->orig_cb((IDirectDrawSurface *)&This->IDirectDrawSurface3_iface, &desc,
            ctx->orig_ctx);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_EnumAttachedSurfaces(IDirectDrawSurface3 *iface,
        void *context, LPDDENUMSURFACESCALLBACK cb)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    struct enumsurfaces_thunk ctx;
    TRACE("(%p)->(%p,%p): Thunking to IDirectDraw4\n", This, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
    return IDirectDrawSurface4_EnumAttachedSurfaces(&This->IDirectDrawSurface4_iface, &ctx,
            enumsurfaces_thunk_cb);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(IDirectDrawSurface4 *iface,
        DWORD Flags, void *context, LPDDENUMSURFACESCALLBACK2 cb)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    struct enumsurfaces_wrap ctx;
    TRACE("(%p)->(0x%08x,%p,%p)\n", This, Flags, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
    return IDirectDrawSurface4_EnumOverlayZOrders(This->parent, Flags, &ctx, enumsurfaces_wrap_cb);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_EnumOverlayZOrders(IDirectDrawSurface3 *iface,
        DWORD Flags, void *context, LPDDENUMSURFACESCALLBACK cb)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    struct enumsurfaces_thunk ctx;
    TRACE("(%p)->(0x%08x,%p,%p): Thunking to IDirectDraw4\n", This, Flags, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
    return IDirectDrawSurface4_EnumOverlayZOrders(&This->IDirectDrawSurface4_iface, Flags, &ctx,
            enumsurfaces_thunk_cb);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Flip(IDirectDrawSurface4 *iface,
        IDirectDrawSurface4 *DestOverride, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurfaceImpl *Dest = unsafe_impl_from_IDirectDrawSurface4(DestOverride);
    TRACE("(%p)->(%p,0x%08x)\n", This, Dest, Flags);
    return IDirectDrawSurface4_Flip(This->parent, Dest ? Dest->parent : NULL, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_Flip(IDirectDrawSurface3 *iface,
        IDirectDrawSurface3 *DestOverride, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurfaceImpl *Dest = unsafe_impl_from_IDirectDrawSurface3(DestOverride);
    TRACE("(%p)->(%p,0x%08x): Thunking to IDirectDrawSurface4\n", This, Dest, Flags);
    return IDirectDrawSurface4_Flip(&This->IDirectDrawSurface4_iface,
            Dest ? &Dest->IDirectDrawSurface4_iface : NULL, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(IDirectDrawSurface4 *iface,
        DDSCAPS2 *Caps, IDirectDrawSurface4 **Surface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurface4 *inner = NULL;
    HRESULT hr;
    TRACE("(%p)->(%p,%p)\n", This, Caps, Surface);

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

static HRESULT WINAPI IDirectDrawSurface3Impl_GetAttachedSurface(IDirectDrawSurface3 *iface,
        DDSCAPS *Caps, IDirectDrawSurface3 **Surface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurface4 *surf4;
    DDSCAPS2 caps2;
    HRESULT hr;
    TRACE("(%p)->(%p,%p): Thunking to IDirectDrawSurface4\n", This, Caps, Surface);

    memset(&caps2, 0, sizeof(caps2));
    caps2.dwCaps = Caps->dwCaps;
    hr = IDirectDrawSurface4_GetAttachedSurface(&This->IDirectDrawSurface4_iface, &caps2, &surf4);
    if(SUCCEEDED(hr))
    {
        IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface3, (void **) Surface);
        IDirectDrawSurface4_Release(surf4);
    }
    else
    {
        *Surface = NULL;
    }
    return hr;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(IDirectDrawSurface4 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(0x%08x)\n", This, Flags);
    return IDirectDrawSurface4_GetBltStatus(This->parent, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetBltStatus(IDirectDrawSurface3 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(0x%08x): Thunking to IDirectDrawSurface4\n", This, Flags);
    return IDirectDrawSurface4_GetBltStatus(&This->IDirectDrawSurface4_iface, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(IDirectDrawSurface4 *iface, DDSCAPS2 *Caps)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, Caps);
    return IDirectDrawSurface4_GetCaps(This->parent, Caps);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetCaps(IDirectDrawSurface3 *iface, DDSCAPS *Caps)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    DDSCAPS2 caps2;
    HRESULT hr;
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Caps);

    memset(&caps2, 0, sizeof(caps2));
    memset(Caps, 0, sizeof(*Caps));
    hr = IDirectDrawSurface4_GetCaps(&This->IDirectDrawSurface4_iface, &caps2);
    Caps->dwCaps = caps2.dwCaps;
    return hr;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(IDirectDrawSurface4 *iface,
        IDirectDrawClipper **Clipper)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, Clipper);
    return IDirectDrawSurface4_GetClipper(This->parent, Clipper);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetClipper(IDirectDrawSurface3 *iface,
        IDirectDrawClipper **Clipper)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Clipper);
    return IDirectDrawSurface4_GetClipper(&This->IDirectDrawSurface4_iface, Clipper);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(IDirectDrawSurface4 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, CKey);
    return IDirectDrawSurface4_GetColorKey(This->parent, Flags, CKey);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetColorKey(IDirectDrawSurface3 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, CKey);
    return IDirectDrawSurface4_GetColorKey(&This->IDirectDrawSurface4_iface, Flags, CKey);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(IDirectDrawSurface4 *iface, HDC *hdc)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, hdc);
    if(This->permanent_dc)
    {
        TRACE("Returning stored dc %p\n", This->hdc);
        *hdc = This->hdc;
        return DD_OK;
    }
    else
    {
        return IDirectDrawSurface4_GetDC(This->parent, hdc);
    }
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetDC(IDirectDrawSurface3 *iface, HDC *hdc)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, hdc);
    return IDirectDrawSurface4_GetDC(&This->IDirectDrawSurface4_iface, hdc);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(IDirectDrawSurface4 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(0x%08x)\n", This, Flags);
    return IDirectDrawSurface4_GetFlipStatus(This->parent, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetFlipStatus(IDirectDrawSurface3 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(0x%08x): Thunking to IDirectDrawSurface4\n", This, Flags);
    return IDirectDrawSurface4_GetFlipStatus(&This->IDirectDrawSurface4_iface, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(IDirectDrawSurface4 *iface,
        LONG *X, LONG *Y)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p,%p)\n", This, X, Y);
    return IDirectDrawSurface4_GetOverlayPosition(This->parent, X, Y);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetOverlayPosition(IDirectDrawSurface3 *iface,
        LONG *X, LONG *Y)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p,%p): Thunking to IDirectDrawSurface4\n", This, X, Y);
    return IDirectDrawSurface4_GetOverlayPosition(&This->IDirectDrawSurface4_iface, X, Y);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(IDirectDrawSurface4 *iface,
        IDirectDrawPalette **Pal)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, Pal);
    return IDirectDrawSurface4_GetPalette(This->parent, Pal);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetPalette(IDirectDrawSurface3 *iface,
        IDirectDrawPalette **Pal)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Pal);
    return IDirectDrawSurface4_GetPalette(&This->IDirectDrawSurface4_iface, Pal);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(IDirectDrawSurface4 *iface,
        DDPIXELFORMAT *PixelFormat)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, PixelFormat);
    return IDirectDrawSurface4_GetPixelFormat(This->parent, PixelFormat);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetPixelFormat(IDirectDrawSurface3 *iface,
        DDPIXELFORMAT *PixelFormat)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, PixelFormat);
    return IDirectDrawSurface4_GetPixelFormat(&This->IDirectDrawSurface4_iface, PixelFormat);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(IDirectDrawSurface4 *iface,
        DDSURFACEDESC2 *DDSD)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    HRESULT hr;
    TRACE("(%p)->(%p)\n", This, DDSD);
    hr = IDirectDrawSurface4_GetSurfaceDesc(This->parent, DDSD);

    if(SUCCEEDED(hr) && This->permanent_dc)
    {
        DDSD->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
        DDSD->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
    }

    return hr;
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetSurfaceDesc(IDirectDrawSurface3 *iface,
        DDSURFACEDESC *DDSD)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    DDSURFACEDESC2 ddsd2;
    HRESULT hr;
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, DDSD);

    memset(&ddsd2, 0, sizeof(ddsd2));
    ddsd2.dwSize = sizeof(ddsd2);
    hr = IDirectDrawSurface4_GetSurfaceDesc(&This->IDirectDrawSurface4_iface, &ddsd2);
    DDSD2_to_DDSD(&ddsd2, DDSD);
    return hr;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(IDirectDrawSurface4 *iface,
        IDirectDraw *DD, DDSURFACEDESC2 *DDSD)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDraw4 *outer_DD4;
    IDirectDraw4 *inner_DD4;
    IDirectDraw *inner_DD;
    HRESULT hr;
    TRACE("(%p)->(%p,%p)\n", This, DD, DDSD);

    IDirectDraw_QueryInterface(DD, &IID_IDirectDraw4, (void **) &outer_DD4);
    inner_DD4 = dd_get_inner(outer_DD4);
    IDirectDraw4_Release(outer_DD4);
    IDirectDraw4_QueryInterface(inner_DD4, &IID_IDirectDraw4, (void **) &inner_DD);
    hr = IDirectDrawSurface4_Initialize(This->parent, inner_DD, DDSD);
    IDirectDraw_Release(inner_DD);
    return hr;
}

static HRESULT WINAPI IDirectDrawSurface3Impl_Initialize(IDirectDrawSurface3 *iface,
        IDirectDraw *DD, DDSURFACEDESC *DDSD)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    DDSURFACEDESC2 ddsd2;
    TRACE("(%p)->(%p,%p): Thunking to IDirectDrawSurface4\n", This, DD, DDSD);
    DDSD_to_DDSD2(DDSD, &ddsd2);
    return IDirectDrawSurface4_Initialize(&This->IDirectDrawSurface4_iface, DD, &ddsd2);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)\n", This);
    return IDirectDrawSurface4_IsLost(This->parent);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_IsLost(IDirectDrawSurface3 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
    return IDirectDrawSurface4_IsLost(&This->IDirectDrawSurface4_iface);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(IDirectDrawSurface4 *iface, RECT *Rect,
        DDSURFACEDESC2 *DDSD, DWORD Flags, HANDLE h)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    HRESULT hr;
    TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This, Rect, DDSD, Flags, h);
    hr = IDirectDrawSurface4_Lock(This->parent, Rect, DDSD, Flags, h);

    if(SUCCEEDED(hr) && This->permanent_dc)
    {
        DDSD->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
        DDSD->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
    }

    return hr;
}

static HRESULT WINAPI IDirectDrawSurface3Impl_Lock(IDirectDrawSurface3 *iface, RECT *Rect,
        DDSURFACEDESC *DDSD, DWORD Flags, HANDLE h)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    DDSURFACEDESC2 ddsd2;
    HRESULT hr;
    TRACE("(%p)->(%p,%p,0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Rect, DDSD, Flags, h);
    memset(&ddsd2, 0, sizeof(ddsd2));
    ddsd2.dwSize = sizeof(ddsd2);
    hr = IDirectDrawSurface4_Lock(&This->IDirectDrawSurface4_iface, Rect, &ddsd2, Flags, h);
    DDSD2_to_DDSD(&ddsd2, DDSD);
    return hr;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(IDirectDrawSurface4 *iface, HDC hdc)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, hdc);
    if(This->permanent_dc)
    {
        TRACE("Surface has a permanent DC, not doing anything\n");
        return DD_OK;
    }
    else
    {
        return IDirectDrawSurface4_ReleaseDC(This->parent, hdc);
    }
}

static HRESULT WINAPI IDirectDrawSurface3Impl_ReleaseDC(IDirectDrawSurface3 *iface, HDC hdc)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, hdc);
    return IDirectDrawSurface4_ReleaseDC(&This->IDirectDrawSurface4_iface, hdc);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)\n", This);
    return IDirectDrawSurface4_Restore(This->parent);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_Restore(IDirectDrawSurface3 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
    return IDirectDrawSurface4_Restore(&This->IDirectDrawSurface4_iface);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(IDirectDrawSurface4 *iface,
        IDirectDrawClipper *Clipper)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, Clipper);
    return IDirectDrawSurface4_SetClipper(This->parent, Clipper);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_SetClipper(IDirectDrawSurface3 *iface,
        IDirectDrawClipper *Clipper)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Clipper);
    return IDirectDrawSurface4_SetClipper(&This->IDirectDrawSurface4_iface, Clipper);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(IDirectDrawSurface4 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, CKey);
    return IDirectDrawSurface4_SetColorKey(This->parent, Flags, CKey);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_SetColorKey(IDirectDrawSurface3 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, CKey);
    return IDirectDrawSurface4_SetColorKey(&This->IDirectDrawSurface4_iface, Flags, CKey);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(IDirectDrawSurface4 *iface,
        LONG X, LONG Y)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%u,%u)\n", This, X, Y);
    return IDirectDrawSurface4_SetOverlayPosition(This->parent, X, Y);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_SetOverlayPosition(IDirectDrawSurface3 *iface,
        LONG X, LONG Y)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%u,%u): Thunking to IDirectDrawSurface4\n", This, X, Y);
    return IDirectDrawSurface4_SetOverlayPosition(&This->IDirectDrawSurface4_iface, X, Y);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetPalette(IDirectDrawSurface4 *iface,
        IDirectDrawPalette *Pal)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, Pal);
    return IDirectDrawSurface4_SetPalette(This->parent, Pal);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_SetPalette(IDirectDrawSurface3 *iface,
        IDirectDrawPalette *Pal)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Pal);
    return IDirectDrawSurface4_SetPalette(&This->IDirectDrawSurface4_iface, Pal);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Unlock(IDirectDrawSurface4 *iface, RECT *pRect)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, pRect);
    return IDirectDrawSurface4_Unlock(This->parent, pRect);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_Unlock(IDirectDrawSurface3 *iface, void *data)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, data);
    return IDirectDrawSurface4_Unlock(&This->IDirectDrawSurface4_iface, NULL);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(IDirectDrawSurface4 *iface,
        RECT *SrcRect, IDirectDrawSurface4 *DstSurface, RECT *DstRect, DWORD Flags,
        DDOVERLAYFX *FX)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurfaceImpl *Dst = unsafe_impl_from_IDirectDrawSurface4(DstSurface);
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p)\n", This, SrcRect, Dst, DstRect, Flags, FX);
    return IDirectDrawSurface4_UpdateOverlay(This->parent, SrcRect, Dst ? Dst->parent : NULL,
                                             DstRect, Flags, FX);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_UpdateOverlay(IDirectDrawSurface3 *iface,
        LPRECT SrcRect, IDirectDrawSurface3 *DstSurface, LPRECT DstRect, DWORD Flags,
        LPDDOVERLAYFX FX)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurfaceImpl *Dst = unsafe_impl_from_IDirectDrawSurface3(DstSurface);
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, SrcRect, Dst, DstRect, Flags, FX);
    return IDirectDrawSurface4_UpdateOverlay(&This->IDirectDrawSurface4_iface, SrcRect,
            Dst ? &Dst->IDirectDrawSurface4_iface : NULL, DstRect, Flags, FX);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(IDirectDrawSurface4 *iface,
        DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(0x%08x)\n", This, Flags);
    return IDirectDrawSurface4_UpdateOverlayDisplay(This->parent, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_UpdateOverlayDisplay(IDirectDrawSurface3 *iface,
        DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(0x%08x): Thunking to IDirectDrawSurface4\n", This, Flags);
    return IDirectDrawSurface4_UpdateOverlayDisplay(&This->IDirectDrawSurface4_iface, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(IDirectDrawSurface4 *iface,
        DWORD Flags, IDirectDrawSurface4 *DDSRef)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    IDirectDrawSurfaceImpl *Ref = unsafe_impl_from_IDirectDrawSurface4(DDSRef);
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, Ref);
    return IDirectDrawSurface4_UpdateOverlayZOrder(This->parent, Flags, Ref ? Ref->parent : NULL);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_UpdateOverlayZOrder(IDirectDrawSurface3 *iface,
        DWORD Flags, IDirectDrawSurface3 *DDSRef)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    IDirectDrawSurfaceImpl *Ref = unsafe_impl_from_IDirectDrawSurface3(DDSRef);
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, Ref);
    return IDirectDrawSurface4_UpdateOverlayZOrder(&This->IDirectDrawSurface4_iface, Flags,
            Ref ? &Ref->IDirectDrawSurface4_iface : NULL);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(IDirectDrawSurface4 *iface, void **DD)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    FIXME("(%p)->(%p)\n", This, DD);
    /* This has to be implemented in ddrawex, DDraw's interface can't be used because it is pretty
     * hard to tell which version of the DD interface is returned
     */
    *DD = NULL;
    return E_FAIL;
}

static HRESULT WINAPI IDirectDrawSurface3Impl_GetDDInterface(IDirectDrawSurface3 *iface, void **DD)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    FIXME("(%p)->(%p)\n", This, DD);
    /* A thunk it pretty pointless because of the same reason relaying to ddraw.dll works badly
     */
    *DD = NULL;
    return E_FAIL;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(IDirectDrawSurface4 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%x)\n", iface, Flags);
    return IDirectDrawSurface4_PageLock(This->parent, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_PageLock(IDirectDrawSurface3 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%x): Thunking to IDirectDrawSurface4\n", iface, Flags);
    return IDirectDrawSurface4_PageLock(&This->IDirectDrawSurface4_iface, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(IDirectDrawSurface4 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%x)\n", iface, Flags);
    return IDirectDrawSurface4_PageUnlock(This->parent, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_PageUnlock(IDirectDrawSurface3 *iface, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    TRACE("(%p)->(%x): Thunking to IDirectDrawSurface4\n", iface, Flags);
    return IDirectDrawSurface4_PageUnlock(&This->IDirectDrawSurface4_iface, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(IDirectDrawSurface4 *iface,
        DDSURFACEDESC2 *DDSD, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p,0x%08x)\n", This, DDSD, Flags);
    return IDirectDrawSurface4_SetSurfaceDesc(This->parent, DDSD, Flags);
}

static HRESULT WINAPI IDirectDrawSurface3Impl_SetSurfaceDesc(IDirectDrawSurface3 *iface,
        DDSURFACEDESC *DDSD, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
    DDSURFACEDESC2 ddsd;
    TRACE("(%p)->(%p,0x%08x): Thunking to IDirectDrawSurface4\n", This, DDSD, Flags);

    DDSD_to_DDSD2(DDSD, &ddsd);
    return IDirectDrawSurface4_SetSurfaceDesc(&This->IDirectDrawSurface4_iface, &ddsd, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(IDirectDrawSurface4 *iface,
        REFGUID tag, void *Data, DWORD Size, DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%s,%p,%u,0x%08x)\n", iface, debugstr_guid(tag), Data, Size, Flags);

    /* To completely avoid this we'd have to clone the private data API in ddrawex */
    if(IsEqualGUID(&IID_DDrawexPriv, tag)) {
        FIXME("Application uses ddrawex's private guid\n");
    }

    return IDirectDrawSurface4_SetPrivateData(This->parent, tag, Data, Size, Flags);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(IDirectDrawSurface4 *iface,
        REFGUID tag, void *Data, DWORD *Size)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%s,%p,%p)\n", iface, debugstr_guid(tag), Data, Size);

    /* To completely avoid this we'd have to clone the private data API in ddrawex */
    if(IsEqualGUID(&IID_DDrawexPriv, tag)) {
        FIXME("Application uses ddrawex's private guid\n");
    }

    return IDirectDrawSurface4_GetPrivateData(This->parent, tag, Data, Size);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(IDirectDrawSurface4 *iface,
        REFGUID tag)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%s)\n", iface, debugstr_guid(tag));

    /* To completely avoid this we'd have to clone the private data API in ddrawex */
    if(IsEqualGUID(&IID_DDrawexPriv, tag)) {
        FIXME("Application uses ddrawex's private guid\n");
    }

    return IDirectDrawSurface4_FreePrivateData(This->parent, tag);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(IDirectDrawSurface4 *iface,
        DWORD *pValue)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)->(%p)\n", This, pValue);
    return IDirectDrawSurface4_GetUniquenessValue(This->parent, pValue);
}

static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
    TRACE("(%p)\n", This);
    return IDirectDrawSurface4_ChangeUniquenessValue(This->parent);
}

static const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
{
    /* IUnknown */
    IDirectDrawSurface3Impl_QueryInterface,
    IDirectDrawSurface3Impl_AddRef,
    IDirectDrawSurface3Impl_Release,
    /* IDirectDrawSurface */
    IDirectDrawSurface3Impl_AddAttachedSurface,
    IDirectDrawSurface3Impl_AddOverlayDirtyRect,
    IDirectDrawSurface3Impl_Blt,
    IDirectDrawSurface3Impl_BltBatch,
    IDirectDrawSurface3Impl_BltFast,
    IDirectDrawSurface3Impl_DeleteAttachedSurface,
    IDirectDrawSurface3Impl_EnumAttachedSurfaces,
    IDirectDrawSurface3Impl_EnumOverlayZOrders,
    IDirectDrawSurface3Impl_Flip,
    IDirectDrawSurface3Impl_GetAttachedSurface,
    IDirectDrawSurface3Impl_GetBltStatus,
    IDirectDrawSurface3Impl_GetCaps,
    IDirectDrawSurface3Impl_GetClipper,
    IDirectDrawSurface3Impl_GetColorKey,
    IDirectDrawSurface3Impl_GetDC,
    IDirectDrawSurface3Impl_GetFlipStatus,
    IDirectDrawSurface3Impl_GetOverlayPosition,
    IDirectDrawSurface3Impl_GetPalette,
    IDirectDrawSurface3Impl_GetPixelFormat,
    IDirectDrawSurface3Impl_GetSurfaceDesc,
    IDirectDrawSurface3Impl_Initialize,
    IDirectDrawSurface3Impl_IsLost,
    IDirectDrawSurface3Impl_Lock,
    IDirectDrawSurface3Impl_ReleaseDC,
    IDirectDrawSurface3Impl_Restore,
    IDirectDrawSurface3Impl_SetClipper,
    IDirectDrawSurface3Impl_SetColorKey,
    IDirectDrawSurface3Impl_SetOverlayPosition,
    IDirectDrawSurface3Impl_SetPalette,
    IDirectDrawSurface3Impl_Unlock,
    IDirectDrawSurface3Impl_UpdateOverlay,
    IDirectDrawSurface3Impl_UpdateOverlayDisplay,
    IDirectDrawSurface3Impl_UpdateOverlayZOrder,
    /* IDirectDrawSurface 2 */
    IDirectDrawSurface3Impl_GetDDInterface,
    IDirectDrawSurface3Impl_PageLock,
    IDirectDrawSurface3Impl_PageUnlock,
    /* IDirectDrawSurface 3 */
    IDirectDrawSurface3Impl_SetSurfaceDesc
};

static const IDirectDrawSurface4Vtbl IDirectDrawSurface4_Vtbl =
{
    /*** IUnknown ***/
    IDirectDrawSurface4Impl_QueryInterface,
    IDirectDrawSurface4Impl_AddRef,
    IDirectDrawSurface4Impl_Release,
    /*** IDirectDrawSurface ***/
    IDirectDrawSurface4Impl_AddAttachedSurface,
    IDirectDrawSurface4Impl_AddOverlayDirtyRect,
    IDirectDrawSurface4Impl_Blt,
    IDirectDrawSurface4Impl_BltBatch,
    IDirectDrawSurface4Impl_BltFast,
    IDirectDrawSurface4Impl_DeleteAttachedSurface,
    IDirectDrawSurface4Impl_EnumAttachedSurfaces,
    IDirectDrawSurface4Impl_EnumOverlayZOrders,
    IDirectDrawSurface4Impl_Flip,
    IDirectDrawSurface4Impl_GetAttachedSurface,
    IDirectDrawSurface4Impl_GetBltStatus,
    IDirectDrawSurface4Impl_GetCaps,
    IDirectDrawSurface4Impl_GetClipper,
    IDirectDrawSurface4Impl_GetColorKey,
    IDirectDrawSurface4Impl_GetDC,
    IDirectDrawSurface4Impl_GetFlipStatus,
    IDirectDrawSurface4Impl_GetOverlayPosition,
    IDirectDrawSurface4Impl_GetPalette,
    IDirectDrawSurface4Impl_GetPixelFormat,
    IDirectDrawSurface4Impl_GetSurfaceDesc,
    IDirectDrawSurface4Impl_Initialize,
    IDirectDrawSurface4Impl_IsLost,
    IDirectDrawSurface4Impl_Lock,
    IDirectDrawSurface4Impl_ReleaseDC,
    IDirectDrawSurface4Impl_Restore,
    IDirectDrawSurface4Impl_SetClipper,
    IDirectDrawSurface4Impl_SetColorKey,
    IDirectDrawSurface4Impl_SetOverlayPosition,
    IDirectDrawSurface4Impl_SetPalette,
    IDirectDrawSurface4Impl_Unlock,
    IDirectDrawSurface4Impl_UpdateOverlay,
    IDirectDrawSurface4Impl_UpdateOverlayDisplay,
    IDirectDrawSurface4Impl_UpdateOverlayZOrder,
    /*** IDirectDrawSurface2 ***/
    IDirectDrawSurface4Impl_GetDDInterface,
    IDirectDrawSurface4Impl_PageLock,
    IDirectDrawSurface4Impl_PageUnlock,
    /*** IDirectDrawSurface3 ***/
    IDirectDrawSurface4Impl_SetSurfaceDesc,
    /*** IDirectDrawSurface4 ***/
    IDirectDrawSurface4Impl_SetPrivateData,
    IDirectDrawSurface4Impl_GetPrivateData,
    IDirectDrawSurface4Impl_FreePrivateData,
    IDirectDrawSurface4Impl_GetUniquenessValue,
    IDirectDrawSurface4Impl_ChangeUniquenessValue,
};

static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface)
{
    if (!iface) return NULL;
    if (iface->lpVtbl != &IDirectDrawSurface3_Vtbl) return NULL;
    return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface3_iface);
}

IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface4(IDirectDrawSurface4 *iface)
{
    if (!iface) return NULL;
    if (iface->lpVtbl != &IDirectDrawSurface4_Vtbl) return NULL;
    return impl_from_IDirectDrawSurface4(iface);
}

/* dds_get_outer
 *
 * Given a surface from ddraw.dll it retrieves the pointer to the ddrawex.dll wrapper around it
 *
 * Parameters:
 *  inner: ddraw.dll surface to retrieve the outer surface from
 *
 * Returns:
 *  The surface wrapper. If there is none yet, a new one is created
 */
IDirectDrawSurface4 *dds_get_outer(IDirectDrawSurface4 *inner)
{
    IDirectDrawSurface4 *outer = NULL;
    DWORD size = sizeof(outer);
    HRESULT hr;
    if(!inner) return NULL;

    hr = IDirectDrawSurface4_GetPrivateData(inner,
                                            &IID_DDrawexPriv,
                                            &outer,
                                            &size);
    if(FAILED(hr) || outer == NULL)
    {
        IDirectDrawSurfaceImpl *impl;

        TRACE("Creating new ddrawex surface wrapper for surface %p\n", inner);
        impl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*impl));
        impl->ref = 1;
        impl->IDirectDrawSurface3_iface.lpVtbl = &IDirectDrawSurface3_Vtbl;
        impl->IDirectDrawSurface4_iface.lpVtbl = &IDirectDrawSurface4_Vtbl;
        IDirectDrawSurface4_AddRef(inner);
        impl->parent = inner;

        outer = &impl->IDirectDrawSurface4_iface;

        hr = IDirectDrawSurface4_SetPrivateData(inner,
                                                &IID_DDrawexPriv,
                                                &outer,
                                                sizeof(outer),
                                                0 /* Flags */);
        if(FAILED(hr))
        {
            ERR("IDirectDrawSurface4_SetPrivateData failed\n");
        }
    }

    return outer;
}

HRESULT prepare_permanent_dc(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = unsafe_impl_from_IDirectDrawSurface4(iface);
    HRESULT hr;
    This->permanent_dc = TRUE;

    hr = IDirectDrawSurface4_GetDC(This->parent, &This->hdc);
    if(FAILED(hr)) return hr;
    hr = IDirectDrawSurface4_ReleaseDC(This->parent, This->hdc);
    return hr;
}
