/*
 * 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_dds4(IDirectDrawSurface4 *iface)
{
    if(!iface) return NULL;
    return (IDirectDrawSurfaceImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawSurfaceImpl, IDirectDrawSurface4_Vtbl));
}
static IDirectDrawSurface4 *dds4_from_impl(IDirectDrawSurfaceImpl *This)
{
    if(!This) return NULL;
    return (IDirectDrawSurface4 *) &This->IDirectDrawSurface4_Vtbl;
}

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

    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
    *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 = dds4_from_impl(This);
        IDirectDrawSurface4_AddRef((IDirectDrawSurface4 *) *obj);
        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(dds4_from_impl(This), riid, obj);
}

static ULONG WINAPI
IDirectDrawSurface4Impl_AddRef(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This));
}

static ULONG WINAPI
IDirectDrawSurface4Impl_Release(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This));
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_AddAttachedSurface(IDirectDrawSurface4 *iface,
                                           IDirectDrawSurface4 *Attach_iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    IDirectDrawSurfaceImpl *attach = impl_from_dds4(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(dds4_from_impl(This), dds4_from_impl(attach));
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_AddOverlayDirtyRect(IDirectDrawSurface4 *iface,
                                            RECT *Rect)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Rect);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_Blt(IDirectDrawSurface4 *iface,
                            RECT *DestRect,
                            IDirectDrawSurface4 *SrcSurface,
                            RECT *SrcRect,
                            DWORD Flags,
                            DDBLTFX *DDBltFx)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    IDirectDrawSurfaceImpl *Src = impl_from_dds4(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(dds4_from_impl(This), DestRect, dds4_from_impl(Src),
                                   SrcRect, Flags, DDBltFx);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_BltBatch(IDirectDrawSurface4 *iface,
                                 DDBLTBATCH *Batch,
                                 DWORD Count,
                                 DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Batch, Count, Flags);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_BltFast(IDirectDrawSurface4 *iface,
                                DWORD dstx,
                                DWORD dsty,
                                IDirectDrawSurface4 *Source,
                                RECT *rsrc,
                                DWORD trans)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    IDirectDrawSurfaceImpl *Src = impl_from_dds4(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(dds4_from_impl(This), dstx, dsty, dds4_from_impl(Src),
                                       rsrc, trans);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_DeleteAttachedSurface(IDirectDrawSurface4 *iface,
                                              DWORD Flags,
                                              IDirectDrawSurface4 *Attach)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    IDirectDrawSurfaceImpl *Att = impl_from_dds4(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(dds4_from_impl(This), Flags,
                                                     dds4_from_impl(Att));
}

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_dds4(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 = impl_from_dds4(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(dds4_from_impl(This), &ctx, enumsurfaces_thunk_cb);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumOverlayZOrders(IDirectDrawSurface4 *iface,
                                           DWORD Flags,
                                           void *context,
                                           LPDDENUMSURFACESCALLBACK2 cb)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Flags, &ctx, enumsurfaces_thunk_cb);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_Flip(IDirectDrawSurface4 *iface,
                             IDirectDrawSurface4 *DestOverride,
                             DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    IDirectDrawSurfaceImpl *Dest = impl_from_dds4(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(dds4_from_impl(This), dds4_from_impl(Dest), Flags);
}

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

    hr = IDirectDrawSurface4_GetAttachedSurface(dds4_from_impl(This), 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(dds4_from_impl(This), &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_dds4(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(dds4_from_impl(This), Flags);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetCaps(IDirectDrawSurface4 *iface,
                                DDSCAPS2 *Caps)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), &caps2);
    Caps->dwCaps = caps2.dwCaps;
    return hr;
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetClipper(IDirectDrawSurface4 *iface,
                                   IDirectDrawClipper **Clipper)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Clipper);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetColorKey(IDirectDrawSurface4 *iface,
                                    DWORD Flags,
                                    DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Flags, CKey);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDC(IDirectDrawSurface4 *iface,
                             HDC *hdc)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), hdc);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetFlipStatus(IDirectDrawSurface4 *iface,
                                      DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Flags);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetOverlayPosition(IDirectDrawSurface4 *iface,
                                           LONG *X,
                                           LONG *Y)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), X, Y);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPalette(IDirectDrawSurface4 *iface,
                                   IDirectDrawPalette **Pal)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Pal);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPixelFormat(IDirectDrawSurface4 *iface,
                                       DDPIXELFORMAT *PixelFormat)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), PixelFormat);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetSurfaceDesc(IDirectDrawSurface4 *iface,
                                       DDSURFACEDESC2 *DDSD)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), &ddsd2);
    DDSD2_to_DDSD(&ddsd2, DDSD);
    return hr;
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_Initialize(IDirectDrawSurface4 *iface,
                                   IDirectDraw *DD,
                                   DDSURFACEDESC2 *DDSD)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), DD, &ddsd2);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_IsLost(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This));
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_Lock(IDirectDrawSurface4 *iface,
                             RECT *Rect,
                             DDSURFACEDESC2 *DDSD,
                             DWORD Flags,
                             HANDLE h)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Rect, &ddsd2, Flags, h);
    DDSD2_to_DDSD(&ddsd2, DDSD);
    return hr;
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_ReleaseDC(IDirectDrawSurface4 *iface,
                                  HDC hdc)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), hdc);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_Restore(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This));
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_SetClipper(IDirectDrawSurface4 *iface,
                                   IDirectDrawClipper *Clipper)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Clipper);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_SetColorKey(IDirectDrawSurface4 *iface,
                                    DWORD Flags,
                                    DDCOLORKEY *CKey)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Flags, CKey);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_SetOverlayPosition(IDirectDrawSurface4 *iface,
                                           LONG X,
                                           LONG Y)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), X, Y);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_SetPalette(IDirectDrawSurface4 *iface,
                                   IDirectDrawPalette *Pal)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Pal);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_Unlock(IDirectDrawSurface4 *iface,
                               RECT *pRect)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), NULL);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlay(IDirectDrawSurface4 *iface,
                                      LPRECT SrcRect,
                                      IDirectDrawSurface4 *DstSurface,
                                      LPRECT DstRect,
                                      DWORD Flags,
                                      LPDDOVERLAYFX FX)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    IDirectDrawSurfaceImpl *Dst = impl_from_dds4(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(dds4_from_impl(This), SrcRect, dds4_from_impl(Dst),
                                             DstRect, Flags, FX);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayDisplay(IDirectDrawSurface4 *iface,
                                             DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Flags);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayZOrder(IDirectDrawSurface4 *iface,
                                            DWORD Flags,
                                            IDirectDrawSurface4 *DDSRef)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    IDirectDrawSurfaceImpl *Ref = impl_from_dds4(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(dds4_from_impl(This), Flags, dds4_from_impl(Ref));
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDDInterface(IDirectDrawSurface4 *iface,
                                       void **DD)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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_dds4(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(dds4_from_impl(This), Flags);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_PageUnlock(IDirectDrawSurface4 *iface,
                                  DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), Flags);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_SetSurfaceDesc(IDirectDrawSurface4 *iface,
                                       DDSURFACEDESC2 *DDSD,
                                       DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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(dds4_from_impl(This), &ddsd, Flags);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_SetPrivateData(IDirectDrawSurface4 *iface,
                                       REFGUID tag,
                                       void *Data,
                                       DWORD Size,
                                       DWORD Flags)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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_dds4(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_dds4(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,
                                           LPDWORD pValue)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(iface);
    TRACE("(%p)->(%p)\n", This, pValue);
    return IDirectDrawSurface4_GetUniquenessValue(This->parent, pValue);
}

static HRESULT WINAPI
IDirectDrawSurface4Impl_ChangeUniquenessValue(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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);
}

/* 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_Vtbl = &IDirectDrawSurface4_Vtbl;
        IDirectDrawSurface4_AddRef(inner);
        impl->parent = inner;

        outer = dds4_from_impl(impl);

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

    return outer;
}

IDirectDrawSurface4 *dds_get_inner(IDirectDrawSurface4 *outer)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(outer);
    if(This == NULL) return NULL;
    return This->parent;
}

HRESULT prepare_permanent_dc(IDirectDrawSurface4 *iface)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds4(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;
}
