From efcecb9b99331a39f2f96d456df280a15a9557ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Fri, 9 Jan 2009 12:23:17 +0100 Subject: [PATCH] ddrawex: Implement a wrapper around IDirectDraw. This allows us to cleanly implement the differences between ddraw.dll and ddrawex.dll without private functions and if checks if an object was created by ddraw or ddrawex. A similar wrapper will be added for IDirectDrawSurface. --- dlls/ddrawex/Makefile.in | 1 + dlls/ddrawex/ddraw.c | 1484 ++++++++++++++++++++++++++++++++ dlls/ddrawex/ddrawex_private.h | 21 +- dlls/ddrawex/main.c | 32 +- 4 files changed, 1506 insertions(+), 32 deletions(-) create mode 100644 dlls/ddrawex/ddraw.c diff --git a/dlls/ddrawex/Makefile.in b/dlls/ddrawex/Makefile.in index 8cf514b628a..e6b927bf5be 100644 --- a/dlls/ddrawex/Makefile.in +++ b/dlls/ddrawex/Makefile.in @@ -6,6 +6,7 @@ MODULE = ddrawex.dll IMPORTS = dxguid uuid ddraw ole32 advapi32 kernel32 C_SRCS = \ + ddraw.c \ main.c \ regsvr.c diff --git a/dlls/ddrawex/ddraw.c b/dlls/ddrawex/ddraw.c new file mode 100644 index 00000000000..f3c5c4138c8 --- /dev/null +++ b/dlls/ddrawex/ddraw.c @@ -0,0 +1,1484 @@ +/* + * 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 IDirectDrawImpl *impl_from_dd1(IDirectDraw *iface) +{ + return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw_Vtbl)); +} +static IDirectDraw *dd1_from_impl(IDirectDrawImpl *This) +{ + return (IDirectDraw *) &This->IDirectDraw_Vtbl; +} + +static IDirectDrawImpl *impl_from_dd2(IDirectDraw2 *iface) +{ + return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw2_Vtbl)); +} +static IDirectDraw2 *dd2_from_impl(IDirectDrawImpl *This) +{ + return (IDirectDraw2 *) &This->IDirectDraw2_Vtbl; +} + +static IDirectDrawImpl *impl_from_dd3(IDirectDraw3 *iface) +{ + return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw3_Vtbl)); +} +static IDirectDraw3 *dd3_from_impl(IDirectDrawImpl *This) +{ + return (IDirectDraw3 *) &This->IDirectDraw3_Vtbl; +} + +static IDirectDrawImpl *impl_from_dd4(IDirectDraw4 *iface) +{ + return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw4_Vtbl)); +} +static IDirectDraw4 *dd4_from_impl(IDirectDrawImpl *This) +{ + return (IDirectDraw4 *) &This->IDirectDraw4_Vtbl; +} + +/****************************************************************************** + * IDirectDraw4 -> ddraw.dll wrappers + ******************************************************************************/ +static HRESULT WINAPI +IDirectDraw4Impl_QueryInterface(IDirectDraw4 *iface, + REFIID refiid, + void **obj) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj); + *obj = NULL; + + if(!refiid) + { + return DDERR_INVALIDPARAMS; + } + + if (IsEqualGUID( &IID_IDirectDraw7, refiid ) ) + { + WARN("IDirectDraw7 not allowed in ddrawex.dll\n"); + return E_NOINTERFACE; + } + else if ( IsEqualGUID( &IID_IUnknown, refiid ) || + IsEqualGUID( &IID_IDirectDraw4, refiid ) ) + { + *obj = dd4_from_impl(This); + TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj); + IDirectDraw4_AddRef((IDirectDraw4 *) *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) ) + { + *obj = dd3_from_impl(This); + TRACE("(%p) Returning IDirectDraw3 interface at %p\n", This, *obj); + IDirectDraw3_AddRef((IDirectDraw3 *) *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) + { + *obj = dd2_from_impl(This); + TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj); + IDirectDraw2_AddRef((IDirectDraw2 *) *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) + { + *obj = dd1_from_impl(This); + TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj); + IDirectDraw_AddRef((IDirectDraw *) *obj); + } + else if ( IsEqualGUID( &IID_IDirect3D , refiid ) || + IsEqualGUID( &IID_IDirect3D2 , refiid ) || + IsEqualGUID( &IID_IDirect3D3 , refiid ) || + IsEqualGUID( &IID_IDirect3D7 , refiid ) ) + { + WARN("Direct3D not allowed in ddrawex.dll\n"); + return E_NOINTERFACE; + } + /* Unknown interface */ + else + { + ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj); + return E_NOINTERFACE; + } + TRACE("Returning S_OK\n"); + return S_OK; +} + +static HRESULT WINAPI +IDirectDraw3Impl_QueryInterface(IDirectDraw3 *iface, + REFIID refiid, + void **obj) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj); +} + +static HRESULT WINAPI +IDirectDraw2Impl_QueryInterface(IDirectDraw2 *iface, + REFIID refiid, + void **obj) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj); +} + +static HRESULT WINAPI +IDirectDrawImpl_QueryInterface(IDirectDraw *iface, + REFIID refiid, + void **obj) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj); +} + +static ULONG WINAPI +IDirectDraw4Impl_AddRef(IDirectDraw4 *iface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) : incrementing refcount from %u.\n", This, ref - 1); + + return ref; +} + +static ULONG WINAPI +IDirectDraw3Impl_AddRef(IDirectDraw3 *iface) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_AddRef(dd4_from_impl(This)); +} + +static ULONG WINAPI +IDirectDraw2Impl_AddRef(IDirectDraw2 *iface) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_AddRef(dd4_from_impl(This)); +} + +static ULONG WINAPI +IDirectDrawImpl_AddRef(IDirectDraw *iface) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_AddRef(dd4_from_impl(This)); +} + +static ULONG WINAPI +IDirectDraw4Impl_Release(IDirectDraw4 *iface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) : decrementing refcount to %u.\n", This, ref); + + if(ref == 0) + { + TRACE("Destroying object\n"); + IDirectDraw4_Release(This->parent); + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} + +static ULONG WINAPI +IDirectDraw3Impl_Release(IDirectDraw3 *iface) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_Release(dd4_from_impl(This)); +} + +static ULONG WINAPI +IDirectDraw2Impl_Release(IDirectDraw2 *iface) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_Release(dd4_from_impl(This)); +} + +static ULONG WINAPI +IDirectDrawImpl_Release(IDirectDraw *iface) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_Release(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDraw4Impl_Compact(IDirectDraw4 *iface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)\n", This); + + return IDirectDraw4_Compact(This->parent); +} + +static HRESULT WINAPI +IDirectDraw3Impl_Compact(IDirectDraw3 *iface) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_Compact(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDraw2Impl_Compact(IDirectDraw2 *iface) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_Compact(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDrawImpl_Compact(IDirectDraw *iface) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_Compact(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDraw4Impl_CreateClipper(IDirectDraw4 *iface, + DWORD Flags, + IDirectDrawClipper **clipper, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(0x%08x, %p, %p)\n", This, Flags, clipper, UnkOuter); + + if(UnkOuter != NULL) + { + /* This may require a wrapper interface for clippers too which handles this */ + FIXME("Test and implement Aggregation for ddrawex clippers\n"); + } + + return IDirectDraw4_CreateClipper(This->parent, Flags, clipper, UnkOuter); +} + +static HRESULT WINAPI +IDirectDraw3Impl_CreateClipper(IDirectDraw3 *iface, + DWORD Flags, + IDirectDrawClipper **clipper, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter); +} + +static HRESULT WINAPI +IDirectDraw2Impl_CreateClipper(IDirectDraw2 *iface, + DWORD Flags, + IDirectDrawClipper **clipper, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter); +} + +static HRESULT WINAPI +IDirectDrawImpl_CreateClipper(IDirectDraw *iface, + DWORD Flags, + IDirectDrawClipper **clipper, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter); +} + +static HRESULT WINAPI +IDirectDraw4Impl_CreatePalette(IDirectDraw4 *iface, + DWORD Flags, + PALETTEENTRY *ColorTable, + IDirectDrawPalette **Palette, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)(0x%08x,%p,%p,%p)\n", This, Flags, ColorTable, Palette, UnkOuter); + + if(UnkOuter != NULL) + { + /* This may require a wrapper interface for palettes too which handles this */ + FIXME("Test and implement Aggregation for ddrawex palettes\n"); + } + + return IDirectDraw4_CreatePalette(This->parent, Flags, ColorTable, Palette, UnkOuter); +} + +static HRESULT WINAPI +IDirectDraw3Impl_CreatePalette(IDirectDraw3 *iface, + DWORD Flags, + PALETTEENTRY *ColorTable, + IDirectDrawPalette **Palette, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter); +} + +static HRESULT WINAPI +IDirectDraw2Impl_CreatePalette(IDirectDraw2 *iface, + DWORD Flags, + PALETTEENTRY *ColorTable, + IDirectDrawPalette **Palette, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter); +} + +static HRESULT WINAPI +IDirectDrawImpl_CreatePalette(IDirectDraw *iface, + DWORD Flags, + PALETTEENTRY *ColorTable, + IDirectDrawPalette **Palette, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw4\n"); + return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter); +} + +static HRESULT WINAPI +IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface, + DDSURFACEDESC2 *DDSD, + IDirectDrawSurface4 **Surf, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter); + + if(UnkOuter != NULL) + { + /* Handle this in this dll. Don't forward the UnkOuter to ddraw.dll */ + FIXME("Implement aggregation for ddrawex surfaces\n"); + } + + return IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter); +} + +static void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out) +{ + memset(out, 0, sizeof(*out)); + out->dwSize = sizeof(*out); + out->dwFlags = in->dwFlags; + if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth; + if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight; + if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->ddpfPixelFormat; + if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps; + if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch; + 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; + 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; + if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt; + if(in->dwFlags & DDSD_MIPMAPCOUNT) out->dwMipMapCount = in->dwMipMapCount; + if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate; + if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->dwLinearSize; + /* Does not exist in DDSURFACEDESC: + * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE, + */ +} + +static void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) +{ + memset(out, 0, sizeof(*out)); + out->dwSize = sizeof(*out); + out->dwFlags = in->dwFlags; + if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth; + if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight; + if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->ddpfPixelFormat; + if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps; + if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch; + 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; + 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; + if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt; + if(in->dwFlags & DDSD_MIPMAPCOUNT) out->dwMipMapCount = in->dwMipMapCount; + if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate; + if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->dwLinearSize; + /* Does not exist in DDSURFACEDESC: + * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE, + */ + if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n"); + if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n"); + if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n"); + out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE); +} + +static HRESULT WINAPI +IDirectDraw3Impl_CreateSurface(IDirectDraw3 *iface, + DDSURFACEDESC *DDSD, + IDirectDrawSurface **Surf, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + DDSURFACEDESC2 ddsd2; + IDirectDrawSurface4 *surf4 = NULL; + HRESULT hr; + TRACE("Thunking to IDirectDraw4\n"); + + DDSD_to_DDSD2(DDSD, &ddsd2); + + hr = IDirectDraw4_CreateSurface(dd4_from_impl(This), &ddsd2, &surf4, UnkOuter); + if(FAILED(hr)) + { + *Surf = NULL; + return hr; + } + + IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf); + IDirectDrawSurface4_Release(surf4); + return hr; +} + +static HRESULT WINAPI +IDirectDraw2Impl_CreateSurface(IDirectDraw2 *iface, + DDSURFACEDESC *DDSD, + IDirectDrawSurface **Surf, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw3\n"); + return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter); +} + +static HRESULT WINAPI +IDirectDrawImpl_CreateSurface(IDirectDraw *iface, + DDSURFACEDESC *DDSD, + IDirectDrawSurface **Surf, + IUnknown *UnkOuter) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw3\n"); + return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter); +} + +static HRESULT WINAPI +IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface, + IDirectDrawSurface4 *src, + IDirectDrawSurface4 **dst) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p,%p)\n", This, src, dst); + + return IDirectDraw4_DuplicateSurface(This->parent, src, dst); +} + +static HRESULT WINAPI +IDirectDraw3Impl_DuplicateSurface(IDirectDraw3 *iface, + IDirectDrawSurface *src, + IDirectDrawSurface **dst) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + IDirectDrawSurface4 *src_4; + IDirectDrawSurface4 *dst_4; + HRESULT hr; + + TRACE("Thunking to IDirectDraw4\n"); + IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **) &src_4); + hr = IDirectDraw4_DuplicateSurface(dd4_from_impl(This), src_4, &dst_4); + IDirectDrawSurface4_Release(src_4); + + if(FAILED(hr)) + { + *dst = NULL; + return hr; + } + IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **) dst); + IDirectDrawSurface4_Release(dst_4); + return hr; +} + +static HRESULT WINAPI +IDirectDraw2Impl_DuplicateSurface(IDirectDraw2 *iface, + IDirectDrawSurface *src, + IDirectDrawSurface **dst) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("Thunking to IDirectDraw3\n"); + return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst); +} + +static HRESULT WINAPI +IDirectDrawImpl_DuplicateSurface(IDirectDraw *iface, + IDirectDrawSurface *src, + IDirectDrawSurface **dst) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("Thunking to IDirectDraw3\n"); + return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst); +} + +static HRESULT WINAPI +IDirectDraw4Impl_EnumDisplayModes(IDirectDraw4 *iface, + DWORD Flags, + DDSURFACEDESC2 *DDSD, + void *Context, + LPDDENUMMODESCALLBACK2 cb) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, cb); + + return IDirectDraw4_EnumDisplayModes(This->parent, Flags, DDSD, Context, cb); +} + +struct enummodes_ctx +{ + LPDDENUMMODESCALLBACK orig_cb; + void *orig_ctx; +}; + +static HRESULT WINAPI +enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx) +{ + struct enummodes_ctx *ctx = (struct enummodes_ctx *) vctx; + DDSURFACEDESC ddsd; + + DDSD2_to_DDSD(ddsd2, &ddsd); + return ctx->orig_cb(&ddsd, ctx->orig_ctx); +} + +static HRESULT WINAPI +IDirectDraw3Impl_EnumDisplayModes(IDirectDraw3 *iface, + DWORD Flags, + DDSURFACEDESC *DDSD, + void *Context, + LPDDENUMMODESCALLBACK cb) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + DDSURFACEDESC2 ddsd2; + struct enummodes_ctx ctx; + TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, cb); + + DDSD_to_DDSD2(DDSD, &ddsd2); + ctx.orig_cb = cb; + ctx.orig_ctx = Context; + return IDirectDraw4_EnumDisplayModes(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_modes_cb2); +} + +static HRESULT WINAPI +IDirectDraw2Impl_EnumDisplayModes(IDirectDraw2 *iface, + DWORD Flags, + DDSURFACEDESC *DDSD, + void *Context, + LPDDENUMMODESCALLBACK cb) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb); + return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb); +} + +static HRESULT WINAPI +IDirectDrawImpl_EnumDisplayModes(IDirectDraw *iface, + DWORD Flags, + DDSURFACEDESC *DDSD, + void *Context, + LPDDENUMMODESCALLBACK cb) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb); + return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb); +} + +static HRESULT WINAPI +IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface, + DWORD Flags, + DDSURFACEDESC2 *DDSD, + void *Context, + LPDDENUMSURFACESCALLBACK2 Callback) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback); + + return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, Context, Callback); +} + +struct enumsurfaces_ctx +{ + LPDDENUMSURFACESCALLBACK orig_cb; + void *orig_ctx; +}; + +static HRESULT WINAPI +enum_surfaces_cb2(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx) +{ + struct enumsurfaces_ctx *ctx = (struct enumsurfaces_ctx *) vctx; + IDirectDrawSurface *surf1; + DDSURFACEDESC ddsd; + + /* Keep the reference, it goes to the application */ + IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) &surf1); + /* Release the reference this function got */ + IDirectDrawSurface4_Release(surf4); + + DDSD2_to_DDSD(ddsd2, &ddsd); + return ctx->orig_cb(surf1, &ddsd, ctx->orig_ctx); +} + +static HRESULT WINAPI +IDirectDraw3Impl_EnumSurfaces(IDirectDraw3 *iface, + DWORD Flags, + DDSURFACEDESC *DDSD, + void *Context, + LPDDENUMSURFACESCALLBACK Callback) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + DDSURFACEDESC2 ddsd2; + struct enumsurfaces_ctx ctx; + TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, Callback); + + DDSD_to_DDSD2(DDSD, &ddsd2); + ctx.orig_cb = Callback; + ctx.orig_ctx = Context; + return IDirectDraw4_EnumSurfaces(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_surfaces_cb2); +} + +static HRESULT WINAPI +IDirectDraw2Impl_EnumSurfaces(IDirectDraw2 *iface, + DWORD Flags, + DDSURFACEDESC *DDSD, + void *Context, + LPDDENUMSURFACESCALLBACK Callback) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback); + return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback); +} + +static HRESULT WINAPI +IDirectDrawImpl_EnumSurfaces(IDirectDraw *iface, + DWORD Flags, + DDSURFACEDESC *DDSD, + void *Context, + LPDDENUMSURFACESCALLBACK Callback) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback); + return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback); +} + +static HRESULT WINAPI +IDirectDraw4Impl_FlipToGDISurface(IDirectDraw4 *iface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)\n", This); + + return IDirectDraw4_FlipToGDISurface(This->parent); +} + +static HRESULT WINAPI +IDirectDraw3Impl_FlipToGDISurface(IDirectDraw3 *iface) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p). Thunking to IDirectDraw4\n", This); + return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDraw2Impl_FlipToGDISurface(IDirectDraw2 *iface) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p). Thunking to IDirectDraw4\n", This); + return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDrawImpl_FlipToGDISurface(IDirectDraw *iface) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p). Thunking to IDirectDraw4\n", This); + return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetCaps(IDirectDraw4 *iface, + DDCAPS *DriverCaps, + DDCAPS *HELCaps) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps); + return IDirectDraw4_GetCaps(This->parent, DriverCaps, HELCaps); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetCaps(IDirectDraw3 *iface, + DDCAPS *DriverCaps, + DDCAPS *HELCaps) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps); + return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps); +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetCaps(IDirectDraw2 *iface, + DDCAPS *DriverCaps, + DDCAPS *HELCaps) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps); + return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps); +} + +static HRESULT WINAPI +IDirectDrawImpl_GetCaps(IDirectDraw *iface, + DDCAPS *DriverCaps, + DDCAPS *HELCaps) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps); + return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetDisplayMode(IDirectDraw4 *iface, + DDSURFACEDESC2 *DDSD) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p)\n", This, DDSD); + return IDirectDraw4_GetDisplayMode(This->parent, DDSD); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetDisplayMode(IDirectDraw3 *iface, + DDSURFACEDESC *DDSD) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + DDSURFACEDESC2 ddsd2; + HRESULT hr; + + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, DDSD); + hr = IDirectDraw4_GetDisplayMode(dd4_from_impl(This), &ddsd2); + DDSD2_to_DDSD(&ddsd2, DDSD); + return hr; +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetDisplayMode(IDirectDraw2 *iface, + DDSURFACEDESC *DDSD) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD); + return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD); +} + +static HRESULT WINAPI +IDirectDrawImpl_GetDisplayMode(IDirectDraw *iface, + DDSURFACEDESC *DDSD) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD); + return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetFourCCCodes(IDirectDraw4 *iface, + DWORD *NumCodes, + DWORD *Codes) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p, %p):\n", This, NumCodes, Codes); + return IDirectDraw4_GetFourCCCodes(This->parent, NumCodes, Codes); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetFourCCCodes(IDirectDraw3 *iface, + DWORD *NumCodes, + DWORD *Codes) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes); + return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes); +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetFourCCCodes(IDirectDraw2 *iface, + DWORD *NumCodes, + DWORD *Codes) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes); + return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes); +} + +static HRESULT WINAPI +IDirectDrawImpl_GetFourCCCodes(IDirectDraw *iface, + DWORD *NumCodes, + DWORD *Codes) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes); + return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface, + IDirectDrawSurface4 **GDISurface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p)\n", This, GDISurface); + return IDirectDraw4_GetGDISurface(This->parent, GDISurface); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetGDISurface(IDirectDraw3 *iface, + IDirectDrawSurface **GDISurface) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + IDirectDrawSurface4 *surf4; + HRESULT hr; + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, GDISurface); + + hr = IDirectDraw4_GetGDISurface(dd4_from_impl(This), &surf4); + if(FAILED(hr)) { + *GDISurface = NULL; + return hr; + } + + /* Release the reference we got from the DDraw4 call, and pass a reference to the caller */ + IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) GDISurface); + IDirectDrawSurface4_Release(surf4); + return hr; +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetGDISurface(IDirectDraw2 *iface, + IDirectDrawSurface **GDISurface) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface); + return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface); +} + +static HRESULT WINAPI +IDirectDrawImpl_GetGDISurface(IDirectDraw *iface, + IDirectDrawSurface **GDISurface) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface); + return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetMonitorFrequency(IDirectDraw4 *iface, + DWORD *Freq) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p)\n", This, Freq); + return IDirectDraw4_GetMonitorFrequency(This->parent, Freq); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetMonitorFrequency(IDirectDraw3 *iface, + DWORD *Freq) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq); + return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq); +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetMonitorFrequency(IDirectDraw2 *iface, + DWORD *Freq) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq); + return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq); +} + +static HRESULT WINAPI +IDirectDrawImpl_GetMonitorFrequency(IDirectDraw *iface, + DWORD *Freq) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq); + return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetScanLine(IDirectDraw4 *iface, + DWORD *Scanline) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p)\n", This, Scanline); + return IDirectDraw4_GetScanLine(This->parent, Scanline); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetScanLine(IDirectDraw3 *iface, + DWORD *Scanline) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline); + return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline); +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetScanLine(IDirectDraw2 *iface, + DWORD *Scanline) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline); + return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline); +} + +static HRESULT WINAPI +IDirectDrawImpl_GetScanLine(IDirectDraw *iface, + DWORD *Scanline) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline); + return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetVerticalBlankStatus(IDirectDraw4 *iface, + BOOL *status) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p)\n", This, status); + return IDirectDraw4_GetVerticalBlankStatus(This->parent, status); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetVerticalBlankStatus(IDirectDraw3 *iface, + BOOL *status) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status); + return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status); +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetVerticalBlankStatus(IDirectDraw2 *iface, + BOOL *status) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status); + return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status); +} + +static HRESULT WINAPI +IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw *iface, + BOOL *status) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status); + return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status); +} + +static HRESULT WINAPI +IDirectDraw4Impl_Initialize(IDirectDraw4 *iface, + GUID *Guid) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%s)\n", This, debugstr_guid(Guid)); + return IDirectDraw4_Initialize(This->parent, Guid); +} + +static HRESULT WINAPI +IDirectDraw3Impl_Initialize(IDirectDraw3 *iface, + GUID *Guid) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid)); + return IDirectDraw4_Initialize(dd4_from_impl(This), Guid); +} + +static HRESULT WINAPI +IDirectDraw2Impl_Initialize(IDirectDraw2 *iface, + GUID *Guid) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid)); + return IDirectDraw4_Initialize(dd4_from_impl(This), Guid); +} + +static HRESULT WINAPI +IDirectDrawImpl_Initialize(IDirectDraw *iface, + GUID *Guid) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid)); + return IDirectDraw4_Initialize(dd4_from_impl(This), Guid); +} + +static HRESULT WINAPI +IDirectDraw4Impl_RestoreDisplayMode(IDirectDraw4 *iface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)\n", This); + return IDirectDraw4_RestoreDisplayMode(This->parent); +} + +static HRESULT WINAPI +IDirectDraw3Impl_RestoreDisplayMode(IDirectDraw3 *iface) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p): Thunking to IDirectDraw4\n", This); + return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDraw2Impl_RestoreDisplayMode(IDirectDraw2 *iface) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p): Thunking to IDirectDraw4\n", This); + return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDrawImpl_RestoreDisplayMode(IDirectDraw *iface) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p): Thunking to IDirectDraw4\n", This); + return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This)); +} + +static HRESULT WINAPI +IDirectDraw4Impl_SetCooperativeLevel(IDirectDraw4 *iface, + HWND hwnd, + DWORD cooplevel) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p, 0x%08x)\n", This, hwnd, cooplevel); + return IDirectDraw4_SetCooperativeLevel(This->parent, hwnd, cooplevel); +} + +static HRESULT WINAPI +IDirectDraw3Impl_SetCooperativeLevel(IDirectDraw3 *iface, + HWND hwnd, + DWORD cooplevel) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel); + return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel); +} + +static HRESULT WINAPI +IDirectDraw2Impl_SetCooperativeLevel(IDirectDraw2 *iface, + HWND hwnd, + DWORD cooplevel) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel); + return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel); +} + +static HRESULT WINAPI +IDirectDrawImpl_SetCooperativeLevel(IDirectDraw *iface, + HWND hwnd, + DWORD cooplevel) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel); + return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel); +} + +static HRESULT WINAPI +IDirectDraw4Impl_SetDisplayMode(IDirectDraw4 *iface, + DWORD Width, + DWORD Height, + DWORD BPP, + DWORD RefreshRate, + DWORD Flags) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%u, %u, %u, %u, 0x%08x)\n", This, Width, Height, BPP, RefreshRate, Flags); + return IDirectDraw4_SetDisplayMode(This->parent, Width, Height, BPP, RefreshRate, Flags); +} + +static HRESULT WINAPI +IDirectDraw3Impl_SetDisplayMode(IDirectDraw3 *iface, + DWORD Width, + DWORD Height, + DWORD BPP, + DWORD RefreshRate, + DWORD Flags) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags); + return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags); +} + +static HRESULT WINAPI +IDirectDraw2Impl_SetDisplayMode(IDirectDraw2 *iface, + DWORD Width, + DWORD Height, + DWORD BPP, + DWORD RefreshRate, + DWORD Flags) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags); + return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags); +} + +static HRESULT WINAPI +IDirectDrawImpl_SetDisplayMode(IDirectDraw *iface, + DWORD Width, + DWORD Height, + DWORD BPP) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(%u, %u, %u): Thunking to IDirectDraw4\n", This, Width, Height, BPP); + return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, 0, 0); +} + +static HRESULT WINAPI +IDirectDraw4Impl_WaitForVerticalBlank(IDirectDraw4 *iface, + DWORD Flags, + HANDLE h) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(0x%08x, %p)\n", This, Flags, h); + return IDirectDraw4_WaitForVerticalBlank(This->parent, Flags, h); +} + +static HRESULT WINAPI +IDirectDraw3Impl_WaitForVerticalBlank(IDirectDraw3 *iface, + DWORD Flags, + HANDLE h) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h); + return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h); +} + +static HRESULT WINAPI +IDirectDraw2Impl_WaitForVerticalBlank(IDirectDraw2 *iface, + DWORD Flags, + HANDLE h) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h); + return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h); +} + +static HRESULT WINAPI +IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw *iface, + DWORD Flags, + HANDLE h) +{ + IDirectDrawImpl *This = impl_from_dd1(iface); + TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h); + return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetAvailableVidMem(IDirectDraw4 *iface, + DDSCAPS2 *Caps, + DWORD *total, + DWORD *free) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free); + return IDirectDraw4_GetAvailableVidMem(This->parent, Caps, total, free); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetAvailableVidMem(IDirectDraw3 *iface, + DDSCAPS *Caps, + DWORD *total, + DWORD *free) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + DDSCAPS2 caps2; + TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free); + memset(&caps2, 0, sizeof(caps2)); + caps2.dwCaps = Caps->dwCaps; + return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free); +} + +static HRESULT WINAPI +IDirectDraw2Impl_GetAvailableVidMem(IDirectDraw2 *iface, + DDSCAPS *Caps, + DWORD *total, + DWORD *free) +{ + IDirectDrawImpl *This = impl_from_dd2(iface); + DDSCAPS2 caps2; + TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free); + memset(&caps2, 0, sizeof(caps2)); + caps2.dwCaps = Caps->dwCaps; + return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetSurfaceFromDC(IDirectDraw4 *iface, + HDC hdc, + IDirectDrawSurface4 **Surface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p, %p)\n", This, hdc, Surface); + return IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, Surface); +} + +static HRESULT WINAPI +IDirectDraw3Impl_GetSurfaceFromDC(IDirectDraw3 *iface, + HDC hdc, + IDirectDrawSurface **Surface) +{ + IDirectDrawImpl *This = impl_from_dd3(iface); + IDirectDrawSurface4 *surf4; + HRESULT hr; + TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, hdc, Surface); + + hr = IDirectDraw4_GetSurfaceFromDC(dd4_from_impl(This), hdc, &surf4); + if(FAILED(hr)) + { + *Surface = NULL; + return hr; + } + IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surface); + IDirectDrawSurface4_Release(surf4); + return hr; +} + +static HRESULT WINAPI +IDirectDraw4Impl_RestoreAllSurfaces(IDirectDraw4 *iface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)\n", This); + return IDirectDraw4_RestoreAllSurfaces(This->parent); +} + +static HRESULT WINAPI +IDirectDraw4Impl_TestCooperativeLevel(IDirectDraw4 *iface) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)\n", This); + return IDirectDraw4_TestCooperativeLevel(This->parent); +} + +static HRESULT WINAPI +IDirectDraw4Impl_GetDeviceIdentifier(IDirectDraw4 *iface, + DDDEVICEIDENTIFIER *DDDI, + DWORD Flags) +{ + IDirectDrawImpl *This = impl_from_dd4(iface); + TRACE("(%p)->(%p,0x%08x)\n", This, DDDI, Flags); + return IDirectDraw4_GetDeviceIdentifier(This->parent, DDDI, Flags); +} + +static const IDirectDrawVtbl IDirectDraw1_Vtbl = +{ + IDirectDrawImpl_QueryInterface, + IDirectDrawImpl_AddRef, + IDirectDrawImpl_Release, + IDirectDrawImpl_Compact, + IDirectDrawImpl_CreateClipper, + IDirectDrawImpl_CreatePalette, + IDirectDrawImpl_CreateSurface, + IDirectDrawImpl_DuplicateSurface, + IDirectDrawImpl_EnumDisplayModes, + IDirectDrawImpl_EnumSurfaces, + IDirectDrawImpl_FlipToGDISurface, + IDirectDrawImpl_GetCaps, + IDirectDrawImpl_GetDisplayMode, + IDirectDrawImpl_GetFourCCCodes, + IDirectDrawImpl_GetGDISurface, + IDirectDrawImpl_GetMonitorFrequency, + IDirectDrawImpl_GetScanLine, + IDirectDrawImpl_GetVerticalBlankStatus, + IDirectDrawImpl_Initialize, + IDirectDrawImpl_RestoreDisplayMode, + IDirectDrawImpl_SetCooperativeLevel, + IDirectDrawImpl_SetDisplayMode, + IDirectDrawImpl_WaitForVerticalBlank, +}; + +static const IDirectDraw2Vtbl IDirectDraw2_Vtbl = +{ + IDirectDraw2Impl_QueryInterface, + IDirectDraw2Impl_AddRef, + IDirectDraw2Impl_Release, + IDirectDraw2Impl_Compact, + IDirectDraw2Impl_CreateClipper, + IDirectDraw2Impl_CreatePalette, + IDirectDraw2Impl_CreateSurface, + IDirectDraw2Impl_DuplicateSurface, + IDirectDraw2Impl_EnumDisplayModes, + IDirectDraw2Impl_EnumSurfaces, + IDirectDraw2Impl_FlipToGDISurface, + IDirectDraw2Impl_GetCaps, + IDirectDraw2Impl_GetDisplayMode, + IDirectDraw2Impl_GetFourCCCodes, + IDirectDraw2Impl_GetGDISurface, + IDirectDraw2Impl_GetMonitorFrequency, + IDirectDraw2Impl_GetScanLine, + IDirectDraw2Impl_GetVerticalBlankStatus, + IDirectDraw2Impl_Initialize, + IDirectDraw2Impl_RestoreDisplayMode, + IDirectDraw2Impl_SetCooperativeLevel, + IDirectDraw2Impl_SetDisplayMode, + IDirectDraw2Impl_WaitForVerticalBlank, + IDirectDraw2Impl_GetAvailableVidMem +}; + +static const IDirectDraw3Vtbl IDirectDraw3_Vtbl = +{ + IDirectDraw3Impl_QueryInterface, + IDirectDraw3Impl_AddRef, + IDirectDraw3Impl_Release, + IDirectDraw3Impl_Compact, + IDirectDraw3Impl_CreateClipper, + IDirectDraw3Impl_CreatePalette, + IDirectDraw3Impl_CreateSurface, + IDirectDraw3Impl_DuplicateSurface, + IDirectDraw3Impl_EnumDisplayModes, + IDirectDraw3Impl_EnumSurfaces, + IDirectDraw3Impl_FlipToGDISurface, + IDirectDraw3Impl_GetCaps, + IDirectDraw3Impl_GetDisplayMode, + IDirectDraw3Impl_GetFourCCCodes, + IDirectDraw3Impl_GetGDISurface, + IDirectDraw3Impl_GetMonitorFrequency, + IDirectDraw3Impl_GetScanLine, + IDirectDraw3Impl_GetVerticalBlankStatus, + IDirectDraw3Impl_Initialize, + IDirectDraw3Impl_RestoreDisplayMode, + IDirectDraw3Impl_SetCooperativeLevel, + IDirectDraw3Impl_SetDisplayMode, + IDirectDraw3Impl_WaitForVerticalBlank, + IDirectDraw3Impl_GetAvailableVidMem, + IDirectDraw3Impl_GetSurfaceFromDC, +}; + +static const IDirectDraw4Vtbl IDirectDraw4_Vtbl = +{ + IDirectDraw4Impl_QueryInterface, + IDirectDraw4Impl_AddRef, + IDirectDraw4Impl_Release, + IDirectDraw4Impl_Compact, + IDirectDraw4Impl_CreateClipper, + IDirectDraw4Impl_CreatePalette, + IDirectDraw4Impl_CreateSurface, + IDirectDraw4Impl_DuplicateSurface, + IDirectDraw4Impl_EnumDisplayModes, + IDirectDraw4Impl_EnumSurfaces, + IDirectDraw4Impl_FlipToGDISurface, + IDirectDraw4Impl_GetCaps, + IDirectDraw4Impl_GetDisplayMode, + IDirectDraw4Impl_GetFourCCCodes, + IDirectDraw4Impl_GetGDISurface, + IDirectDraw4Impl_GetMonitorFrequency, + IDirectDraw4Impl_GetScanLine, + IDirectDraw4Impl_GetVerticalBlankStatus, + IDirectDraw4Impl_Initialize, + IDirectDraw4Impl_RestoreDisplayMode, + IDirectDraw4Impl_SetCooperativeLevel, + IDirectDraw4Impl_SetDisplayMode, + IDirectDraw4Impl_WaitForVerticalBlank, + IDirectDraw4Impl_GetAvailableVidMem, + IDirectDraw4Impl_GetSurfaceFromDC, + IDirectDraw4Impl_RestoreAllSurfaces, + IDirectDraw4Impl_TestCooperativeLevel, + IDirectDraw4Impl_GetDeviceIdentifier +}; + +/******************************************************************************* + * IDirectDrawFactoryImpl_CreateDirectDraw + *******************************************************************************/ +HRESULT WINAPI +IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface, + GUID * pGUID, + HWND hWnd, + DWORD dwCoopLevelFlags, + DWORD dwReserved, + IUnknown *pUnkOuter, + IDirectDraw **ppDirectDraw) +{ + HRESULT hr; + IDirectDrawImpl *object = NULL; + IDirectDraw *parent = NULL; + + TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p,%p)", iface, debugstr_guid(pGUID), hWnd, dwCoopLevelFlags, + dwReserved, pUnkOuter, ppDirectDraw); + + if(pUnkOuter) + { + FIXME("Implement aggregation in ddrawex's IDirectDraw interface\n"); + } + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if(!object) + { + ERR("Out of memory\n"); + hr = E_OUTOFMEMORY; + goto err; + } + object->ref = 1; + object->IDirectDraw_Vtbl = &IDirectDraw1_Vtbl; + object->IDirectDraw2_Vtbl = &IDirectDraw2_Vtbl; + object->IDirectDraw3_Vtbl = &IDirectDraw3_Vtbl; + object->IDirectDraw4_Vtbl = &IDirectDraw4_Vtbl; + + hr = DirectDrawCreate(pGUID, &parent, NULL); + if (FAILED(hr)) goto err; + + hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **) &object->parent); + if(FAILED(hr)) goto err; + + hr = IDirectDraw_SetCooperativeLevel(dd1_from_impl(object), hWnd, dwCoopLevelFlags); + if (FAILED(hr)) goto err; + + *ppDirectDraw = dd1_from_impl(object); + IDirectDraw_Release(parent); + return DD_OK; + +err: + if(object && object->parent) IDirectDraw4_Release(object->parent); + if(parent) IDirectDraw_Release(parent); + if(object) HeapFree(GetProcessHeap(), 0, object); + *ppDirectDraw = NULL; + return hr; +} diff --git a/dlls/ddrawex/ddrawex_private.h b/dlls/ddrawex/ddrawex_private.h index 117ddba1fe6..e9396dbeb53 100644 --- a/dlls/ddrawex/ddrawex_private.h +++ b/dlls/ddrawex/ddrawex_private.h @@ -55,7 +55,7 @@ typedef struct /****************************************************************************** - * DirectDrawFactopry implementation + * DirectDrawFactory implementation ******************************************************************************/ typedef struct { @@ -63,4 +63,23 @@ typedef struct LONG ref; } IDirectDrawFactoryImpl; +HRESULT WINAPI IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface, + GUID * pGUID, HWND hWnd, DWORD dwCoopLevelFlags, DWORD dwReserved, IUnknown *pUnkOuter, + IDirectDraw **ppDirectDraw); + +/****************************************************************************** + * IDirectDraw wrapper implementation + ******************************************************************************/ +typedef struct +{ + const IDirectDrawVtbl *IDirectDraw_Vtbl; + const IDirectDraw2Vtbl *IDirectDraw2_Vtbl; + const IDirectDraw3Vtbl *IDirectDraw3_Vtbl; + const IDirectDraw4Vtbl *IDirectDraw4_Vtbl; + LONG ref; + + /* The interface we're forwarding to */ + IDirectDraw4 *parent; +} IDirectDrawImpl; + #endif /* __WINE_DLLS_DDRAWEX_DDRAWEX_PRIVATE_H */ diff --git a/dlls/ddrawex/main.c b/dlls/ddrawex/main.c index 6befb957c85..de63f233797 100644 --- a/dlls/ddrawex/main.c +++ b/dlls/ddrawex/main.c @@ -33,7 +33,7 @@ #include "initguid.h" #include "ddrawex_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +WINE_DEFAULT_DEBUG_CHANNEL(ddrawex); /******************************************************************************* @@ -194,36 +194,6 @@ IDirectDrawFactoryImpl_Release(IDirectDrawFactory *iface) return ref; } - -/******************************************************************************* - * IDirectDrawFactoryImpl_CreateDirectDraw - *******************************************************************************/ -static HRESULT WINAPI -IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface, - GUID * pGUID, - HWND hWnd, - DWORD dwCoopLevelFlags, - DWORD dwReserved, - IUnknown *pUnkOuter, - IDirectDraw **ppDirectDraw) -{ - HRESULT hr; - - TRACE("\n"); - - hr = DirectDrawCreateEx(pGUID, (void**)ppDirectDraw, &IID_IDirectDraw3, pUnkOuter); - - if (FAILED(hr)) - return hr; - - hr = IDirectDraw_SetCooperativeLevel(*ppDirectDraw, hWnd, dwCoopLevelFlags); - if (FAILED(hr)) - IDirectDraw_Release(*ppDirectDraw); - - return hr; -} - - /******************************************************************************* * IDirectDrawFactoryImpl_DirectDrawEnumerate *******************************************************************************/