| /* | |
| * 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 | |
| */ | |
| #define COBJMACROS | |
| #define NONAMELESSUNION | |
| #include <stdarg.h> | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "wingdi.h" | |
| #include "ddraw.h" | |
| #include "d3d.h" | |
| #include "ddrawex_private.h" | |
| #include "wine/debug.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); | |
| HRESULT hr; | |
| const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY; | |
| BOOL permanent_dc; | |
| 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"); | |
| } | |
| /* plain ddraw.dll refuses to create a surface that has both VIDMEM and SYSMEM flags | |
| * set. In ddrawex this succeeds, and the GetDC() call changes the behavior. The DC | |
| * is permanently valid, and the surface can be locked between GetDC() and ReleaseDC() | |
| * calls. GetDC() can be called more than once too | |
| */ | |
| if((DDSD->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags) | |
| { | |
| permanent_dc = TRUE; | |
| DDSD->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; | |
| DDSD->ddsCaps.dwCaps |= DDSCAPS_OWNDC; | |
| } | |
| else | |
| { | |
| permanent_dc = FALSE; | |
| } | |
| hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter); | |
| *Surf = dds_get_outer(*Surf); | |
| if(permanent_dc) prepare_permanent_dc(*Surf); | |
| return hr; | |
| } | |
| 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->u4.ddpfPixelFormat = in->ddpfPixelFormat; | |
| if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps; | |
| if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch; | |
| if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount; | |
| if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwMipMapCount = in->u2.dwZBufferBitDepth; /* same union */ | |
| if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth; | |
| /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */ | |
| out->lpSurface = in->lpSurface; | |
| if(in->dwFlags & DDSD_CKDESTOVERLAY) out->u3.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->u2.dwMipMapCount = in->u2.dwMipMapCount; | |
| if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate; | |
| if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize; | |
| /* Does not exist in DDSURFACEDESC: | |
| * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE, | |
| */ | |
| } | |
| 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->u4.ddpfPixelFormat; | |
| if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps; | |
| if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch; | |
| if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount; | |
| if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwZBufferBitDepth = in->u2.dwMipMapCount; /* same union */ | |
| if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth; | |
| /* 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->u3.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->u2.dwMipMapCount = in->u2.dwMipMapCount; | |
| if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate; | |
| if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.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; | |
| } | |
| TRACE("Got surface %p\n", surf4); | |
| 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); | |
| FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst); | |
| return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(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 = 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); | |
| } | |
| 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 = 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, | |
| DDSURFACEDESC2 *DDSD, | |
| void *Context, | |
| 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); | |
| ctx.orig_cb = Callback; | |
| ctx.orig_ctx = Context; | |
| return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, &ctx, enum_surfaces_wrapper); | |
| } | |
| 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 = 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); | |
| IDirectDrawSurface4 *inner = NULL; | |
| HRESULT hr; | |
| TRACE("(%p)->(%p)\n", This, 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 | |
| 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); | |
| IDirectDrawSurface4 *inner; | |
| HRESULT hr; | |
| TRACE("(%p)->(%p, %p)\n", This, 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 | |
| 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)\n", 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); | |
| HeapFree(GetProcessHeap(), 0, object); | |
| *ppDirectDraw = NULL; | |
| return hr; | |
| } | |
| IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer) | |
| { | |
| IDirectDrawImpl *This = impl_from_dd4(outer); | |
| return This->parent; | |
| } |