From 0d80130aa21211eae6dba12498c3a6256b5fa046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Thu, 18 Dec 2008 15:40:55 +0100 Subject: [PATCH] ddrawex: Create a surface wrapper. --- dlls/ddrawex/Makefile.in | 3 +- dlls/ddrawex/ddraw.c | 80 +- dlls/ddrawex/ddrawex_private.h | 26 + dlls/ddrawex/surface.c | 1261 ++++++++++++++++++++++++++++++++ 4 files changed, 1359 insertions(+), 11 deletions(-) create mode 100644 dlls/ddrawex/surface.c diff --git a/dlls/ddrawex/Makefile.in b/dlls/ddrawex/Makefile.in index e6b927bf5be..f2ec08082e7 100644 --- a/dlls/ddrawex/Makefile.in +++ b/dlls/ddrawex/Makefile.in @@ -8,7 +8,8 @@ IMPORTS = dxguid uuid ddraw ole32 advapi32 kernel32 C_SRCS = \ ddraw.c \ main.c \ - regsvr.c + regsvr.c \ + surface.c @MAKE_DLL_RULES@ diff --git a/dlls/ddrawex/ddraw.c b/dlls/ddrawex/ddraw.c index f3c5c4138c8..9645a3de6af 100644 --- a/dlls/ddrawex/ddraw.c +++ b/dlls/ddrawex/ddraw.c @@ -386,6 +386,7 @@ IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface, IUnknown *UnkOuter) { IDirectDrawImpl *This = impl_from_dd4(iface); + HRESULT hr; TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter); if(UnkOuter != NULL) @@ -394,10 +395,12 @@ IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface, FIXME("Implement aggregation for ddrawex surfaces\n"); } - return IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter); + hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter); + *Surf = dds_get_outer(*Surf); + return hr; } -static void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out) +void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out) { memset(out, 0, sizeof(*out)); out->dwSize = sizeof(*out); @@ -410,7 +413,8 @@ static void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out) if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount; if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwMipMapCount = in->dwZBufferBitDepth; /* same union */ if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth; - if(in->dwFlags & DDSD_LPSURFACE) out->lpSurface = in->lpSurface; + /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */ + out->lpSurface = in->lpSurface; if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay; if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt; if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay; @@ -423,7 +427,7 @@ static void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out) */ } -static void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) +void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) { memset(out, 0, sizeof(*out)); out->dwSize = sizeof(*out); @@ -436,7 +440,8 @@ static void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount; if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwZBufferBitDepth = in->dwMipMapCount; /* same union */ if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth; - if(in->dwFlags & DDSD_LPSURFACE) out->lpSurface = in->lpSurface; + /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */ + out->lpSurface = in->lpSurface; if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay; if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt; if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay; @@ -474,6 +479,7 @@ IDirectDraw3Impl_CreateSurface(IDirectDraw3 *iface, return hr; } + TRACE("Got surface %p\n", surf4); IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf); IDirectDrawSurface4_Release(surf4); return hr; @@ -507,9 +513,9 @@ IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface, IDirectDrawSurface4 **dst) { IDirectDrawImpl *This = impl_from_dd4(iface); - TRACE("(%p)->(%p,%p)\n", This, src, dst); + FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst); - return IDirectDraw4_DuplicateSurface(This->parent, src, dst); + return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(src), dst); } static HRESULT WINAPI @@ -628,6 +634,23 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw *iface, return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb); } +struct enumsurfaces4_ctx +{ + LPDDENUMSURFACESCALLBACK2 orig_cb; + void *orig_ctx; +}; + +static HRESULT WINAPI +enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx) +{ + struct enumsurfaces4_ctx *ctx = (struct enumsurfaces4_ctx *) vctx; + IDirectDrawSurface4 *outer = dds_get_outer(surf4); + IDirectDrawSurface4_AddRef(outer); + IDirectDrawSurface4_Release(surf4); + TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4); + return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx); +} + static HRESULT WINAPI IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface, DWORD Flags, @@ -636,9 +659,12 @@ IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface, LPDDENUMSURFACESCALLBACK2 Callback) { IDirectDrawImpl *This = impl_from_dd4(iface); + struct enumsurfaces4_ctx *ctx; TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback); - return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, Context, Callback); + ctx->orig_cb = Callback; + ctx->orig_ctx = Context; + return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, &ctx, enum_surfaces_wrapper); } struct enumsurfaces_ctx @@ -864,8 +890,22 @@ IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface, IDirectDrawSurface4 **GDISurface) { IDirectDrawImpl *This = impl_from_dd4(iface); + IDirectDrawSurface4 *inner = NULL; + HRESULT hr; TRACE("(%p)->(%p)\n", This, GDISurface); - return IDirectDraw4_GetGDISurface(This->parent, GDISurface); + + hr = IDirectDraw4_GetGDISurface(This->parent, &inner); + if(SUCCEEDED(hr)) + { + *GDISurface = dds_get_outer(inner); + IDirectDrawSurface4_AddRef(*GDISurface); + IDirectDrawSurface4_Release(inner); + } + else + { + *GDISurface = NULL; + } + return hr; } static HRESULT WINAPI @@ -1258,8 +1298,22 @@ IDirectDraw4Impl_GetSurfaceFromDC(IDirectDraw4 *iface, IDirectDrawSurface4 **Surface) { IDirectDrawImpl *This = impl_from_dd4(iface); + IDirectDrawSurface4 *inner; + HRESULT hr; TRACE("(%p)->(%p, %p)\n", This, hdc, Surface); - return IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, Surface); + hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, &inner); + if(SUCCEEDED(hr)) + { + *Surface = dds_get_outer(inner); + IDirectDrawSurface4_AddRef(*Surface); + IDirectDrawSurface4_Release(inner); + } + else + { + *Surface = NULL; + } + + return hr; } static HRESULT WINAPI @@ -1482,3 +1536,9 @@ err: *ppDirectDraw = NULL; return hr; } + +IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer) +{ + IDirectDrawImpl *This = impl_from_dd4(outer); + return This->parent; +} diff --git a/dlls/ddrawex/ddrawex_private.h b/dlls/ddrawex/ddrawex_private.h index e9396dbeb53..12d76d5293c 100644 --- a/dlls/ddrawex/ddrawex_private.h +++ b/dlls/ddrawex/ddrawex_private.h @@ -67,6 +67,9 @@ HRESULT WINAPI IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface GUID * pGUID, HWND hWnd, DWORD dwCoopLevelFlags, DWORD dwReserved, IUnknown *pUnkOuter, IDirectDraw **ppDirectDraw); +void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out); +void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out); + /****************************************************************************** * IDirectDraw wrapper implementation ******************************************************************************/ @@ -82,4 +85,27 @@ typedef struct IDirectDraw4 *parent; } IDirectDrawImpl; +IDirectDraw4 *dd_get_outer(IDirectDraw4 *inner); +IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer); + +/****************************************************************************** + * IDirectDrawSurface implementation + ******************************************************************************/ +typedef struct +{ + const IDirectDrawSurface3Vtbl *IDirectDrawSurface3_Vtbl; + const IDirectDrawSurface4Vtbl *IDirectDrawSurface4_Vtbl; + LONG ref; + + /* The interface we're forwarding to */ + IDirectDrawSurface4 *parent; + + /* An UUID we use to store the outer surface as private data in the inner surface */ +#define IID_DDrawexPriv IID_IDirectDrawSurface4 + +} IDirectDrawSurfaceImpl; + +IDirectDrawSurface4 *dds_get_outer(IDirectDrawSurface4 *inner); +IDirectDrawSurface4 *dds_get_inner(IDirectDrawSurface4 *outer); + #endif /* __WINE_DLLS_DDRAWEX_DDRAWEX_PRIVATE_H */ diff --git a/dlls/ddrawex/surface.c b/dlls/ddrawex/surface.c new file mode 100644 index 00000000000..9b16ce51109 --- /dev/null +++ b/dlls/ddrawex/surface.c @@ -0,0 +1,1261 @@ +/* + * 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 = (struct enumsurfaces_wrap *) 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 = (struct enumsurfaces_thunk *) 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); + 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); + TRACE("(%p)->(%p)\n", This, DDSD); + return IDirectDrawSurface4_GetSurfaceDesc(This->parent, DDSD); +} + +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); + TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This, Rect, DDSD, Flags, h); + return IDirectDrawSurface4_Lock(This->parent, Rect, DDSD, Flags, h); +} + +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); + 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; +}