| /* | |
| * 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); | |
| static struct ddrawex_surface *impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface) | |
| { | |
| return CONTAINING_RECORD(iface, struct ddrawex_surface, IDirectDrawSurface3_iface); | |
| } | |
| static struct ddrawex_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface); | |
| static struct ddrawex_surface *impl_from_IDirectDrawSurface4(IDirectDrawSurface4 *iface) | |
| { | |
| return CONTAINING_RECORD(iface, struct ddrawex_surface, IDirectDrawSurface4_iface); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_QueryInterface(IDirectDrawSurface4 *iface, REFIID riid, void **out) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); | |
| if (!riid) | |
| { | |
| *out = NULL; | |
| return DDERR_INVALIDPARAMS; | |
| } | |
| if (IsEqualGUID(riid, &IID_IDirectDrawSurface4) | |
| || IsEqualGUID(riid, &IID_IUnknown)) | |
| { | |
| *out = &surface->IDirectDrawSurface4_iface; | |
| } | |
| else if (IsEqualGUID(riid, &IID_IDirectDrawSurface3) | |
| || IsEqualGUID(riid, &IID_IDirectDrawSurface2) | |
| || IsEqualGUID(riid, &IID_IDirectDrawSurface)) | |
| { | |
| *out = &surface->IDirectDrawSurface3_iface; | |
| } | |
| else | |
| { | |
| if (IsEqualGUID(riid, &IID_IDirectDrawGammaControl)) | |
| FIXME("Implement IDirectDrawGammaControl in ddrawex.\n"); | |
| else if (IsEqualGUID(riid, &IID_IDirect3DHALDevice) | |
| || IsEqualGUID(riid, &IID_IDirect3DRGBDevice)) | |
| FIXME("Test IDirect3DDevice in ddrawex.\n"); | |
| else if (IsEqualGUID(&IID_IDirect3DTexture2, riid) | |
| || IsEqualGUID( &IID_IDirect3DTexture, riid)) | |
| FIXME("Implement IDirect3DTexture in ddrawex.\n"); | |
| *out = NULL; | |
| WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); | |
| return E_NOINTERFACE; | |
| } | |
| IUnknown_AddRef((IUnknown *)*out); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_QueryInterface(IDirectDrawSurface3 *iface, REFIID riid, void **out) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); | |
| return ddrawex_surface4_QueryInterface(&surface->IDirectDrawSurface4_iface, riid, out); | |
| } | |
| static ULONG WINAPI ddrawex_surface4_AddRef(IDirectDrawSurface4 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| ULONG refcount = InterlockedIncrement(&surface->ref); | |
| TRACE("%p increasing refcount to %u.\n", iface, refcount); | |
| return refcount; | |
| } | |
| static ULONG WINAPI ddrawex_surface3_AddRef(IDirectDrawSurface3 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p.\n", iface); | |
| return ddrawex_surface4_AddRef(&surface->IDirectDrawSurface4_iface); | |
| } | |
| static ULONG WINAPI ddrawex_surface4_Release(IDirectDrawSurface4 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| ULONG refcount = InterlockedDecrement(&surface->ref); | |
| TRACE("%p decreasing refcount to %u.\n", iface, refcount); | |
| if (!refcount) | |
| { | |
| IDirectDrawSurface4_FreePrivateData(surface->parent, &IID_DDrawexPriv); | |
| IDirectDrawSurface4_Release(surface->parent); | |
| HeapFree(GetProcessHeap(), 0, surface); | |
| } | |
| return refcount; | |
| } | |
| static ULONG WINAPI ddrawex_surface3_Release(IDirectDrawSurface3 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p.\n", iface); | |
| return ddrawex_surface4_Release(&surface->IDirectDrawSurface4_iface); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_AddAttachedSurface(IDirectDrawSurface4 *iface, | |
| IDirectDrawSurface4 *attachment) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| struct ddrawex_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface4(attachment); | |
| TRACE("iface %p, attachment %p.\n", iface, attachment); | |
| return IDirectDrawSurface4_AddAttachedSurface(surface->parent, attachment_impl->parent); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_AddAttachedSurface(IDirectDrawSurface3 *iface, | |
| IDirectDrawSurface3 *attachment) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| struct ddrawex_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface3(attachment); | |
| TRACE("iface %p, attachment %p.\n", iface, attachment); | |
| return ddrawex_surface4_AddAttachedSurface(&surface->IDirectDrawSurface4_iface, | |
| attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_AddOverlayDirtyRect(IDirectDrawSurface4 *iface, RECT *rect) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect)); | |
| return IDirectDrawSurface4_AddOverlayDirtyRect(surface->parent, rect); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_AddOverlayDirtyRect(IDirectDrawSurface3 *iface, RECT *rect) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect)); | |
| return ddrawex_surface4_AddOverlayDirtyRect(&surface->IDirectDrawSurface4_iface, rect); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_Blt(IDirectDrawSurface4 *iface, RECT *dst_rect, | |
| IDirectDrawSurface4 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx) | |
| { | |
| struct ddrawex_surface *dst = impl_from_IDirectDrawSurface4(iface); | |
| struct ddrawex_surface *src = unsafe_impl_from_IDirectDrawSurface4(src_surface); | |
| TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", | |
| iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx); | |
| return IDirectDrawSurface4_Blt(dst->parent, dst_rect, src ? src->parent : NULL, src_rect, flags, fx); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_Blt(IDirectDrawSurface3 *iface, RECT *dst_rect, | |
| IDirectDrawSurface3 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx) | |
| { | |
| struct ddrawex_surface *dst = impl_from_IDirectDrawSurface3(iface); | |
| struct ddrawex_surface *src = unsafe_impl_from_IDirectDrawSurface3(src_surface); | |
| TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", | |
| iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx); | |
| return ddrawex_surface4_Blt(&dst->IDirectDrawSurface4_iface, dst_rect, | |
| src ? &src->IDirectDrawSurface4_iface : NULL, src_rect, flags, fx); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_BltBatch(IDirectDrawSurface4 *iface, | |
| DDBLTBATCH *batch, DWORD count, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags); | |
| return IDirectDrawSurface4_BltBatch(surface->parent, batch, count, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_BltBatch(IDirectDrawSurface3 *iface, | |
| DDBLTBATCH *batch, DWORD count, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags); | |
| return ddrawex_surface4_BltBatch(&surface->IDirectDrawSurface4_iface, batch, count, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_BltFast(IDirectDrawSurface4 *iface, DWORD dst_x, | |
| DWORD dst_y, IDirectDrawSurface4 *src_surface, RECT *src_rect, DWORD flags) | |
| { | |
| struct ddrawex_surface *dst = impl_from_IDirectDrawSurface4(iface); | |
| struct ddrawex_surface *src = unsafe_impl_from_IDirectDrawSurface4(src_surface); | |
| TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", | |
| iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), flags); | |
| return IDirectDrawSurface4_BltFast(dst->parent, dst_x, dst_y, | |
| src ? src->parent : NULL, src_rect, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_BltFast(IDirectDrawSurface3 *iface, DWORD dst_x, | |
| DWORD dst_y, IDirectDrawSurface3 *src_surface, RECT *src_rect, DWORD flags) | |
| { | |
| struct ddrawex_surface *dst = impl_from_IDirectDrawSurface3(iface); | |
| struct ddrawex_surface *src = unsafe_impl_from_IDirectDrawSurface3(src_surface); | |
| TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", | |
| iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), flags); | |
| return ddrawex_surface4_BltFast(&dst->IDirectDrawSurface4_iface, dst_x, dst_y, | |
| src ? &src->IDirectDrawSurface4_iface : NULL, src_rect, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_DeleteAttachedSurface(IDirectDrawSurface4 *iface, | |
| DWORD flags, IDirectDrawSurface4 *attachment) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| struct ddrawex_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface4(attachment); | |
| TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment); | |
| return IDirectDrawSurface4_DeleteAttachedSurface(surface->parent, | |
| flags, attachment_impl ? attachment_impl->parent : NULL); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_DeleteAttachedSurface(IDirectDrawSurface3 *iface, | |
| DWORD flags, IDirectDrawSurface3 *attachment) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| struct ddrawex_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface3(attachment); | |
| TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment); | |
| return ddrawex_surface4_DeleteAttachedSurface(&surface->IDirectDrawSurface4_iface, | |
| flags, attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL); | |
| } | |
| struct enumsurfaces_wrap | |
| { | |
| LPDDENUMSURFACESCALLBACK2 orig_cb; | |
| void *orig_ctx; | |
| }; | |
| static HRESULT WINAPI | |
| enumsurfaces_wrap_cb(IDirectDrawSurface4 *surf, DDSURFACEDESC2 *desc, void *vctx) | |
| { | |
| struct enumsurfaces_wrap *ctx = vctx; | |
| IDirectDrawSurface4 *outer = dds_get_outer(surf); | |
| TRACE("Returning outer surface %p for inner surface %p\n", outer, surf); | |
| IDirectDrawSurface4_AddRef(outer); | |
| IDirectDrawSurface4_Release(surf); | |
| return ctx->orig_cb(outer, desc, vctx); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_EnumAttachedSurfaces(IDirectDrawSurface4 *iface, | |
| void *ctx, LPDDENUMSURFACESCALLBACK2 cb) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| struct enumsurfaces_wrap cb_ctx; | |
| TRACE("iface %p, ctx %p, cb %p.\n", iface, ctx, cb); | |
| cb_ctx.orig_cb = cb; | |
| cb_ctx.orig_ctx = ctx; | |
| return IDirectDrawSurface4_EnumAttachedSurfaces(surface->parent, &cb_ctx, enumsurfaces_wrap_cb); | |
| } | |
| struct enumsurfaces_thunk | |
| { | |
| LPDDENUMSURFACESCALLBACK orig_cb; | |
| void *orig_ctx; | |
| }; | |
| static HRESULT WINAPI enumsurfaces_thunk_cb(IDirectDrawSurface4 *surf, DDSURFACEDESC2 *desc2, | |
| void *vctx) | |
| { | |
| struct ddrawex_surface *surface = unsafe_impl_from_IDirectDrawSurface4(surf); | |
| struct enumsurfaces_thunk *ctx = vctx; | |
| DDSURFACEDESC desc; | |
| TRACE("Thunking back to IDirectDrawSurface3\n"); | |
| IDirectDrawSurface3_AddRef(&surface->IDirectDrawSurface3_iface); | |
| IDirectDrawSurface3_Release(surf); | |
| DDSD2_to_DDSD(desc2, &desc); | |
| return ctx->orig_cb((IDirectDrawSurface *)&surface->IDirectDrawSurface3_iface, &desc, ctx->orig_ctx); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_EnumAttachedSurfaces(IDirectDrawSurface3 *iface, | |
| void *ctx, LPDDENUMSURFACESCALLBACK cb) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| struct enumsurfaces_thunk cb_ctx; | |
| TRACE("iface %p, ctx %p, cb %p.\n", iface, ctx, cb); | |
| cb_ctx.orig_cb = cb; | |
| cb_ctx.orig_ctx = ctx; | |
| return ddrawex_surface4_EnumAttachedSurfaces(&surface->IDirectDrawSurface4_iface, &cb_ctx, enumsurfaces_thunk_cb); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_EnumOverlayZOrders(IDirectDrawSurface4 *iface, | |
| DWORD flags, void *ctx, LPDDENUMSURFACESCALLBACK2 cb) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| struct enumsurfaces_wrap cb_ctx; | |
| TRACE("iface %p, flags %#x, ctx %p, cb %p.\n", iface, flags, ctx, cb); | |
| cb_ctx.orig_cb = cb; | |
| cb_ctx.orig_ctx = ctx; | |
| return IDirectDrawSurface4_EnumOverlayZOrders(surface->parent, flags, &cb_ctx, enumsurfaces_wrap_cb); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_EnumOverlayZOrders(IDirectDrawSurface3 *iface, | |
| DWORD flags, void *ctx, LPDDENUMSURFACESCALLBACK cb) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| struct enumsurfaces_thunk cb_ctx; | |
| TRACE("iface %p, flags %#x, ctx %p, cb %p.\n", iface, flags, ctx, cb); | |
| cb_ctx.orig_cb = cb; | |
| cb_ctx.orig_ctx = ctx; | |
| return ddrawex_surface4_EnumOverlayZOrders(&surface->IDirectDrawSurface4_iface, | |
| flags, &cb_ctx, enumsurfaces_thunk_cb); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_Flip(IDirectDrawSurface4 *iface, IDirectDrawSurface4 *dst, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| struct ddrawex_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface4(dst); | |
| TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); | |
| return IDirectDrawSurface4_Flip(surface->parent, dst_impl ? dst_impl->parent : NULL, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_Flip(IDirectDrawSurface3 *iface, IDirectDrawSurface3 *dst, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| struct ddrawex_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface3(dst); | |
| TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); | |
| return ddrawex_surface4_Flip(&surface->IDirectDrawSurface4_iface, | |
| dst_impl ? &dst_impl->IDirectDrawSurface4_iface : NULL, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetAttachedSurface(IDirectDrawSurface4 *iface, | |
| DDSCAPS2 *caps, IDirectDrawSurface4 **attachment) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| IDirectDrawSurface4 *inner = NULL; | |
| HRESULT hr; | |
| TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment); | |
| if (SUCCEEDED(hr = IDirectDrawSurface4_GetAttachedSurface(surface->parent, caps, &inner))) | |
| { | |
| *attachment = dds_get_outer(inner); | |
| IDirectDrawSurface4_AddRef(*attachment); | |
| IDirectDrawSurface4_Release(inner); | |
| } | |
| else | |
| { | |
| *attachment = NULL; | |
| } | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetAttachedSurface(IDirectDrawSurface3 *iface, | |
| DDSCAPS *caps, IDirectDrawSurface3 **attachment) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| IDirectDrawSurface4 *surf4; | |
| DDSCAPS2 caps2; | |
| HRESULT hr; | |
| TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment); | |
| memset(&caps2, 0, sizeof(caps2)); | |
| caps2.dwCaps = caps->dwCaps; | |
| if (SUCCEEDED(hr = ddrawex_surface4_GetAttachedSurface(&surface->IDirectDrawSurface4_iface, &caps2, &surf4))) | |
| { | |
| IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface3, (void **)attachment); | |
| IDirectDrawSurface4_Release(surf4); | |
| } | |
| else | |
| { | |
| *attachment = NULL; | |
| } | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetBltStatus(IDirectDrawSurface4 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return IDirectDrawSurface4_GetBltStatus(surface->parent, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetBltStatus(IDirectDrawSurface3 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return ddrawex_surface4_GetBltStatus(&surface->IDirectDrawSurface4_iface, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetCaps(IDirectDrawSurface4 *iface, DDSCAPS2 *caps) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, caps %p.\n", iface, caps); | |
| return IDirectDrawSurface4_GetCaps(surface->parent, caps); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetCaps(IDirectDrawSurface3 *iface, DDSCAPS *caps) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| DDSCAPS2 caps2; | |
| HRESULT hr; | |
| TRACE("iface %p, caps %p.\n", iface, caps); | |
| memset(&caps2, 0, sizeof(caps2)); | |
| memset(caps, 0, sizeof(*caps)); | |
| hr = IDirectDrawSurface4_GetCaps(&surface->IDirectDrawSurface4_iface, &caps2); | |
| caps->dwCaps = caps2.dwCaps; | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetClipper(IDirectDrawSurface4 *iface, IDirectDrawClipper **clipper) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, clipper %p.\n", iface, clipper); | |
| return IDirectDrawSurface4_GetClipper(surface->parent, clipper); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetClipper(IDirectDrawSurface3 *iface, IDirectDrawClipper **clipper) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, clipper %p.\n", iface, clipper); | |
| return ddrawex_surface4_GetClipper(&surface->IDirectDrawSurface4_iface, clipper); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetColorKey(IDirectDrawSurface4 *iface, DWORD flags, DDCOLORKEY *color_key) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); | |
| return IDirectDrawSurface4_GetColorKey(surface->parent, flags, color_key); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetColorKey(IDirectDrawSurface3 *iface, DWORD flags, DDCOLORKEY *color_key) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); | |
| return ddrawex_surface4_GetColorKey(&surface->IDirectDrawSurface4_iface, flags, color_key); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetDC(IDirectDrawSurface4 *iface, HDC *dc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, dc %p.\n", iface, dc); | |
| if (surface->permanent_dc) | |
| { | |
| TRACE("Returning stored dc %p.\n", surface->hdc); | |
| *dc = surface->hdc; | |
| return DD_OK; | |
| } | |
| return IDirectDrawSurface4_GetDC(surface->parent, dc); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetDC(IDirectDrawSurface3 *iface, HDC *dc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, dc %p.\n", iface, dc); | |
| return ddrawex_surface4_GetDC(&surface->IDirectDrawSurface4_iface, dc); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetFlipStatus(IDirectDrawSurface4 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return IDirectDrawSurface4_GetFlipStatus(surface->parent, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetFlipStatus(IDirectDrawSurface3 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return ddrawex_surface4_GetFlipStatus(&surface->IDirectDrawSurface4_iface, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetOverlayPosition(IDirectDrawSurface4 *iface, LONG *x, LONG *y) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, x %p, y %p.\n", iface, x, y); | |
| return IDirectDrawSurface4_GetOverlayPosition(surface->parent, x, y); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetOverlayPosition(IDirectDrawSurface3 *iface, LONG *x, LONG *y) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, x %p, y %p.\n", iface, x, y); | |
| return ddrawex_surface4_GetOverlayPosition(&surface->IDirectDrawSurface4_iface, x, y); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetPalette(IDirectDrawSurface4 *iface, IDirectDrawPalette **palette) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, palette %p.\n", iface, palette); | |
| return IDirectDrawSurface4_GetPalette(surface->parent, palette); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetPalette(IDirectDrawSurface3 *iface, IDirectDrawPalette **palette) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, palette %p.\n", iface, palette); | |
| return ddrawex_surface4_GetPalette(&surface->IDirectDrawSurface4_iface, palette); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetPixelFormat(IDirectDrawSurface4 *iface, DDPIXELFORMAT *pixel_format) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, pixel_format %p.\n", iface, pixel_format); | |
| return IDirectDrawSurface4_GetPixelFormat(surface->parent, pixel_format); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetPixelFormat(IDirectDrawSurface3 *iface, DDPIXELFORMAT *pixel_format) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, pixel_format %p.\n", iface, pixel_format); | |
| return ddrawex_surface4_GetPixelFormat(&surface->IDirectDrawSurface4_iface, pixel_format); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetSurfaceDesc(IDirectDrawSurface4 *iface, DDSURFACEDESC2 *desc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| HRESULT hr; | |
| TRACE("iface %p, desc %p.\n", iface, desc); | |
| if (SUCCEEDED(hr = IDirectDrawSurface4_GetSurfaceDesc(surface->parent, desc)) | |
| && surface->permanent_dc) | |
| { | |
| desc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; | |
| desc->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC; | |
| } | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetSurfaceDesc(IDirectDrawSurface3 *iface, DDSURFACEDESC *desc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| DDSURFACEDESC2 ddsd2; | |
| HRESULT hr; | |
| TRACE("iface %p, desc %p.\n", iface, desc); | |
| memset(&ddsd2, 0, sizeof(ddsd2)); | |
| ddsd2.dwSize = sizeof(ddsd2); | |
| hr = ddrawex_surface4_GetSurfaceDesc(&surface->IDirectDrawSurface4_iface, &ddsd2); | |
| DDSD2_to_DDSD(&ddsd2, desc); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_Initialize(IDirectDrawSurface4 *iface, | |
| IDirectDraw *ddraw, DDSURFACEDESC2 *desc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| IDirectDraw4 *outer_DD4; | |
| IDirectDraw4 *inner_DD4; | |
| IDirectDraw *inner_DD; | |
| HRESULT hr; | |
| TRACE("iface %p, ddraw %p, desc %p.\n", iface, ddraw, desc); | |
| IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw4, (void **)&outer_DD4); | |
| inner_DD4 = dd_get_inner(outer_DD4); | |
| IDirectDraw4_Release(outer_DD4); | |
| IDirectDraw4_QueryInterface(inner_DD4, &IID_IDirectDraw4, (void **)&inner_DD); | |
| hr = IDirectDrawSurface4_Initialize(surface->parent, inner_DD, desc); | |
| IDirectDraw_Release(inner_DD); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_Initialize(IDirectDrawSurface3 *iface, | |
| IDirectDraw *ddraw, DDSURFACEDESC *desc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| DDSURFACEDESC2 ddsd2; | |
| TRACE("iface %p, ddraw %p, desc %p.\n", iface, ddraw, desc); | |
| DDSD_to_DDSD2(desc, &ddsd2); | |
| return ddrawex_surface4_Initialize(&surface->IDirectDrawSurface4_iface, ddraw, &ddsd2); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_IsLost(IDirectDrawSurface4 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p.\n", iface); | |
| return IDirectDrawSurface4_IsLost(surface->parent); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_IsLost(IDirectDrawSurface3 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p.\n", iface); | |
| return ddrawex_surface4_IsLost(&surface->IDirectDrawSurface4_iface); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_Lock(IDirectDrawSurface4 *iface, RECT *rect, | |
| DDSURFACEDESC2 *desc, DWORD flags, HANDLE h) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| HRESULT hr; | |
| TRACE("iface %p, rect %s, desc %p, flags %#x, h %p.\n", | |
| iface, wine_dbgstr_rect(rect), desc, flags, h); | |
| if (SUCCEEDED(hr = IDirectDrawSurface4_Lock(surface->parent, rect, desc, flags, h)) | |
| && surface->permanent_dc) | |
| { | |
| desc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; | |
| desc->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC; | |
| } | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect, | |
| DDSURFACEDESC *desc, DWORD flags, HANDLE h) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| DDSURFACEDESC2 ddsd2; | |
| HRESULT hr; | |
| TRACE("iface %p, rect %s, desc %p, flags %#x, h %p.\n", | |
| iface, wine_dbgstr_rect(rect), desc, flags, h); | |
| memset(&ddsd2, 0, sizeof(ddsd2)); | |
| ddsd2.dwSize = sizeof(ddsd2); | |
| hr = ddrawex_surface4_Lock(&surface->IDirectDrawSurface4_iface, rect, &ddsd2, flags, h); | |
| DDSD2_to_DDSD(&ddsd2, desc); | |
| return hr; | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_ReleaseDC(IDirectDrawSurface4 *iface, HDC dc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, dc %p.\n", iface, dc); | |
| if (surface->permanent_dc) | |
| { | |
| TRACE("Surface has a permanent DC, not doing anything.\n"); | |
| return DD_OK; | |
| } | |
| return IDirectDrawSurface4_ReleaseDC(surface->parent, dc); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_ReleaseDC(IDirectDrawSurface3 *iface, HDC dc) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, dc %p.\n", iface, dc); | |
| return ddrawex_surface4_ReleaseDC(&surface->IDirectDrawSurface4_iface, dc); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_Restore(IDirectDrawSurface4 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p.\n", iface); | |
| return IDirectDrawSurface4_Restore(surface->parent); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_Restore(IDirectDrawSurface3 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p.\n", iface); | |
| return ddrawex_surface4_Restore(&surface->IDirectDrawSurface4_iface); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_SetClipper(IDirectDrawSurface4 *iface, IDirectDrawClipper *clipper) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, clipper %p.\n", iface, clipper); | |
| return IDirectDrawSurface4_SetClipper(surface->parent, clipper); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_SetClipper(IDirectDrawSurface3 *iface, IDirectDrawClipper *clipper) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, clipper %p.\n", iface, clipper); | |
| return ddrawex_surface4_SetClipper(&surface->IDirectDrawSurface4_iface, clipper); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_SetColorKey(IDirectDrawSurface4 *iface, | |
| DWORD flags, DDCOLORKEY *color_key) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); | |
| return IDirectDrawSurface4_SetColorKey(surface->parent, flags, color_key); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_SetColorKey(IDirectDrawSurface3 *iface, | |
| DWORD flags, DDCOLORKEY *color_key) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); | |
| return ddrawex_surface4_SetColorKey(&surface->IDirectDrawSurface4_iface, flags, color_key); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_SetOverlayPosition(IDirectDrawSurface4 *iface, LONG x, LONG y) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, x %d, y %d.\n", iface, x, y); | |
| return IDirectDrawSurface4_SetOverlayPosition(surface->parent, x, y); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_SetOverlayPosition(IDirectDrawSurface3 *iface, LONG x, LONG y) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, x %d, y %d.\n", iface, x, y); | |
| return ddrawex_surface4_SetOverlayPosition(&surface->IDirectDrawSurface4_iface, x, y); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_SetPalette(IDirectDrawSurface4 *iface, IDirectDrawPalette *palette) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, palette %p.\n", iface, palette); | |
| return IDirectDrawSurface4_SetPalette(surface->parent, palette); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_SetPalette(IDirectDrawSurface3 *iface, IDirectDrawPalette *palette) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, palette %p.\n", iface, palette); | |
| return ddrawex_surface4_SetPalette(&surface->IDirectDrawSurface4_iface, palette); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_Unlock(IDirectDrawSurface4 *iface, RECT *rect) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect)); | |
| return IDirectDrawSurface4_Unlock(surface->parent, rect); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_Unlock(IDirectDrawSurface3 *iface, void *data) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, data %p.\n", iface, data); | |
| return ddrawex_surface4_Unlock(&surface->IDirectDrawSurface4_iface, NULL); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_UpdateOverlay(IDirectDrawSurface4 *iface, RECT *src_rect, | |
| IDirectDrawSurface4 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx) | |
| { | |
| struct ddrawex_surface *src_impl = impl_from_IDirectDrawSurface4(iface); | |
| struct ddrawex_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface4(dst_surface); | |
| TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n", | |
| iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx); | |
| return IDirectDrawSurface4_UpdateOverlay(src_impl->parent, src_rect, | |
| dst_impl ? dst_impl->parent : NULL, dst_rect, flags, fx); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_UpdateOverlay(IDirectDrawSurface3 *iface, RECT *src_rect, | |
| IDirectDrawSurface3 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx) | |
| { | |
| struct ddrawex_surface *src_impl = impl_from_IDirectDrawSurface3(iface); | |
| struct ddrawex_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface3(dst_surface); | |
| TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n", | |
| iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx); | |
| return ddrawex_surface4_UpdateOverlay(&src_impl->IDirectDrawSurface4_iface, src_rect, | |
| dst_impl ? &dst_impl->IDirectDrawSurface4_iface : NULL, dst_rect, flags, fx); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_UpdateOverlayDisplay(IDirectDrawSurface4 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return IDirectDrawSurface4_UpdateOverlayDisplay(surface->parent, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_UpdateOverlayDisplay(IDirectDrawSurface3 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return ddrawex_surface4_UpdateOverlayDisplay(&surface->IDirectDrawSurface4_iface, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_UpdateOverlayZOrder(IDirectDrawSurface4 *iface, | |
| DWORD flags, IDirectDrawSurface4 *reference) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| struct ddrawex_surface *reference_impl = unsafe_impl_from_IDirectDrawSurface4(reference); | |
| TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference); | |
| return IDirectDrawSurface4_UpdateOverlayZOrder(surface->parent, | |
| flags, reference_impl ? reference_impl->parent : NULL); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_UpdateOverlayZOrder(IDirectDrawSurface3 *iface, | |
| DWORD flags, IDirectDrawSurface3 *reference) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| struct ddrawex_surface *reference_impl = unsafe_impl_from_IDirectDrawSurface3(reference); | |
| TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference); | |
| return ddrawex_surface4_UpdateOverlayZOrder(&surface->IDirectDrawSurface4_iface, | |
| flags, reference_impl ? &reference_impl->IDirectDrawSurface4_iface : NULL); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetDDInterface(IDirectDrawSurface4 *iface, void **ddraw) | |
| { | |
| FIXME("iface %p, ddraw %p stub!\n", iface, ddraw); | |
| /* This has to be implemented in ddrawex, ddraw's interface can't be used | |
| * because it is pretty hard to tell which version of the ddraw interface | |
| * is returned. */ | |
| *ddraw = NULL; | |
| return E_FAIL; | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_GetDDInterface(IDirectDrawSurface3 *iface, void **ddraw) | |
| { | |
| FIXME("iface %p, ddraw %p stub!\n", iface, ddraw); | |
| /* A thunk it pretty pointless for the same reason that relaying to | |
| * ddraw.dll works badly. */ | |
| *ddraw = NULL; | |
| return E_FAIL; | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_PageLock(IDirectDrawSurface4 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return IDirectDrawSurface4_PageLock(surface->parent, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_PageLock(IDirectDrawSurface3 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return ddrawex_surface4_PageLock(&surface->IDirectDrawSurface4_iface, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_PageUnlock(IDirectDrawSurface4 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return IDirectDrawSurface4_PageUnlock(surface->parent, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_PageUnlock(IDirectDrawSurface3 *iface, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| TRACE("iface %p, flags %#x.\n", iface, flags); | |
| return ddrawex_surface4_PageUnlock(&surface->IDirectDrawSurface4_iface, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_SetSurfaceDesc(IDirectDrawSurface4 *iface, | |
| DDSURFACEDESC2 *desc, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, desc %p, flags %#x.\n", iface, desc, flags); | |
| return IDirectDrawSurface4_SetSurfaceDesc(surface->parent, desc, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface3_SetSurfaceDesc(IDirectDrawSurface3 *iface, | |
| DDSURFACEDESC *desc, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface3(iface); | |
| DDSURFACEDESC2 ddsd; | |
| TRACE("iface %p, desc %p, flags %#x.\n", iface, desc, flags); | |
| DDSD_to_DDSD2(desc, &ddsd); | |
| return ddrawex_surface4_SetSurfaceDesc(&surface->IDirectDrawSurface4_iface, &ddsd, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_SetPrivateData(IDirectDrawSurface4 *iface, | |
| REFGUID tag, void *data, DWORD data_size, DWORD flags) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n", | |
| iface, debugstr_guid(tag), data, data_size, flags); | |
| /* To completely avoid this we'd have to clone the private data API in | |
| * ddrawex. */ | |
| if (IsEqualGUID(&IID_DDrawexPriv, tag)) | |
| FIXME("Application uses ddrawex's private GUID.\n"); | |
| return IDirectDrawSurface4_SetPrivateData(surface->parent, tag, data, data_size, flags); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetPrivateData(IDirectDrawSurface4 *iface, | |
| REFGUID tag, void *data, DWORD *data_size) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, tag %s, data %p, data_size %p.\n", | |
| iface, debugstr_guid(tag), data, data_size); | |
| /* To completely avoid this we'd have to clone the private data API in | |
| * ddrawex. */ | |
| if (IsEqualGUID(&IID_DDrawexPriv, tag)) | |
| FIXME("Application uses ddrawex's private GUID.\n"); | |
| return IDirectDrawSurface4_GetPrivateData(surface->parent, tag, data, data_size); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_FreePrivateData(IDirectDrawSurface4 *iface, REFGUID tag) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, tag %s.\n", iface, debugstr_guid(tag)); | |
| /* To completely avoid this we'd have to clone the private data API in | |
| * ddrawex. */ | |
| if (IsEqualGUID(&IID_DDrawexPriv, tag)) | |
| FIXME("Application uses ddrawex's private GUID.\n"); | |
| return IDirectDrawSurface4_FreePrivateData(surface->parent, tag); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_GetUniquenessValue(IDirectDrawSurface4 *iface, DWORD *value) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p, value %p.\n", iface, value); | |
| return IDirectDrawSurface4_GetUniquenessValue(surface->parent, value); | |
| } | |
| static HRESULT WINAPI ddrawex_surface4_ChangeUniquenessValue(IDirectDrawSurface4 *iface) | |
| { | |
| struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); | |
| TRACE("iface %p.\n", iface); | |
| return IDirectDrawSurface4_ChangeUniquenessValue(surface->parent); | |
| } | |
| static const IDirectDrawSurface3Vtbl ddrawex_surface3_vtbl = | |
| { | |
| ddrawex_surface3_QueryInterface, | |
| ddrawex_surface3_AddRef, | |
| ddrawex_surface3_Release, | |
| ddrawex_surface3_AddAttachedSurface, | |
| ddrawex_surface3_AddOverlayDirtyRect, | |
| ddrawex_surface3_Blt, | |
| ddrawex_surface3_BltBatch, | |
| ddrawex_surface3_BltFast, | |
| ddrawex_surface3_DeleteAttachedSurface, | |
| ddrawex_surface3_EnumAttachedSurfaces, | |
| ddrawex_surface3_EnumOverlayZOrders, | |
| ddrawex_surface3_Flip, | |
| ddrawex_surface3_GetAttachedSurface, | |
| ddrawex_surface3_GetBltStatus, | |
| ddrawex_surface3_GetCaps, | |
| ddrawex_surface3_GetClipper, | |
| ddrawex_surface3_GetColorKey, | |
| ddrawex_surface3_GetDC, | |
| ddrawex_surface3_GetFlipStatus, | |
| ddrawex_surface3_GetOverlayPosition, | |
| ddrawex_surface3_GetPalette, | |
| ddrawex_surface3_GetPixelFormat, | |
| ddrawex_surface3_GetSurfaceDesc, | |
| ddrawex_surface3_Initialize, | |
| ddrawex_surface3_IsLost, | |
| ddrawex_surface3_Lock, | |
| ddrawex_surface3_ReleaseDC, | |
| ddrawex_surface3_Restore, | |
| ddrawex_surface3_SetClipper, | |
| ddrawex_surface3_SetColorKey, | |
| ddrawex_surface3_SetOverlayPosition, | |
| ddrawex_surface3_SetPalette, | |
| ddrawex_surface3_Unlock, | |
| ddrawex_surface3_UpdateOverlay, | |
| ddrawex_surface3_UpdateOverlayDisplay, | |
| ddrawex_surface3_UpdateOverlayZOrder, | |
| ddrawex_surface3_GetDDInterface, | |
| ddrawex_surface3_PageLock, | |
| ddrawex_surface3_PageUnlock, | |
| ddrawex_surface3_SetSurfaceDesc, | |
| }; | |
| static const IDirectDrawSurface4Vtbl ddrawex_surface4_vtbl = | |
| { | |
| ddrawex_surface4_QueryInterface, | |
| ddrawex_surface4_AddRef, | |
| ddrawex_surface4_Release, | |
| ddrawex_surface4_AddAttachedSurface, | |
| ddrawex_surface4_AddOverlayDirtyRect, | |
| ddrawex_surface4_Blt, | |
| ddrawex_surface4_BltBatch, | |
| ddrawex_surface4_BltFast, | |
| ddrawex_surface4_DeleteAttachedSurface, | |
| ddrawex_surface4_EnumAttachedSurfaces, | |
| ddrawex_surface4_EnumOverlayZOrders, | |
| ddrawex_surface4_Flip, | |
| ddrawex_surface4_GetAttachedSurface, | |
| ddrawex_surface4_GetBltStatus, | |
| ddrawex_surface4_GetCaps, | |
| ddrawex_surface4_GetClipper, | |
| ddrawex_surface4_GetColorKey, | |
| ddrawex_surface4_GetDC, | |
| ddrawex_surface4_GetFlipStatus, | |
| ddrawex_surface4_GetOverlayPosition, | |
| ddrawex_surface4_GetPalette, | |
| ddrawex_surface4_GetPixelFormat, | |
| ddrawex_surface4_GetSurfaceDesc, | |
| ddrawex_surface4_Initialize, | |
| ddrawex_surface4_IsLost, | |
| ddrawex_surface4_Lock, | |
| ddrawex_surface4_ReleaseDC, | |
| ddrawex_surface4_Restore, | |
| ddrawex_surface4_SetClipper, | |
| ddrawex_surface4_SetColorKey, | |
| ddrawex_surface4_SetOverlayPosition, | |
| ddrawex_surface4_SetPalette, | |
| ddrawex_surface4_Unlock, | |
| ddrawex_surface4_UpdateOverlay, | |
| ddrawex_surface4_UpdateOverlayDisplay, | |
| ddrawex_surface4_UpdateOverlayZOrder, | |
| ddrawex_surface4_GetDDInterface, | |
| ddrawex_surface4_PageLock, | |
| ddrawex_surface4_PageUnlock, | |
| ddrawex_surface4_SetSurfaceDesc, | |
| ddrawex_surface4_SetPrivateData, | |
| ddrawex_surface4_GetPrivateData, | |
| ddrawex_surface4_FreePrivateData, | |
| ddrawex_surface4_GetUniquenessValue, | |
| ddrawex_surface4_ChangeUniquenessValue, | |
| }; | |
| static struct ddrawex_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface) | |
| { | |
| if (!iface || iface->lpVtbl != &ddrawex_surface3_vtbl) | |
| return NULL; | |
| return impl_from_IDirectDrawSurface3(iface); | |
| } | |
| struct ddrawex_surface *unsafe_impl_from_IDirectDrawSurface4(IDirectDrawSurface4 *iface) | |
| { | |
| if (!iface || iface->lpVtbl != &ddrawex_surface4_vtbl) | |
| return NULL; | |
| return impl_from_IDirectDrawSurface4(iface); | |
| } | |
| /* dds_get_outer | |
| * | |
| * Given a surface from ddraw.dll it retrieves the pointer to the ddrawex.dll wrapper around it | |
| * | |
| * Parameters: | |
| * inner: ddraw.dll surface to retrieve the outer surface from | |
| * | |
| * Returns: | |
| * The surface wrapper. If there is none yet, a new one is created | |
| */ | |
| IDirectDrawSurface4 *dds_get_outer(IDirectDrawSurface4 *inner) | |
| { | |
| IDirectDrawSurface4 *outer = NULL; | |
| DWORD size = sizeof(outer); | |
| HRESULT hr; | |
| if(!inner) return NULL; | |
| hr = IDirectDrawSurface4_GetPrivateData(inner, | |
| &IID_DDrawexPriv, | |
| &outer, | |
| &size); | |
| if(FAILED(hr) || outer == NULL) | |
| { | |
| struct ddrawex_surface *impl; | |
| TRACE("Creating new ddrawex surface wrapper for surface %p\n", inner); | |
| impl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*impl)); | |
| impl->ref = 1; | |
| impl->IDirectDrawSurface3_iface.lpVtbl = &ddrawex_surface3_vtbl; | |
| impl->IDirectDrawSurface4_iface.lpVtbl = &ddrawex_surface4_vtbl; | |
| IDirectDrawSurface4_AddRef(inner); | |
| impl->parent = inner; | |
| outer = &impl->IDirectDrawSurface4_iface; | |
| hr = IDirectDrawSurface4_SetPrivateData(inner, | |
| &IID_DDrawexPriv, | |
| &outer, | |
| sizeof(outer), | |
| 0 /* Flags */); | |
| if(FAILED(hr)) | |
| { | |
| ERR("IDirectDrawSurface4_SetPrivateData failed\n"); | |
| } | |
| } | |
| return outer; | |
| } | |
| HRESULT prepare_permanent_dc(IDirectDrawSurface4 *iface) | |
| { | |
| struct ddrawex_surface *surface = unsafe_impl_from_IDirectDrawSurface4(iface); | |
| HRESULT hr; | |
| surface->permanent_dc = TRUE; | |
| if (FAILED(hr = IDirectDrawSurface4_GetDC(surface->parent, &surface->hdc))) | |
| return hr; | |
| return IDirectDrawSurface4_ReleaseDC(surface->parent, surface->hdc); | |
| } |