ddrawex: Rename impl_from_dd4() to impl_from_IDirectDraw4().
[wine.git] / dlls / ddrawex / ddraw.c
blob70448ca4d532e261b3e5fea66d5831c13ae88d70
1 /*
2 * Copyright 2008 Stefan Dösinger for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
20 #define NONAMELESSUNION
22 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
27 #include "ddraw.h"
28 #include "d3d.h"
30 #include "ddrawex_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);
35 /******************************************************************************
36 * Helper functions for COM management
37 ******************************************************************************/
38 static IDirectDrawImpl *impl_from_IDirectDraw(IDirectDraw *iface)
40 return CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw_iface);
43 static IDirectDrawImpl *impl_from_IDirectDraw2(IDirectDraw2 *iface)
45 return CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw2_iface);
48 static IDirectDrawImpl *impl_from_IDirectDraw3(IDirectDraw3 *iface)
50 return CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw3_iface);
53 static IDirectDrawImpl *impl_from_IDirectDraw4(IDirectDraw4 *iface)
55 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw4_Vtbl));
57 static IDirectDraw4 *dd4_from_impl(IDirectDrawImpl *This)
59 return (IDirectDraw4 *) &This->IDirectDraw4_Vtbl;
62 /******************************************************************************
63 * IDirectDraw4 -> ddraw.dll wrappers
64 ******************************************************************************/
65 static HRESULT WINAPI IDirectDraw4Impl_QueryInterface(IDirectDraw4 *iface, REFIID refiid,
66 void **obj)
68 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
70 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
71 *obj = NULL;
73 if(!refiid)
75 return DDERR_INVALIDPARAMS;
78 if (IsEqualGUID( &IID_IDirectDraw7, refiid ) )
80 WARN("IDirectDraw7 not allowed in ddrawex.dll\n");
81 return E_NOINTERFACE;
83 else if ( IsEqualGUID( &IID_IUnknown, refiid ) ||
84 IsEqualGUID( &IID_IDirectDraw4, refiid ) )
86 *obj = dd4_from_impl(This);
87 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
88 IDirectDraw4_AddRef((IDirectDraw4 *) *obj);
90 else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) )
92 *obj = &This->IDirectDraw3_iface;
93 TRACE("(%p) Returning IDirectDraw3 interface at %p\n", This, *obj);
94 IDirectDraw3_AddRef(&This->IDirectDraw3_iface);
96 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
98 *obj = &This->IDirectDraw2_iface;
99 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
100 IDirectDraw2_AddRef(&This->IDirectDraw2_iface);
102 else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
104 *obj = &This->IDirectDraw_iface;
105 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
106 IDirectDraw_AddRef(&This->IDirectDraw_iface);
108 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
109 IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
110 IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
111 IsEqualGUID( &IID_IDirect3D7 , refiid ) )
113 WARN("Direct3D not allowed in ddrawex.dll\n");
114 return E_NOINTERFACE;
116 /* Unknown interface */
117 else
119 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
120 return E_NOINTERFACE;
122 TRACE("Returning S_OK\n");
123 return S_OK;
126 static HRESULT WINAPI IDirectDraw3Impl_QueryInterface(IDirectDraw3 *iface, REFIID refiid,
127 void **obj)
129 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
130 TRACE("Thunking to IDirectDraw4\n");
131 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
134 static HRESULT WINAPI IDirectDraw2Impl_QueryInterface(IDirectDraw2 *iface, REFIID refiid,
135 void **obj)
137 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
138 TRACE("Thunking to IDirectDraw4\n");
139 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
142 static HRESULT WINAPI IDirectDrawImpl_QueryInterface(IDirectDraw *iface, REFIID refiid, void **obj)
144 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
145 TRACE("Thunking to IDirectDraw4\n");
146 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
149 static ULONG WINAPI IDirectDraw4Impl_AddRef(IDirectDraw4 *iface)
151 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
152 ULONG ref = InterlockedIncrement(&This->ref);
154 TRACE("(%p) : incrementing refcount from %u.\n", This, ref - 1);
156 return ref;
159 static ULONG WINAPI IDirectDraw3Impl_AddRef(IDirectDraw3 *iface)
161 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
162 TRACE("Thunking to IDirectDraw4\n");
163 return IDirectDraw4_AddRef(dd4_from_impl(This));
166 static ULONG WINAPI IDirectDraw2Impl_AddRef(IDirectDraw2 *iface)
168 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
169 TRACE("Thunking to IDirectDraw4\n");
170 return IDirectDraw4_AddRef(dd4_from_impl(This));
173 static ULONG WINAPI IDirectDrawImpl_AddRef(IDirectDraw *iface)
175 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
176 TRACE("Thunking to IDirectDraw4\n");
177 return IDirectDraw4_AddRef(dd4_from_impl(This));
180 static ULONG WINAPI IDirectDraw4Impl_Release(IDirectDraw4 *iface)
182 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
183 ULONG ref = InterlockedDecrement(&This->ref);
185 TRACE("(%p) : decrementing refcount to %u.\n", This, ref);
187 if(ref == 0)
189 TRACE("Destroying object\n");
190 IDirectDraw4_Release(This->parent);
191 HeapFree(GetProcessHeap(), 0, This);
193 return ref;
196 static ULONG WINAPI IDirectDraw3Impl_Release(IDirectDraw3 *iface)
198 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
199 TRACE("Thunking to IDirectDraw4\n");
200 return IDirectDraw4_Release(dd4_from_impl(This));
203 static ULONG WINAPI IDirectDraw2Impl_Release(IDirectDraw2 *iface)
205 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
206 TRACE("Thunking to IDirectDraw4\n");
207 return IDirectDraw4_Release(dd4_from_impl(This));
210 static ULONG WINAPI IDirectDrawImpl_Release(IDirectDraw *iface)
212 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
213 TRACE("Thunking to IDirectDraw4\n");
214 return IDirectDraw4_Release(dd4_from_impl(This));
217 static HRESULT WINAPI IDirectDraw4Impl_Compact(IDirectDraw4 *iface)
219 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
220 TRACE("(%p)\n", This);
222 return IDirectDraw4_Compact(This->parent);
225 static HRESULT WINAPI IDirectDraw3Impl_Compact(IDirectDraw3 *iface)
227 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
228 TRACE("Thunking to IDirectDraw4\n");
229 return IDirectDraw4_Compact(dd4_from_impl(This));
232 static HRESULT WINAPI IDirectDraw2Impl_Compact(IDirectDraw2 *iface)
234 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
235 TRACE("Thunking to IDirectDraw4\n");
236 return IDirectDraw4_Compact(dd4_from_impl(This));
239 static HRESULT WINAPI IDirectDrawImpl_Compact(IDirectDraw *iface)
241 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
242 TRACE("Thunking to IDirectDraw4\n");
243 return IDirectDraw4_Compact(dd4_from_impl(This));
246 static HRESULT WINAPI IDirectDraw4Impl_CreateClipper(IDirectDraw4 *iface, DWORD Flags,
247 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
249 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
250 TRACE("(%p)->(0x%08x, %p, %p)\n", This, Flags, clipper, UnkOuter);
252 if(UnkOuter != NULL)
254 /* This may require a wrapper interface for clippers too which handles this */
255 FIXME("Test and implement Aggregation for ddrawex clippers\n");
258 return IDirectDraw4_CreateClipper(This->parent, Flags, clipper, UnkOuter);
261 static HRESULT WINAPI IDirectDraw3Impl_CreateClipper(IDirectDraw3 *iface, DWORD Flags,
262 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
264 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
265 TRACE("Thunking to IDirectDraw4\n");
266 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
269 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(IDirectDraw2 *iface, DWORD Flags,
270 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
272 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
273 TRACE("Thunking to IDirectDraw4\n");
274 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
277 static HRESULT WINAPI IDirectDrawImpl_CreateClipper(IDirectDraw *iface, DWORD Flags,
278 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
280 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
281 TRACE("Thunking to IDirectDraw4\n");
282 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
285 static HRESULT WINAPI IDirectDraw4Impl_CreatePalette(IDirectDraw4 *iface, DWORD Flags,
286 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
288 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
289 TRACE("(%p)(0x%08x,%p,%p,%p)\n", This, Flags, ColorTable, Palette, UnkOuter);
291 if(UnkOuter != NULL)
293 /* This may require a wrapper interface for palettes too which handles this */
294 FIXME("Test and implement Aggregation for ddrawex palettes\n");
297 return IDirectDraw4_CreatePalette(This->parent, Flags, ColorTable, Palette, UnkOuter);
300 static HRESULT WINAPI IDirectDraw3Impl_CreatePalette(IDirectDraw3 *iface, DWORD Flags,
301 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
303 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
304 TRACE("Thunking to IDirectDraw4\n");
305 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
308 static HRESULT WINAPI IDirectDraw2Impl_CreatePalette(IDirectDraw2 *iface, DWORD Flags,
309 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
311 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
312 TRACE("Thunking to IDirectDraw4\n");
313 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
316 static HRESULT WINAPI IDirectDrawImpl_CreatePalette(IDirectDraw *iface, DWORD Flags,
317 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
319 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
320 TRACE("Thunking to IDirectDraw4\n");
321 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
324 static HRESULT WINAPI IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface, DDSURFACEDESC2 *DDSD,
325 IDirectDrawSurface4 **Surf, IUnknown *UnkOuter)
327 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
328 HRESULT hr;
329 const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
330 BOOL permanent_dc;
331 TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter);
333 if(UnkOuter != NULL)
335 /* Handle this in this dll. Don't forward the UnkOuter to ddraw.dll */
336 FIXME("Implement aggregation for ddrawex surfaces\n");
339 /* plain ddraw.dll refuses to create a surface that has both VIDMEM and SYSMEM flags
340 * set. In ddrawex this succeeds, and the GetDC() call changes the behavior. The DC
341 * is permanently valid, and the surface can be locked between GetDC() and ReleaseDC()
342 * calls. GetDC() can be called more than once too
344 if((DDSD->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags)
346 permanent_dc = TRUE;
347 DDSD->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
348 DDSD->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
350 else
352 permanent_dc = FALSE;
355 hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter);
356 *Surf = dds_get_outer(*Surf);
357 if(permanent_dc) prepare_permanent_dc(*Surf);
358 return hr;
361 void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
363 memset(out, 0, sizeof(*out));
364 out->dwSize = sizeof(*out);
365 out->dwFlags = in->dwFlags;
366 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
367 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
368 if(in->dwFlags & DDSD_PIXELFORMAT) out->u4.ddpfPixelFormat = in->ddpfPixelFormat;
369 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
370 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
371 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
372 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwMipMapCount = in->u2.dwZBufferBitDepth; /* same union */
373 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
374 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
375 out->lpSurface = in->lpSurface;
376 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->u3.ddckCKDestOverlay = in->ddckCKDestOverlay;
377 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
378 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
379 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
380 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
381 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
382 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
383 /* Does not exist in DDSURFACEDESC:
384 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
388 void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
390 memset(out, 0, sizeof(*out));
391 out->dwSize = sizeof(*out);
392 out->dwFlags = in->dwFlags;
393 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
394 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
395 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->u4.ddpfPixelFormat;
396 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
397 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
398 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
399 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwZBufferBitDepth = in->u2.dwMipMapCount; /* same union */
400 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
401 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
402 out->lpSurface = in->lpSurface;
403 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->u3.ddckCKDestOverlay;
404 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
405 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
406 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
407 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
408 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
409 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
410 /* Does not exist in DDSURFACEDESC:
411 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
413 if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n");
414 if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n");
415 if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n");
416 out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE);
419 static HRESULT WINAPI IDirectDraw3Impl_CreateSurface(IDirectDraw3 *iface, DDSURFACEDESC *DDSD,
420 IDirectDrawSurface **Surf, IUnknown *UnkOuter)
422 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
423 DDSURFACEDESC2 ddsd2;
424 IDirectDrawSurface4 *surf4 = NULL;
425 HRESULT hr;
426 TRACE("Thunking to IDirectDraw4\n");
428 DDSD_to_DDSD2(DDSD, &ddsd2);
430 hr = IDirectDraw4_CreateSurface(dd4_from_impl(This), &ddsd2, &surf4, UnkOuter);
431 if(FAILED(hr))
433 *Surf = NULL;
434 return hr;
437 TRACE("Got surface %p\n", surf4);
438 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf);
439 IDirectDrawSurface4_Release(surf4);
440 return hr;
443 static HRESULT WINAPI IDirectDraw2Impl_CreateSurface(IDirectDraw2 *iface, DDSURFACEDESC *DDSD,
444 IDirectDrawSurface **Surf, IUnknown *UnkOuter)
446 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
447 TRACE("Thunking to IDirectDraw3\n");
448 return IDirectDraw3_CreateSurface(&This->IDirectDraw3_iface, DDSD, Surf, UnkOuter);
451 static HRESULT WINAPI IDirectDrawImpl_CreateSurface(IDirectDraw *iface, DDSURFACEDESC *DDSD,
452 IDirectDrawSurface **Surf, IUnknown *UnkOuter)
454 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
455 TRACE("Thunking to IDirectDraw3\n");
456 return IDirectDraw3_CreateSurface(&This->IDirectDraw3_iface, DDSD, Surf, UnkOuter);
459 static HRESULT WINAPI IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface,
460 IDirectDrawSurface4 *src, IDirectDrawSurface4 **dst)
462 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
463 FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst);
465 return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(src), dst);
468 static HRESULT WINAPI IDirectDraw3Impl_DuplicateSurface(IDirectDraw3 *iface,
469 IDirectDrawSurface *src, IDirectDrawSurface **dst)
471 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
472 IDirectDrawSurface4 *src_4;
473 IDirectDrawSurface4 *dst_4;
474 HRESULT hr;
476 TRACE("Thunking to IDirectDraw4\n");
477 IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **) &src_4);
478 hr = IDirectDraw4_DuplicateSurface(dd4_from_impl(This), src_4, &dst_4);
479 IDirectDrawSurface4_Release(src_4);
481 if(FAILED(hr))
483 *dst = NULL;
484 return hr;
486 IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **) dst);
487 IDirectDrawSurface4_Release(dst_4);
488 return hr;
491 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(IDirectDraw2 *iface,
492 IDirectDrawSurface *src, IDirectDrawSurface **dst)
494 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
495 TRACE("Thunking to IDirectDraw3\n");
496 return IDirectDraw3_DuplicateSurface(&This->IDirectDraw3_iface, src, dst);
499 static HRESULT WINAPI IDirectDrawImpl_DuplicateSurface(IDirectDraw *iface, IDirectDrawSurface *src,
500 IDirectDrawSurface **dst)
502 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
503 TRACE("Thunking to IDirectDraw3\n");
504 return IDirectDraw3_DuplicateSurface(&This->IDirectDraw3_iface, src, dst);
507 static HRESULT WINAPI IDirectDraw4Impl_EnumDisplayModes(IDirectDraw4 *iface, DWORD Flags,
508 DDSURFACEDESC2 *DDSD, void *Context, LPDDENUMMODESCALLBACK2 cb)
510 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
511 TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, cb);
513 return IDirectDraw4_EnumDisplayModes(This->parent, Flags, DDSD, Context, cb);
516 struct enummodes_ctx
518 LPDDENUMMODESCALLBACK orig_cb;
519 void *orig_ctx;
522 static HRESULT WINAPI
523 enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx)
525 struct enummodes_ctx *ctx = vctx;
526 DDSURFACEDESC ddsd;
528 DDSD2_to_DDSD(ddsd2, &ddsd);
529 return ctx->orig_cb(&ddsd, ctx->orig_ctx);
532 static HRESULT WINAPI IDirectDraw3Impl_EnumDisplayModes(IDirectDraw3 *iface, DWORD Flags,
533 DDSURFACEDESC *DDSD, void *Context, LPDDENUMMODESCALLBACK cb)
535 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
536 DDSURFACEDESC2 ddsd2;
537 struct enummodes_ctx ctx;
538 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, cb);
540 DDSD_to_DDSD2(DDSD, &ddsd2);
541 ctx.orig_cb = cb;
542 ctx.orig_ctx = Context;
543 return IDirectDraw4_EnumDisplayModes(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_modes_cb2);
546 static HRESULT WINAPI IDirectDraw2Impl_EnumDisplayModes(IDirectDraw2 *iface, DWORD Flags,
547 DDSURFACEDESC *DDSD, void *Context, LPDDENUMMODESCALLBACK cb)
549 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
550 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
551 return IDirectDraw3_EnumDisplayModes(&This->IDirectDraw3_iface, Flags, DDSD, Context, cb);
554 static HRESULT WINAPI IDirectDrawImpl_EnumDisplayModes(IDirectDraw *iface, DWORD Flags,
555 DDSURFACEDESC *DDSD, void *Context, LPDDENUMMODESCALLBACK cb)
557 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
558 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
559 return IDirectDraw3_EnumDisplayModes(&This->IDirectDraw3_iface, Flags, DDSD, Context, cb);
562 struct enumsurfaces4_ctx
564 LPDDENUMSURFACESCALLBACK2 orig_cb;
565 void *orig_ctx;
568 static HRESULT WINAPI
569 enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
571 struct enumsurfaces4_ctx *ctx = vctx;
572 IDirectDrawSurface4 *outer = dds_get_outer(surf4);
573 IDirectDrawSurface4_AddRef(outer);
574 IDirectDrawSurface4_Release(surf4);
575 TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4);
576 return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx);
579 static HRESULT WINAPI IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface, DWORD Flags,
580 DDSURFACEDESC2 *DDSD, void *Context, LPDDENUMSURFACESCALLBACK2 Callback)
582 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
583 struct enumsurfaces4_ctx ctx;
584 TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback);
586 ctx.orig_cb = Callback;
587 ctx.orig_ctx = Context;
588 return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, &ctx, enum_surfaces_wrapper);
591 struct enumsurfaces_ctx
593 LPDDENUMSURFACESCALLBACK orig_cb;
594 void *orig_ctx;
597 static HRESULT WINAPI
598 enum_surfaces_cb2(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
600 struct enumsurfaces_ctx *ctx = vctx;
601 IDirectDrawSurface *surf1;
602 DDSURFACEDESC ddsd;
604 /* Keep the reference, it goes to the application */
605 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) &surf1);
606 /* Release the reference this function got */
607 IDirectDrawSurface4_Release(surf4);
609 DDSD2_to_DDSD(ddsd2, &ddsd);
610 return ctx->orig_cb(surf1, &ddsd, ctx->orig_ctx);
613 static HRESULT WINAPI IDirectDraw3Impl_EnumSurfaces(IDirectDraw3 *iface, DWORD Flags,
614 DDSURFACEDESC *DDSD, void *Context, LPDDENUMSURFACESCALLBACK Callback)
616 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
617 DDSURFACEDESC2 ddsd2;
618 struct enumsurfaces_ctx ctx;
619 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, Callback);
621 DDSD_to_DDSD2(DDSD, &ddsd2);
622 ctx.orig_cb = Callback;
623 ctx.orig_ctx = Context;
624 return IDirectDraw4_EnumSurfaces(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_surfaces_cb2);
627 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(IDirectDraw2 *iface, DWORD Flags,
628 DDSURFACEDESC *DDSD, void *Context, LPDDENUMSURFACESCALLBACK Callback)
630 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
631 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
632 return IDirectDraw3_EnumSurfaces(&This->IDirectDraw3_iface, Flags, DDSD, Context, Callback);
635 static HRESULT WINAPI IDirectDrawImpl_EnumSurfaces(IDirectDraw *iface, DWORD Flags,
636 DDSURFACEDESC *DDSD, void *Context, LPDDENUMSURFACESCALLBACK Callback)
638 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
639 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
640 return IDirectDraw3_EnumSurfaces(&This->IDirectDraw3_iface, Flags, DDSD, Context, Callback);
643 static HRESULT WINAPI IDirectDraw4Impl_FlipToGDISurface(IDirectDraw4 *iface)
645 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
646 TRACE("(%p)\n", This);
648 return IDirectDraw4_FlipToGDISurface(This->parent);
651 static HRESULT WINAPI IDirectDraw3Impl_FlipToGDISurface(IDirectDraw3 *iface)
653 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
654 TRACE("(%p). Thunking to IDirectDraw4\n", This);
655 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
658 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(IDirectDraw2 *iface)
660 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
661 TRACE("(%p). Thunking to IDirectDraw4\n", This);
662 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
665 static HRESULT WINAPI IDirectDrawImpl_FlipToGDISurface(IDirectDraw *iface)
667 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
668 TRACE("(%p). Thunking to IDirectDraw4\n", This);
669 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
672 static HRESULT WINAPI IDirectDraw4Impl_GetCaps(IDirectDraw4 *iface, DDCAPS *DriverCaps,
673 DDCAPS *HELCaps)
675 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
676 TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps);
677 return IDirectDraw4_GetCaps(This->parent, DriverCaps, HELCaps);
680 static HRESULT WINAPI IDirectDraw3Impl_GetCaps(IDirectDraw3 *iface, DDCAPS *DriverCaps,
681 DDCAPS *HELCaps)
683 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
684 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
685 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
688 static HRESULT WINAPI IDirectDraw2Impl_GetCaps(IDirectDraw2 *iface, DDCAPS *DriverCaps,
689 DDCAPS *HELCaps)
691 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
692 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
693 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
696 static HRESULT WINAPI IDirectDrawImpl_GetCaps(IDirectDraw *iface, DDCAPS *DriverCaps,
697 DDCAPS *HELCaps)
699 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
700 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
701 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
704 static HRESULT WINAPI IDirectDraw4Impl_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 *DDSD)
706 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
707 TRACE("(%p)->(%p)\n", This, DDSD);
708 return IDirectDraw4_GetDisplayMode(This->parent, DDSD);
711 static HRESULT WINAPI IDirectDraw3Impl_GetDisplayMode(IDirectDraw3 *iface, DDSURFACEDESC *DDSD)
713 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
714 DDSURFACEDESC2 ddsd2;
715 HRESULT hr;
717 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, DDSD);
718 hr = IDirectDraw4_GetDisplayMode(dd4_from_impl(This), &ddsd2);
719 DDSD2_to_DDSD(&ddsd2, DDSD);
720 return hr;
723 static HRESULT WINAPI IDirectDraw2Impl_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC *DDSD)
725 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
726 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
727 return IDirectDraw3_GetDisplayMode(&This->IDirectDraw3_iface, DDSD);
730 static HRESULT WINAPI IDirectDrawImpl_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *DDSD)
732 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
733 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
734 return IDirectDraw3_GetDisplayMode(&This->IDirectDraw3_iface, DDSD);
737 static HRESULT WINAPI IDirectDraw4Impl_GetFourCCCodes(IDirectDraw4 *iface, DWORD *NumCodes,
738 DWORD *Codes)
740 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
741 TRACE("(%p)->(%p, %p):\n", This, NumCodes, Codes);
742 return IDirectDraw4_GetFourCCCodes(This->parent, NumCodes, Codes);
745 static HRESULT WINAPI IDirectDraw3Impl_GetFourCCCodes(IDirectDraw3 *iface, DWORD *NumCodes,
746 DWORD *Codes)
748 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
749 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
750 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
753 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(IDirectDraw2 *iface, DWORD *NumCodes,
754 DWORD *Codes)
756 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
757 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
758 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
761 static HRESULT WINAPI IDirectDrawImpl_GetFourCCCodes(IDirectDraw *iface, DWORD *NumCodes,
762 DWORD *Codes)
764 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
765 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
766 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
769 static HRESULT WINAPI IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface,
770 IDirectDrawSurface4 **GDISurface)
772 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
773 IDirectDrawSurface4 *inner = NULL;
774 HRESULT hr;
775 TRACE("(%p)->(%p)\n", This, GDISurface);
777 hr = IDirectDraw4_GetGDISurface(This->parent, &inner);
778 if(SUCCEEDED(hr))
780 *GDISurface = dds_get_outer(inner);
781 IDirectDrawSurface4_AddRef(*GDISurface);
782 IDirectDrawSurface4_Release(inner);
784 else
786 *GDISurface = NULL;
788 return hr;
791 static HRESULT WINAPI IDirectDraw3Impl_GetGDISurface(IDirectDraw3 *iface,
792 IDirectDrawSurface **GDISurface)
794 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
795 IDirectDrawSurface4 *surf4;
796 HRESULT hr;
797 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, GDISurface);
799 hr = IDirectDraw4_GetGDISurface(dd4_from_impl(This), &surf4);
800 if(FAILED(hr)) {
801 *GDISurface = NULL;
802 return hr;
805 /* Release the reference we got from the DDraw4 call, and pass a reference to the caller */
806 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) GDISurface);
807 IDirectDrawSurface4_Release(surf4);
808 return hr;
811 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(IDirectDraw2 *iface,
812 IDirectDrawSurface **GDISurface)
814 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
815 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
816 return IDirectDraw3_GetGDISurface(&This->IDirectDraw3_iface, GDISurface);
819 static HRESULT WINAPI IDirectDrawImpl_GetGDISurface(IDirectDraw *iface,
820 IDirectDrawSurface **GDISurface)
822 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
823 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
824 return IDirectDraw3_GetGDISurface(&This->IDirectDraw3_iface, GDISurface);
827 static HRESULT WINAPI IDirectDraw4Impl_GetMonitorFrequency(IDirectDraw4 *iface, DWORD *Freq)
829 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
830 TRACE("(%p)->(%p)\n", This, Freq);
831 return IDirectDraw4_GetMonitorFrequency(This->parent, Freq);
834 static HRESULT WINAPI IDirectDraw3Impl_GetMonitorFrequency(IDirectDraw3 *iface, DWORD *Freq)
836 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
837 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
838 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
841 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(IDirectDraw2 *iface, DWORD *Freq)
843 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
844 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
845 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
848 static HRESULT WINAPI IDirectDrawImpl_GetMonitorFrequency(IDirectDraw *iface, DWORD *Freq)
850 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
851 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
852 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
855 static HRESULT WINAPI IDirectDraw4Impl_GetScanLine(IDirectDraw4 *iface, DWORD *Scanline)
857 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
858 TRACE("(%p)->(%p)\n", This, Scanline);
859 return IDirectDraw4_GetScanLine(This->parent, Scanline);
862 static HRESULT WINAPI IDirectDraw3Impl_GetScanLine(IDirectDraw3 *iface, DWORD *Scanline)
864 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
865 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
866 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
869 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(IDirectDraw2 *iface, DWORD *Scanline)
871 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
872 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
873 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
876 static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw *iface, DWORD *Scanline)
878 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
879 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
880 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
883 static HRESULT WINAPI IDirectDraw4Impl_GetVerticalBlankStatus(IDirectDraw4 *iface, BOOL *status)
885 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
886 TRACE("(%p)->(%p)\n", This, status);
887 return IDirectDraw4_GetVerticalBlankStatus(This->parent, status);
890 static HRESULT WINAPI IDirectDraw3Impl_GetVerticalBlankStatus(IDirectDraw3 *iface, BOOL *status)
892 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
893 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
894 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
897 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(IDirectDraw2 *iface, BOOL *status)
899 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
900 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
901 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
904 static HRESULT WINAPI IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *status)
906 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
907 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
908 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
911 static HRESULT WINAPI IDirectDraw4Impl_Initialize(IDirectDraw4 *iface, GUID *Guid)
913 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
914 TRACE("(%p)->(%s)\n", This, debugstr_guid(Guid));
915 return IDirectDraw4_Initialize(This->parent, Guid);
918 static HRESULT WINAPI IDirectDraw3Impl_Initialize(IDirectDraw3 *iface, GUID *Guid)
920 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
921 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
922 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
925 static HRESULT WINAPI IDirectDraw2Impl_Initialize(IDirectDraw2 *iface, GUID *Guid)
927 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
928 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
929 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
932 static HRESULT WINAPI IDirectDrawImpl_Initialize(IDirectDraw *iface, GUID *Guid)
934 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
935 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
936 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
939 static HRESULT WINAPI IDirectDraw4Impl_RestoreDisplayMode(IDirectDraw4 *iface)
941 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
942 TRACE("(%p)\n", This);
943 return IDirectDraw4_RestoreDisplayMode(This->parent);
946 static HRESULT WINAPI IDirectDraw3Impl_RestoreDisplayMode(IDirectDraw3 *iface)
948 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
949 TRACE("(%p): Thunking to IDirectDraw4\n", This);
950 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
953 static HRESULT WINAPI IDirectDraw2Impl_RestoreDisplayMode(IDirectDraw2 *iface)
955 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
956 TRACE("(%p): Thunking to IDirectDraw4\n", This);
957 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
960 static HRESULT WINAPI IDirectDrawImpl_RestoreDisplayMode(IDirectDraw *iface)
962 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
963 TRACE("(%p): Thunking to IDirectDraw4\n", This);
964 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
967 static HRESULT WINAPI IDirectDraw4Impl_SetCooperativeLevel(IDirectDraw4 *iface, HWND hwnd,
968 DWORD cooplevel)
970 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
971 TRACE("(%p)->(%p, 0x%08x)\n", This, hwnd, cooplevel);
972 return IDirectDraw4_SetCooperativeLevel(This->parent, hwnd, cooplevel);
975 static HRESULT WINAPI IDirectDraw3Impl_SetCooperativeLevel(IDirectDraw3 *iface, HWND hwnd,
976 DWORD cooplevel)
978 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
979 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
980 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
983 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(IDirectDraw2 *iface, HWND hwnd,
984 DWORD cooplevel)
986 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
987 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
988 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
991 static HRESULT WINAPI IDirectDrawImpl_SetCooperativeLevel(IDirectDraw *iface, HWND hwnd,
992 DWORD cooplevel)
994 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
995 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
996 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
999 static HRESULT WINAPI IDirectDraw4Impl_SetDisplayMode(IDirectDraw4 *iface, DWORD Width,
1000 DWORD Height, DWORD BPP, DWORD RefreshRate, DWORD Flags)
1002 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1003 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x)\n", This, Width, Height, BPP, RefreshRate, Flags);
1004 return IDirectDraw4_SetDisplayMode(This->parent, Width, Height, BPP, RefreshRate, Flags);
1007 static HRESULT WINAPI IDirectDraw3Impl_SetDisplayMode(IDirectDraw3 *iface, DWORD Width,
1008 DWORD Height, DWORD BPP, DWORD RefreshRate, DWORD Flags)
1010 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1011 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1012 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
1015 static HRESULT WINAPI IDirectDraw2Impl_SetDisplayMode(IDirectDraw2 *iface, DWORD Width,
1016 DWORD Height, DWORD BPP, DWORD RefreshRate, DWORD Flags)
1018 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
1019 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1020 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
1023 static HRESULT WINAPI IDirectDrawImpl_SetDisplayMode(IDirectDraw *iface, DWORD Width, DWORD Height,
1024 DWORD BPP)
1026 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
1027 TRACE("(%p)->(%u, %u, %u): Thunking to IDirectDraw4\n", This, Width, Height, BPP);
1028 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, 0, 0);
1031 static HRESULT WINAPI IDirectDraw4Impl_WaitForVerticalBlank(IDirectDraw4 *iface, DWORD Flags,
1032 HANDLE h)
1034 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1035 TRACE("(%p)->(0x%08x, %p)\n", This, Flags, h);
1036 return IDirectDraw4_WaitForVerticalBlank(This->parent, Flags, h);
1039 static HRESULT WINAPI IDirectDraw3Impl_WaitForVerticalBlank(IDirectDraw3 *iface, DWORD Flags,
1040 HANDLE h)
1042 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1043 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1044 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1047 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(IDirectDraw2 *iface, DWORD Flags,
1048 HANDLE h)
1050 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
1051 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1052 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1055 static HRESULT WINAPI IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw *iface, DWORD Flags,
1056 HANDLE h)
1058 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
1059 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1060 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1063 static HRESULT WINAPI IDirectDraw4Impl_GetAvailableVidMem(IDirectDraw4 *iface, DDSCAPS2 *Caps,
1064 DWORD *total, DWORD *free)
1066 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1067 TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
1068 return IDirectDraw4_GetAvailableVidMem(This->parent, Caps, total, free);
1071 static HRESULT WINAPI IDirectDraw3Impl_GetAvailableVidMem(IDirectDraw3 *iface, DDSCAPS *Caps,
1072 DWORD *total, DWORD *free)
1074 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1075 DDSCAPS2 caps2;
1076 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1077 memset(&caps2, 0, sizeof(caps2));
1078 caps2.dwCaps = Caps->dwCaps;
1079 return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
1082 static HRESULT WINAPI IDirectDraw2Impl_GetAvailableVidMem(IDirectDraw2 *iface, DDSCAPS *Caps,
1083 DWORD *total, DWORD *free)
1085 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
1086 DDSCAPS2 caps2;
1087 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1088 memset(&caps2, 0, sizeof(caps2));
1089 caps2.dwCaps = Caps->dwCaps;
1090 return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
1093 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(IDirectDraw4 *iface, HDC hdc,
1094 IDirectDrawSurface4 **Surface)
1096 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1097 HRESULT hr;
1098 TRACE("(%p)->(%p, %p)\n", This, hdc, Surface);
1099 hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, Surface);
1101 return hr;
1104 static HRESULT WINAPI IDirectDraw3Impl_GetSurfaceFromDC(IDirectDraw3 *iface, HDC hdc,
1105 IDirectDrawSurface **Surface)
1107 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1108 IDirectDrawSurface4 *surf4, *outer;
1109 IDirectDrawSurface *inner;
1110 HRESULT hr;
1111 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, hdc, Surface);
1113 if (!Surface) return E_POINTER;
1115 hr = IDirectDraw4_GetSurfaceFromDC(This->parent, hdc, (IDirectDrawSurface4 **)&inner);
1116 if(FAILED(hr))
1118 *Surface = NULL;
1119 return hr;
1122 hr = IDirectDrawSurface_QueryInterface(inner, &IID_IDirectDrawSurface4, (void **)&surf4);
1123 IDirectDrawSurface_Release(inner);
1124 if (FAILED(hr))
1126 *Surface = NULL;
1127 return hr;
1130 outer = dds_get_outer(surf4);
1131 hr = IDirectDrawSurface4_QueryInterface(outer, &IID_IDirectDrawSurface, (void **)Surface);
1132 IDirectDrawSurface4_Release(surf4);
1133 return hr;
1136 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(IDirectDraw4 *iface)
1138 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1139 TRACE("(%p)\n", This);
1140 return IDirectDraw4_RestoreAllSurfaces(This->parent);
1143 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(IDirectDraw4 *iface)
1145 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1146 TRACE("(%p)\n", This);
1147 return IDirectDraw4_TestCooperativeLevel(This->parent);
1150 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(IDirectDraw4 *iface,
1151 DDDEVICEIDENTIFIER *DDDI, DWORD Flags)
1153 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1154 TRACE("(%p)->(%p,0x%08x)\n", This, DDDI, Flags);
1155 return IDirectDraw4_GetDeviceIdentifier(This->parent, DDDI, Flags);
1158 static const IDirectDrawVtbl IDirectDraw1_Vtbl =
1160 IDirectDrawImpl_QueryInterface,
1161 IDirectDrawImpl_AddRef,
1162 IDirectDrawImpl_Release,
1163 IDirectDrawImpl_Compact,
1164 IDirectDrawImpl_CreateClipper,
1165 IDirectDrawImpl_CreatePalette,
1166 IDirectDrawImpl_CreateSurface,
1167 IDirectDrawImpl_DuplicateSurface,
1168 IDirectDrawImpl_EnumDisplayModes,
1169 IDirectDrawImpl_EnumSurfaces,
1170 IDirectDrawImpl_FlipToGDISurface,
1171 IDirectDrawImpl_GetCaps,
1172 IDirectDrawImpl_GetDisplayMode,
1173 IDirectDrawImpl_GetFourCCCodes,
1174 IDirectDrawImpl_GetGDISurface,
1175 IDirectDrawImpl_GetMonitorFrequency,
1176 IDirectDrawImpl_GetScanLine,
1177 IDirectDrawImpl_GetVerticalBlankStatus,
1178 IDirectDrawImpl_Initialize,
1179 IDirectDrawImpl_RestoreDisplayMode,
1180 IDirectDrawImpl_SetCooperativeLevel,
1181 IDirectDrawImpl_SetDisplayMode,
1182 IDirectDrawImpl_WaitForVerticalBlank,
1185 static const IDirectDraw2Vtbl IDirectDraw2_Vtbl =
1187 IDirectDraw2Impl_QueryInterface,
1188 IDirectDraw2Impl_AddRef,
1189 IDirectDraw2Impl_Release,
1190 IDirectDraw2Impl_Compact,
1191 IDirectDraw2Impl_CreateClipper,
1192 IDirectDraw2Impl_CreatePalette,
1193 IDirectDraw2Impl_CreateSurface,
1194 IDirectDraw2Impl_DuplicateSurface,
1195 IDirectDraw2Impl_EnumDisplayModes,
1196 IDirectDraw2Impl_EnumSurfaces,
1197 IDirectDraw2Impl_FlipToGDISurface,
1198 IDirectDraw2Impl_GetCaps,
1199 IDirectDraw2Impl_GetDisplayMode,
1200 IDirectDraw2Impl_GetFourCCCodes,
1201 IDirectDraw2Impl_GetGDISurface,
1202 IDirectDraw2Impl_GetMonitorFrequency,
1203 IDirectDraw2Impl_GetScanLine,
1204 IDirectDraw2Impl_GetVerticalBlankStatus,
1205 IDirectDraw2Impl_Initialize,
1206 IDirectDraw2Impl_RestoreDisplayMode,
1207 IDirectDraw2Impl_SetCooperativeLevel,
1208 IDirectDraw2Impl_SetDisplayMode,
1209 IDirectDraw2Impl_WaitForVerticalBlank,
1210 IDirectDraw2Impl_GetAvailableVidMem
1213 static const IDirectDraw3Vtbl IDirectDraw3_Vtbl =
1215 IDirectDraw3Impl_QueryInterface,
1216 IDirectDraw3Impl_AddRef,
1217 IDirectDraw3Impl_Release,
1218 IDirectDraw3Impl_Compact,
1219 IDirectDraw3Impl_CreateClipper,
1220 IDirectDraw3Impl_CreatePalette,
1221 IDirectDraw3Impl_CreateSurface,
1222 IDirectDraw3Impl_DuplicateSurface,
1223 IDirectDraw3Impl_EnumDisplayModes,
1224 IDirectDraw3Impl_EnumSurfaces,
1225 IDirectDraw3Impl_FlipToGDISurface,
1226 IDirectDraw3Impl_GetCaps,
1227 IDirectDraw3Impl_GetDisplayMode,
1228 IDirectDraw3Impl_GetFourCCCodes,
1229 IDirectDraw3Impl_GetGDISurface,
1230 IDirectDraw3Impl_GetMonitorFrequency,
1231 IDirectDraw3Impl_GetScanLine,
1232 IDirectDraw3Impl_GetVerticalBlankStatus,
1233 IDirectDraw3Impl_Initialize,
1234 IDirectDraw3Impl_RestoreDisplayMode,
1235 IDirectDraw3Impl_SetCooperativeLevel,
1236 IDirectDraw3Impl_SetDisplayMode,
1237 IDirectDraw3Impl_WaitForVerticalBlank,
1238 IDirectDraw3Impl_GetAvailableVidMem,
1239 IDirectDraw3Impl_GetSurfaceFromDC,
1242 static const IDirectDraw4Vtbl IDirectDraw4_Vtbl =
1244 IDirectDraw4Impl_QueryInterface,
1245 IDirectDraw4Impl_AddRef,
1246 IDirectDraw4Impl_Release,
1247 IDirectDraw4Impl_Compact,
1248 IDirectDraw4Impl_CreateClipper,
1249 IDirectDraw4Impl_CreatePalette,
1250 IDirectDraw4Impl_CreateSurface,
1251 IDirectDraw4Impl_DuplicateSurface,
1252 IDirectDraw4Impl_EnumDisplayModes,
1253 IDirectDraw4Impl_EnumSurfaces,
1254 IDirectDraw4Impl_FlipToGDISurface,
1255 IDirectDraw4Impl_GetCaps,
1256 IDirectDraw4Impl_GetDisplayMode,
1257 IDirectDraw4Impl_GetFourCCCodes,
1258 IDirectDraw4Impl_GetGDISurface,
1259 IDirectDraw4Impl_GetMonitorFrequency,
1260 IDirectDraw4Impl_GetScanLine,
1261 IDirectDraw4Impl_GetVerticalBlankStatus,
1262 IDirectDraw4Impl_Initialize,
1263 IDirectDraw4Impl_RestoreDisplayMode,
1264 IDirectDraw4Impl_SetCooperativeLevel,
1265 IDirectDraw4Impl_SetDisplayMode,
1266 IDirectDraw4Impl_WaitForVerticalBlank,
1267 IDirectDraw4Impl_GetAvailableVidMem,
1268 IDirectDraw4Impl_GetSurfaceFromDC,
1269 IDirectDraw4Impl_RestoreAllSurfaces,
1270 IDirectDraw4Impl_TestCooperativeLevel,
1271 IDirectDraw4Impl_GetDeviceIdentifier
1274 /*******************************************************************************
1275 * IDirectDrawFactoryImpl_CreateDirectDraw
1276 *******************************************************************************/
1277 HRESULT WINAPI
1278 IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface,
1279 GUID * pGUID,
1280 HWND hWnd,
1281 DWORD dwCoopLevelFlags,
1282 DWORD dwReserved,
1283 IUnknown *pUnkOuter,
1284 IDirectDraw **ppDirectDraw)
1286 HRESULT hr;
1287 IDirectDrawImpl *object = NULL;
1288 IDirectDraw *parent = NULL;
1290 TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p,%p)\n", iface, debugstr_guid(pGUID), hWnd, dwCoopLevelFlags,
1291 dwReserved, pUnkOuter, ppDirectDraw);
1293 if(pUnkOuter)
1295 FIXME("Implement aggregation in ddrawex's IDirectDraw interface\n");
1298 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1299 if(!object)
1301 ERR("Out of memory\n");
1302 hr = E_OUTOFMEMORY;
1303 goto err;
1305 object->ref = 1;
1306 object->IDirectDraw_iface.lpVtbl = &IDirectDraw1_Vtbl;
1307 object->IDirectDraw2_iface.lpVtbl = &IDirectDraw2_Vtbl;
1308 object->IDirectDraw3_iface.lpVtbl = &IDirectDraw3_Vtbl;
1309 object->IDirectDraw4_Vtbl = &IDirectDraw4_Vtbl;
1311 hr = DirectDrawCreate(pGUID, &parent, NULL);
1312 if (FAILED(hr)) goto err;
1314 hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **) &object->parent);
1315 if(FAILED(hr)) goto err;
1317 hr = IDirectDraw_SetCooperativeLevel(&object->IDirectDraw_iface, hWnd, dwCoopLevelFlags);
1318 if (FAILED(hr)) goto err;
1320 *ppDirectDraw = &object->IDirectDraw_iface;
1321 IDirectDraw_Release(parent);
1322 return DD_OK;
1324 err:
1325 if(object && object->parent) IDirectDraw4_Release(object->parent);
1326 if(parent) IDirectDraw_Release(parent);
1327 HeapFree(GetProcessHeap(), 0, object);
1328 *ppDirectDraw = NULL;
1329 return hr;
1332 IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
1334 IDirectDrawImpl *This = impl_from_IDirectDraw4(outer);
1335 return This->parent;