/*
 * 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_dds3(IDirectDrawSurface3 *iface)
{
    if(!iface) return NULL;
    return (IDirectDrawSurfaceImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawSurfaceImpl, IDirectDrawSurface3_Vtbl));
}
static IDirectDrawSurface3 *dds3_from_impl(IDirectDrawSurfaceImpl *This)
{
    if(!This) return NULL;
    return (IDirectDrawSurface3 *) &This->IDirectDrawSurface3_Vtbl;
}

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 = dds3_from_impl(This);
        IDirectDrawSurface3_AddRef((IDirectDrawSurface3 *) *obj);
        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_dds3(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_dds3(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_dds3(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_dds3(iface);
    IDirectDrawSurfaceImpl *attach = impl_from_dds3(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_dds3(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_dds3(iface);
    IDirectDrawSurfaceImpl *Src = impl_from_dds3(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_dds3(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_dds3(iface);
    IDirectDrawSurfaceImpl *Src = impl_from_dds3(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_dds3(iface);
    IDirectDrawSurfaceImpl *Att = impl_from_dds3(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(dds3_from_impl(This));
    IDirectDrawSurface3_Release(surf);
    DDSD2_to_DDSD(desc2, &desc);
    return ctx->orig_cb((IDirectDrawSurface *) dds3_from_impl(This), &desc, ctx->orig_ctx);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_EnumAttachedSurfaces(IDirectDrawSurface3 *iface,
                                             void *context,
                                             LPDDENUMSURFACESCALLBACK cb)
{
    IDirectDrawSurfaceImpl *This = impl_from_dds3(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_dds3(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_dds3(iface);
    IDirectDrawSurfaceImpl *Dest = impl_from_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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_dds3(iface);
    IDirectDrawSurfaceImpl *Dst = impl_from_dds3(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_dds3(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_dds3(iface);
    IDirectDrawSurfaceImpl *Ref = impl_from_dds3(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_dds3(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_dds3(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_dds3(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_dds3(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);
}

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
};

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,
};

/* 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_Vtbl = &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;
}
