po: Update French translation.
[wine/multimedia.git] / dlls / ddrawex / ddraw.c
blobab3c731f5be7db1286477fc7f7df58e0810a3a82
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 CONTAINING_RECORD(iface, IDirectDrawImpl, IDirectDraw4_iface);
58 /******************************************************************************
59 * IDirectDraw4 -> ddraw.dll wrappers
60 ******************************************************************************/
61 static HRESULT WINAPI IDirectDraw4Impl_QueryInterface(IDirectDraw4 *iface, REFIID refiid,
62 void **obj)
64 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
66 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
67 *obj = NULL;
69 if(!refiid)
71 return DDERR_INVALIDPARAMS;
74 if (IsEqualGUID( &IID_IDirectDraw7, refiid ) )
76 WARN("IDirectDraw7 not allowed in ddrawex.dll\n");
77 return E_NOINTERFACE;
79 else if ( IsEqualGUID( &IID_IUnknown, refiid ) ||
80 IsEqualGUID( &IID_IDirectDraw4, refiid ) )
82 *obj = &This->IDirectDraw4_iface;
83 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
84 IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
86 else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) )
88 *obj = &This->IDirectDraw3_iface;
89 TRACE("(%p) Returning IDirectDraw3 interface at %p\n", This, *obj);
90 IDirectDraw3_AddRef(&This->IDirectDraw3_iface);
92 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
94 *obj = &This->IDirectDraw2_iface;
95 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
96 IDirectDraw2_AddRef(&This->IDirectDraw2_iface);
98 else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
100 *obj = &This->IDirectDraw_iface;
101 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
102 IDirectDraw_AddRef(&This->IDirectDraw_iface);
104 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
105 IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
106 IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
107 IsEqualGUID( &IID_IDirect3D7 , refiid ) )
109 WARN("Direct3D not allowed in ddrawex.dll\n");
110 return E_NOINTERFACE;
112 /* Unknown interface */
113 else
115 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
116 return E_NOINTERFACE;
118 TRACE("Returning S_OK\n");
119 return S_OK;
122 static HRESULT WINAPI IDirectDraw3Impl_QueryInterface(IDirectDraw3 *iface, REFIID refiid,
123 void **obj)
125 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
126 TRACE("Thunking to IDirectDraw4\n");
127 return IDirectDraw4_QueryInterface(&This->IDirectDraw4_iface, refiid, obj);
130 static HRESULT WINAPI IDirectDraw2Impl_QueryInterface(IDirectDraw2 *iface, REFIID refiid,
131 void **obj)
133 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
134 TRACE("Thunking to IDirectDraw4\n");
135 return IDirectDraw4_QueryInterface(&This->IDirectDraw4_iface, refiid, obj);
138 static HRESULT WINAPI IDirectDrawImpl_QueryInterface(IDirectDraw *iface, REFIID refiid, void **obj)
140 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
141 TRACE("Thunking to IDirectDraw4\n");
142 return IDirectDraw4_QueryInterface(&This->IDirectDraw4_iface, refiid, obj);
145 static ULONG WINAPI IDirectDraw4Impl_AddRef(IDirectDraw4 *iface)
147 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
148 ULONG ref = InterlockedIncrement(&This->ref);
150 TRACE("(%p) : incrementing refcount from %u.\n", This, ref - 1);
152 return ref;
155 static ULONG WINAPI IDirectDraw3Impl_AddRef(IDirectDraw3 *iface)
157 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
158 TRACE("Thunking to IDirectDraw4\n");
159 return IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
162 static ULONG WINAPI IDirectDraw2Impl_AddRef(IDirectDraw2 *iface)
164 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
165 TRACE("Thunking to IDirectDraw4\n");
166 return IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
169 static ULONG WINAPI IDirectDrawImpl_AddRef(IDirectDraw *iface)
171 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
172 TRACE("Thunking to IDirectDraw4\n");
173 return IDirectDraw4_AddRef(&This->IDirectDraw4_iface);
176 static ULONG WINAPI IDirectDraw4Impl_Release(IDirectDraw4 *iface)
178 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
179 ULONG ref = InterlockedDecrement(&This->ref);
181 TRACE("(%p) : decrementing refcount to %u.\n", This, ref);
183 if(ref == 0)
185 TRACE("Destroying object\n");
186 IDirectDraw4_Release(This->parent);
187 HeapFree(GetProcessHeap(), 0, This);
189 return ref;
192 static ULONG WINAPI IDirectDraw3Impl_Release(IDirectDraw3 *iface)
194 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
195 TRACE("Thunking to IDirectDraw4\n");
196 return IDirectDraw4_Release(&This->IDirectDraw4_iface);
199 static ULONG WINAPI IDirectDraw2Impl_Release(IDirectDraw2 *iface)
201 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
202 TRACE("Thunking to IDirectDraw4\n");
203 return IDirectDraw4_Release(&This->IDirectDraw4_iface);
206 static ULONG WINAPI IDirectDrawImpl_Release(IDirectDraw *iface)
208 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
209 TRACE("Thunking to IDirectDraw4\n");
210 return IDirectDraw4_Release(&This->IDirectDraw4_iface);
213 static HRESULT WINAPI IDirectDraw4Impl_Compact(IDirectDraw4 *iface)
215 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
216 TRACE("(%p)\n", This);
218 return IDirectDraw4_Compact(This->parent);
221 static HRESULT WINAPI IDirectDraw3Impl_Compact(IDirectDraw3 *iface)
223 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
224 TRACE("Thunking to IDirectDraw4\n");
225 return IDirectDraw4_Compact(&This->IDirectDraw4_iface);
228 static HRESULT WINAPI IDirectDraw2Impl_Compact(IDirectDraw2 *iface)
230 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
231 TRACE("Thunking to IDirectDraw4\n");
232 return IDirectDraw4_Compact(&This->IDirectDraw4_iface);
235 static HRESULT WINAPI IDirectDrawImpl_Compact(IDirectDraw *iface)
237 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
238 TRACE("Thunking to IDirectDraw4\n");
239 return IDirectDraw4_Compact(&This->IDirectDraw4_iface);
242 static HRESULT WINAPI IDirectDraw4Impl_CreateClipper(IDirectDraw4 *iface, DWORD Flags,
243 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
245 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
246 TRACE("(%p)->(0x%08x, %p, %p)\n", This, Flags, clipper, UnkOuter);
248 if(UnkOuter != NULL)
250 /* This may require a wrapper interface for clippers too which handles this */
251 FIXME("Test and implement Aggregation for ddrawex clippers\n");
254 return IDirectDraw4_CreateClipper(This->parent, Flags, clipper, UnkOuter);
257 static HRESULT WINAPI IDirectDraw3Impl_CreateClipper(IDirectDraw3 *iface, DWORD Flags,
258 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
260 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
261 TRACE("Thunking to IDirectDraw4\n");
262 return IDirectDraw4_CreateClipper(&This->IDirectDraw4_iface, Flags, clipper, UnkOuter);
265 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(IDirectDraw2 *iface, DWORD Flags,
266 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
268 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
269 TRACE("Thunking to IDirectDraw4\n");
270 return IDirectDraw4_CreateClipper(&This->IDirectDraw4_iface, Flags, clipper, UnkOuter);
273 static HRESULT WINAPI IDirectDrawImpl_CreateClipper(IDirectDraw *iface, DWORD Flags,
274 IDirectDrawClipper **clipper, IUnknown *UnkOuter)
276 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
277 TRACE("Thunking to IDirectDraw4\n");
278 return IDirectDraw4_CreateClipper(&This->IDirectDraw4_iface, Flags, clipper, UnkOuter);
281 static HRESULT WINAPI IDirectDraw4Impl_CreatePalette(IDirectDraw4 *iface, DWORD Flags,
282 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
284 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
285 TRACE("(%p)(0x%08x,%p,%p,%p)\n", This, Flags, ColorTable, Palette, UnkOuter);
287 if(UnkOuter != NULL)
289 /* This may require a wrapper interface for palettes too which handles this */
290 FIXME("Test and implement Aggregation for ddrawex palettes\n");
293 return IDirectDraw4_CreatePalette(This->parent, Flags, ColorTable, Palette, UnkOuter);
296 static HRESULT WINAPI IDirectDraw3Impl_CreatePalette(IDirectDraw3 *iface, DWORD Flags,
297 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
299 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
300 TRACE("Thunking to IDirectDraw4\n");
301 return IDirectDraw4_CreatePalette(&This->IDirectDraw4_iface, Flags, ColorTable, Palette,
302 UnkOuter);
305 static HRESULT WINAPI IDirectDraw2Impl_CreatePalette(IDirectDraw2 *iface, DWORD Flags,
306 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
308 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
309 TRACE("Thunking to IDirectDraw4\n");
310 return IDirectDraw4_CreatePalette(&This->IDirectDraw4_iface, Flags, ColorTable, Palette,
311 UnkOuter);
314 static HRESULT WINAPI IDirectDrawImpl_CreatePalette(IDirectDraw *iface, DWORD Flags,
315 PALETTEENTRY *ColorTable, IDirectDrawPalette **Palette, IUnknown *UnkOuter)
317 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
318 TRACE("Thunking to IDirectDraw4\n");
319 return IDirectDraw4_CreatePalette(&This->IDirectDraw4_iface, Flags, ColorTable, Palette,
320 UnkOuter);
323 static HRESULT WINAPI IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface, DDSURFACEDESC2 *DDSD,
324 IDirectDrawSurface4 **Surf, IUnknown *UnkOuter)
326 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
327 HRESULT hr;
328 const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
329 BOOL permanent_dc;
330 TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter);
332 if(UnkOuter != NULL)
334 /* Handle this in this dll. Don't forward the UnkOuter to ddraw.dll */
335 FIXME("Implement aggregation for ddrawex surfaces\n");
338 /* plain ddraw.dll refuses to create a surface that has both VIDMEM and SYSMEM flags
339 * set. In ddrawex this succeeds, and the GetDC() call changes the behavior. The DC
340 * is permanently valid, and the surface can be locked between GetDC() and ReleaseDC()
341 * calls. GetDC() can be called more than once too
343 if((DDSD->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags)
345 permanent_dc = TRUE;
346 DDSD->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
347 DDSD->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
349 else
351 permanent_dc = FALSE;
354 hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter);
355 *Surf = dds_get_outer(*Surf);
356 if(permanent_dc) prepare_permanent_dc(*Surf);
357 return hr;
360 void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
362 memset(out, 0, sizeof(*out));
363 out->dwSize = sizeof(*out);
364 out->dwFlags = in->dwFlags;
365 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
366 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
367 if(in->dwFlags & DDSD_PIXELFORMAT) out->u4.ddpfPixelFormat = in->ddpfPixelFormat;
368 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
369 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
370 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
371 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwMipMapCount = in->u2.dwZBufferBitDepth; /* same union */
372 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
373 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
374 out->lpSurface = in->lpSurface;
375 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->u3.ddckCKDestOverlay = in->ddckCKDestOverlay;
376 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
377 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
378 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
379 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
380 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
381 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
382 /* Does not exist in DDSURFACEDESC:
383 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
387 void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
389 memset(out, 0, sizeof(*out));
390 out->dwSize = sizeof(*out);
391 out->dwFlags = in->dwFlags;
392 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
393 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
394 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->u4.ddpfPixelFormat;
395 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
396 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
397 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
398 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwZBufferBitDepth = in->u2.dwMipMapCount; /* same union */
399 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
400 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
401 out->lpSurface = in->lpSurface;
402 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->u3.ddckCKDestOverlay;
403 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
404 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
405 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
406 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
407 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
408 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
409 /* Does not exist in DDSURFACEDESC:
410 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
412 if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n");
413 if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n");
414 if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n");
415 out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE);
418 static HRESULT WINAPI IDirectDraw3Impl_CreateSurface(IDirectDraw3 *iface, DDSURFACEDESC *DDSD,
419 IDirectDrawSurface **Surf, IUnknown *UnkOuter)
421 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
422 DDSURFACEDESC2 ddsd2;
423 IDirectDrawSurface4 *surf4 = NULL;
424 HRESULT hr;
425 TRACE("Thunking to IDirectDraw4\n");
427 DDSD_to_DDSD2(DDSD, &ddsd2);
429 hr = IDirectDraw4_CreateSurface(&This->IDirectDraw4_iface, &ddsd2, &surf4, UnkOuter);
430 if(FAILED(hr))
432 *Surf = NULL;
433 return hr;
436 TRACE("Got surface %p\n", surf4);
437 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf);
438 IDirectDrawSurface4_Release(surf4);
439 return hr;
442 static HRESULT WINAPI IDirectDraw2Impl_CreateSurface(IDirectDraw2 *iface, DDSURFACEDESC *DDSD,
443 IDirectDrawSurface **Surf, IUnknown *UnkOuter)
445 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
446 TRACE("Thunking to IDirectDraw3\n");
447 return IDirectDraw3_CreateSurface(&This->IDirectDraw3_iface, DDSD, Surf, UnkOuter);
450 static HRESULT WINAPI IDirectDrawImpl_CreateSurface(IDirectDraw *iface, DDSURFACEDESC *DDSD,
451 IDirectDrawSurface **Surf, IUnknown *UnkOuter)
453 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
454 TRACE("Thunking to IDirectDraw3\n");
455 return IDirectDraw3_CreateSurface(&This->IDirectDraw3_iface, DDSD, Surf, UnkOuter);
458 static HRESULT WINAPI IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface,
459 IDirectDrawSurface4 *src, IDirectDrawSurface4 **dst)
461 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
462 FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst);
464 return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(src), dst);
467 static HRESULT WINAPI IDirectDraw3Impl_DuplicateSurface(IDirectDraw3 *iface,
468 IDirectDrawSurface *src, IDirectDrawSurface **dst)
470 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
471 IDirectDrawSurface4 *src_4;
472 IDirectDrawSurface4 *dst_4;
473 HRESULT hr;
475 TRACE("Thunking to IDirectDraw4\n");
476 IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **) &src_4);
477 hr = IDirectDraw4_DuplicateSurface(&This->IDirectDraw4_iface, src_4, &dst_4);
478 IDirectDrawSurface4_Release(src_4);
480 if(FAILED(hr))
482 *dst = NULL;
483 return hr;
485 IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **) dst);
486 IDirectDrawSurface4_Release(dst_4);
487 return hr;
490 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(IDirectDraw2 *iface,
491 IDirectDrawSurface *src, IDirectDrawSurface **dst)
493 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
494 TRACE("Thunking to IDirectDraw3\n");
495 return IDirectDraw3_DuplicateSurface(&This->IDirectDraw3_iface, src, dst);
498 static HRESULT WINAPI IDirectDrawImpl_DuplicateSurface(IDirectDraw *iface, IDirectDrawSurface *src,
499 IDirectDrawSurface **dst)
501 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
502 TRACE("Thunking to IDirectDraw3\n");
503 return IDirectDraw3_DuplicateSurface(&This->IDirectDraw3_iface, src, dst);
506 static HRESULT WINAPI IDirectDraw4Impl_EnumDisplayModes(IDirectDraw4 *iface, DWORD Flags,
507 DDSURFACEDESC2 *DDSD, void *Context, LPDDENUMMODESCALLBACK2 cb)
509 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
510 TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, cb);
512 return IDirectDraw4_EnumDisplayModes(This->parent, Flags, DDSD, Context, cb);
515 struct enummodes_ctx
517 LPDDENUMMODESCALLBACK orig_cb;
518 void *orig_ctx;
521 static HRESULT WINAPI
522 enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx)
524 struct enummodes_ctx *ctx = vctx;
525 DDSURFACEDESC ddsd;
527 DDSD2_to_DDSD(ddsd2, &ddsd);
528 return ctx->orig_cb(&ddsd, ctx->orig_ctx);
531 static HRESULT WINAPI IDirectDraw3Impl_EnumDisplayModes(IDirectDraw3 *iface, DWORD Flags,
532 DDSURFACEDESC *DDSD, void *Context, LPDDENUMMODESCALLBACK cb)
534 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
535 DDSURFACEDESC2 ddsd2;
536 struct enummodes_ctx ctx;
537 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, cb);
539 DDSD_to_DDSD2(DDSD, &ddsd2);
540 ctx.orig_cb = cb;
541 ctx.orig_ctx = Context;
542 return IDirectDraw4_EnumDisplayModes(&This->IDirectDraw4_iface, Flags, &ddsd2, &ctx,
543 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(&This->IDirectDraw4_iface, Flags, &ddsd2, &ctx,
625 enum_surfaces_cb2);
628 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(IDirectDraw2 *iface, DWORD Flags,
629 DDSURFACEDESC *DDSD, void *Context, LPDDENUMSURFACESCALLBACK Callback)
631 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
632 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
633 return IDirectDraw3_EnumSurfaces(&This->IDirectDraw3_iface, Flags, DDSD, Context, Callback);
636 static HRESULT WINAPI IDirectDrawImpl_EnumSurfaces(IDirectDraw *iface, DWORD Flags,
637 DDSURFACEDESC *DDSD, void *Context, LPDDENUMSURFACESCALLBACK Callback)
639 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
640 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
641 return IDirectDraw3_EnumSurfaces(&This->IDirectDraw3_iface, Flags, DDSD, Context, Callback);
644 static HRESULT WINAPI IDirectDraw4Impl_FlipToGDISurface(IDirectDraw4 *iface)
646 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
647 TRACE("(%p)\n", This);
649 return IDirectDraw4_FlipToGDISurface(This->parent);
652 static HRESULT WINAPI IDirectDraw3Impl_FlipToGDISurface(IDirectDraw3 *iface)
654 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
655 TRACE("(%p). Thunking to IDirectDraw4\n", This);
656 return IDirectDraw4_FlipToGDISurface(&This->IDirectDraw4_iface);
659 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(IDirectDraw2 *iface)
661 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
662 TRACE("(%p). Thunking to IDirectDraw4\n", This);
663 return IDirectDraw4_FlipToGDISurface(&This->IDirectDraw4_iface);
666 static HRESULT WINAPI IDirectDrawImpl_FlipToGDISurface(IDirectDraw *iface)
668 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
669 TRACE("(%p). Thunking to IDirectDraw4\n", This);
670 return IDirectDraw4_FlipToGDISurface(&This->IDirectDraw4_iface);
673 static HRESULT WINAPI IDirectDraw4Impl_GetCaps(IDirectDraw4 *iface, DDCAPS *DriverCaps,
674 DDCAPS *HELCaps)
676 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
677 TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps);
678 return IDirectDraw4_GetCaps(This->parent, DriverCaps, HELCaps);
681 static HRESULT WINAPI IDirectDraw3Impl_GetCaps(IDirectDraw3 *iface, DDCAPS *DriverCaps,
682 DDCAPS *HELCaps)
684 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
685 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
686 return IDirectDraw4_GetCaps(&This->IDirectDraw4_iface, DriverCaps, HELCaps);
689 static HRESULT WINAPI IDirectDraw2Impl_GetCaps(IDirectDraw2 *iface, DDCAPS *DriverCaps,
690 DDCAPS *HELCaps)
692 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
693 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
694 return IDirectDraw4_GetCaps(&This->IDirectDraw4_iface, DriverCaps, HELCaps);
697 static HRESULT WINAPI IDirectDrawImpl_GetCaps(IDirectDraw *iface, DDCAPS *DriverCaps,
698 DDCAPS *HELCaps)
700 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
701 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
702 return IDirectDraw4_GetCaps(&This->IDirectDraw4_iface, DriverCaps, HELCaps);
705 static HRESULT WINAPI IDirectDraw4Impl_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 *DDSD)
707 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
708 TRACE("(%p)->(%p)\n", This, DDSD);
709 return IDirectDraw4_GetDisplayMode(This->parent, DDSD);
712 static HRESULT WINAPI IDirectDraw3Impl_GetDisplayMode(IDirectDraw3 *iface, DDSURFACEDESC *DDSD)
714 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
715 DDSURFACEDESC2 ddsd2;
716 HRESULT hr;
718 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, DDSD);
719 hr = IDirectDraw4_GetDisplayMode(&This->IDirectDraw4_iface, &ddsd2);
720 DDSD2_to_DDSD(&ddsd2, DDSD);
721 return hr;
724 static HRESULT WINAPI IDirectDraw2Impl_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC *DDSD)
726 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
727 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
728 return IDirectDraw3_GetDisplayMode(&This->IDirectDraw3_iface, DDSD);
731 static HRESULT WINAPI IDirectDrawImpl_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *DDSD)
733 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
734 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
735 return IDirectDraw3_GetDisplayMode(&This->IDirectDraw3_iface, DDSD);
738 static HRESULT WINAPI IDirectDraw4Impl_GetFourCCCodes(IDirectDraw4 *iface, DWORD *NumCodes,
739 DWORD *Codes)
741 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
742 TRACE("(%p)->(%p, %p):\n", This, NumCodes, Codes);
743 return IDirectDraw4_GetFourCCCodes(This->parent, NumCodes, Codes);
746 static HRESULT WINAPI IDirectDraw3Impl_GetFourCCCodes(IDirectDraw3 *iface, DWORD *NumCodes,
747 DWORD *Codes)
749 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
750 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
751 return IDirectDraw4_GetFourCCCodes(&This->IDirectDraw4_iface, NumCodes, Codes);
754 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(IDirectDraw2 *iface, DWORD *NumCodes,
755 DWORD *Codes)
757 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
758 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
759 return IDirectDraw4_GetFourCCCodes(&This->IDirectDraw4_iface, NumCodes, Codes);
762 static HRESULT WINAPI IDirectDrawImpl_GetFourCCCodes(IDirectDraw *iface, DWORD *NumCodes,
763 DWORD *Codes)
765 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
766 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
767 return IDirectDraw4_GetFourCCCodes(&This->IDirectDraw4_iface, NumCodes, Codes);
770 static HRESULT WINAPI IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface,
771 IDirectDrawSurface4 **GDISurface)
773 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
774 IDirectDrawSurface4 *inner = NULL;
775 HRESULT hr;
776 TRACE("(%p)->(%p)\n", This, GDISurface);
778 hr = IDirectDraw4_GetGDISurface(This->parent, &inner);
779 if(SUCCEEDED(hr))
781 *GDISurface = dds_get_outer(inner);
782 IDirectDrawSurface4_AddRef(*GDISurface);
783 IDirectDrawSurface4_Release(inner);
785 else
787 *GDISurface = NULL;
789 return hr;
792 static HRESULT WINAPI IDirectDraw3Impl_GetGDISurface(IDirectDraw3 *iface,
793 IDirectDrawSurface **GDISurface)
795 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
796 IDirectDrawSurface4 *surf4;
797 HRESULT hr;
798 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, GDISurface);
800 hr = IDirectDraw4_GetGDISurface(&This->IDirectDraw4_iface, &surf4);
801 if(FAILED(hr)) {
802 *GDISurface = NULL;
803 return hr;
806 /* Release the reference we got from the DDraw4 call, and pass a reference to the caller */
807 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) GDISurface);
808 IDirectDrawSurface4_Release(surf4);
809 return hr;
812 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(IDirectDraw2 *iface,
813 IDirectDrawSurface **GDISurface)
815 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
816 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
817 return IDirectDraw3_GetGDISurface(&This->IDirectDraw3_iface, GDISurface);
820 static HRESULT WINAPI IDirectDrawImpl_GetGDISurface(IDirectDraw *iface,
821 IDirectDrawSurface **GDISurface)
823 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
824 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
825 return IDirectDraw3_GetGDISurface(&This->IDirectDraw3_iface, GDISurface);
828 static HRESULT WINAPI IDirectDraw4Impl_GetMonitorFrequency(IDirectDraw4 *iface, DWORD *Freq)
830 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
831 TRACE("(%p)->(%p)\n", This, Freq);
832 return IDirectDraw4_GetMonitorFrequency(This->parent, Freq);
835 static HRESULT WINAPI IDirectDraw3Impl_GetMonitorFrequency(IDirectDraw3 *iface, DWORD *Freq)
837 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
838 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
839 return IDirectDraw4_GetMonitorFrequency(&This->IDirectDraw4_iface, Freq);
842 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(IDirectDraw2 *iface, DWORD *Freq)
844 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
845 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
846 return IDirectDraw4_GetMonitorFrequency(&This->IDirectDraw4_iface, Freq);
849 static HRESULT WINAPI IDirectDrawImpl_GetMonitorFrequency(IDirectDraw *iface, DWORD *Freq)
851 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
852 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
853 return IDirectDraw4_GetMonitorFrequency(&This->IDirectDraw4_iface, Freq);
856 static HRESULT WINAPI IDirectDraw4Impl_GetScanLine(IDirectDraw4 *iface, DWORD *Scanline)
858 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
859 TRACE("(%p)->(%p)\n", This, Scanline);
860 return IDirectDraw4_GetScanLine(This->parent, Scanline);
863 static HRESULT WINAPI IDirectDraw3Impl_GetScanLine(IDirectDraw3 *iface, DWORD *Scanline)
865 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
866 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
867 return IDirectDraw4_GetScanLine(&This->IDirectDraw4_iface, Scanline);
870 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(IDirectDraw2 *iface, DWORD *Scanline)
872 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
873 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
874 return IDirectDraw4_GetScanLine(&This->IDirectDraw4_iface, Scanline);
877 static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw *iface, DWORD *Scanline)
879 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
880 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
881 return IDirectDraw4_GetScanLine(&This->IDirectDraw4_iface, Scanline);
884 static HRESULT WINAPI IDirectDraw4Impl_GetVerticalBlankStatus(IDirectDraw4 *iface, BOOL *status)
886 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
887 TRACE("(%p)->(%p)\n", This, status);
888 return IDirectDraw4_GetVerticalBlankStatus(This->parent, status);
891 static HRESULT WINAPI IDirectDraw3Impl_GetVerticalBlankStatus(IDirectDraw3 *iface, BOOL *status)
893 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
894 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
895 return IDirectDraw4_GetVerticalBlankStatus(&This->IDirectDraw4_iface, status);
898 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(IDirectDraw2 *iface, BOOL *status)
900 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
901 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
902 return IDirectDraw4_GetVerticalBlankStatus(&This->IDirectDraw4_iface, status);
905 static HRESULT WINAPI IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *status)
907 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
908 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
909 return IDirectDraw4_GetVerticalBlankStatus(&This->IDirectDraw4_iface, status);
912 static HRESULT WINAPI IDirectDraw4Impl_Initialize(IDirectDraw4 *iface, GUID *Guid)
914 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
915 TRACE("(%p)->(%s)\n", This, debugstr_guid(Guid));
916 return IDirectDraw4_Initialize(This->parent, Guid);
919 static HRESULT WINAPI IDirectDraw3Impl_Initialize(IDirectDraw3 *iface, GUID *Guid)
921 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
922 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
923 return IDirectDraw4_Initialize(&This->IDirectDraw4_iface, Guid);
926 static HRESULT WINAPI IDirectDraw2Impl_Initialize(IDirectDraw2 *iface, GUID *Guid)
928 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
929 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
930 return IDirectDraw4_Initialize(&This->IDirectDraw4_iface, Guid);
933 static HRESULT WINAPI IDirectDrawImpl_Initialize(IDirectDraw *iface, GUID *Guid)
935 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
936 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
937 return IDirectDraw4_Initialize(&This->IDirectDraw4_iface, Guid);
940 static HRESULT WINAPI IDirectDraw4Impl_RestoreDisplayMode(IDirectDraw4 *iface)
942 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
943 TRACE("(%p)\n", This);
944 return IDirectDraw4_RestoreDisplayMode(This->parent);
947 static HRESULT WINAPI IDirectDraw3Impl_RestoreDisplayMode(IDirectDraw3 *iface)
949 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
950 TRACE("(%p): Thunking to IDirectDraw4\n", This);
951 return IDirectDraw4_RestoreDisplayMode(&This->IDirectDraw4_iface);
954 static HRESULT WINAPI IDirectDraw2Impl_RestoreDisplayMode(IDirectDraw2 *iface)
956 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
957 TRACE("(%p): Thunking to IDirectDraw4\n", This);
958 return IDirectDraw4_RestoreDisplayMode(&This->IDirectDraw4_iface);
961 static HRESULT WINAPI IDirectDrawImpl_RestoreDisplayMode(IDirectDraw *iface)
963 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
964 TRACE("(%p): Thunking to IDirectDraw4\n", This);
965 return IDirectDraw4_RestoreDisplayMode(&This->IDirectDraw4_iface);
968 static HRESULT WINAPI IDirectDraw4Impl_SetCooperativeLevel(IDirectDraw4 *iface, HWND hwnd,
969 DWORD cooplevel)
971 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
972 TRACE("(%p)->(%p, 0x%08x)\n", This, hwnd, cooplevel);
973 return IDirectDraw4_SetCooperativeLevel(This->parent, hwnd, cooplevel);
976 static HRESULT WINAPI IDirectDraw3Impl_SetCooperativeLevel(IDirectDraw3 *iface, HWND hwnd,
977 DWORD cooplevel)
979 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
980 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
981 return IDirectDraw4_SetCooperativeLevel(&This->IDirectDraw4_iface, hwnd, cooplevel);
984 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(IDirectDraw2 *iface, HWND hwnd,
985 DWORD cooplevel)
987 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
988 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
989 return IDirectDraw4_SetCooperativeLevel(&This->IDirectDraw4_iface, hwnd, cooplevel);
992 static HRESULT WINAPI IDirectDrawImpl_SetCooperativeLevel(IDirectDraw *iface, HWND hwnd,
993 DWORD cooplevel)
995 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
996 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
997 return IDirectDraw4_SetCooperativeLevel(&This->IDirectDraw4_iface, hwnd, cooplevel);
1000 static HRESULT WINAPI IDirectDraw4Impl_SetDisplayMode(IDirectDraw4 *iface, DWORD Width,
1001 DWORD Height, DWORD BPP, DWORD RefreshRate, DWORD Flags)
1003 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1004 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x)\n", This, Width, Height, BPP, RefreshRate, Flags);
1005 return IDirectDraw4_SetDisplayMode(This->parent, Width, Height, BPP, RefreshRate, Flags);
1008 static HRESULT WINAPI IDirectDraw3Impl_SetDisplayMode(IDirectDraw3 *iface, DWORD Width,
1009 DWORD Height, DWORD BPP, DWORD RefreshRate, DWORD Flags)
1011 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1012 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1013 return IDirectDraw3_SetDisplayMode(&This->IDirectDraw4_iface, Width, Height, BPP, RefreshRate,
1014 Flags);
1017 static HRESULT WINAPI IDirectDraw2Impl_SetDisplayMode(IDirectDraw2 *iface, DWORD Width,
1018 DWORD Height, DWORD BPP, DWORD RefreshRate, DWORD Flags)
1020 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
1021 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1022 return IDirectDraw3_SetDisplayMode(&This->IDirectDraw4_iface, Width, Height, BPP, RefreshRate,
1023 Flags);
1026 static HRESULT WINAPI IDirectDrawImpl_SetDisplayMode(IDirectDraw *iface, DWORD Width, DWORD Height,
1027 DWORD BPP)
1029 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
1030 TRACE("(%p)->(%u, %u, %u): Thunking to IDirectDraw4\n", This, Width, Height, BPP);
1031 return IDirectDraw3_SetDisplayMode(&This->IDirectDraw4_iface, Width, Height, BPP, 0, 0);
1034 static HRESULT WINAPI IDirectDraw4Impl_WaitForVerticalBlank(IDirectDraw4 *iface, DWORD Flags,
1035 HANDLE h)
1037 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1038 TRACE("(%p)->(0x%08x, %p)\n", This, Flags, h);
1039 return IDirectDraw4_WaitForVerticalBlank(This->parent, Flags, h);
1042 static HRESULT WINAPI IDirectDraw3Impl_WaitForVerticalBlank(IDirectDraw3 *iface, DWORD Flags,
1043 HANDLE h)
1045 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1046 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1047 return IDirectDraw4_WaitForVerticalBlank(&This->IDirectDraw4_iface, Flags, h);
1050 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(IDirectDraw2 *iface, DWORD Flags,
1051 HANDLE h)
1053 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
1054 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1055 return IDirectDraw4_WaitForVerticalBlank(&This->IDirectDraw4_iface, Flags, h);
1058 static HRESULT WINAPI IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw *iface, DWORD Flags,
1059 HANDLE h)
1061 IDirectDrawImpl *This = impl_from_IDirectDraw(iface);
1062 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1063 return IDirectDraw4_WaitForVerticalBlank(&This->IDirectDraw4_iface, Flags, h);
1066 static HRESULT WINAPI IDirectDraw4Impl_GetAvailableVidMem(IDirectDraw4 *iface, DDSCAPS2 *Caps,
1067 DWORD *total, DWORD *free)
1069 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1070 TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
1071 return IDirectDraw4_GetAvailableVidMem(This->parent, Caps, total, free);
1074 static HRESULT WINAPI IDirectDraw3Impl_GetAvailableVidMem(IDirectDraw3 *iface, DDSCAPS *Caps,
1075 DWORD *total, DWORD *free)
1077 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1078 DDSCAPS2 caps2;
1079 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1080 memset(&caps2, 0, sizeof(caps2));
1081 caps2.dwCaps = Caps->dwCaps;
1082 return IDirectDraw4_GetAvailableVidMem(&This->IDirectDraw4_iface, &caps2, total, free);
1085 static HRESULT WINAPI IDirectDraw2Impl_GetAvailableVidMem(IDirectDraw2 *iface, DDSCAPS *Caps,
1086 DWORD *total, DWORD *free)
1088 IDirectDrawImpl *This = impl_from_IDirectDraw2(iface);
1089 DDSCAPS2 caps2;
1090 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1091 memset(&caps2, 0, sizeof(caps2));
1092 caps2.dwCaps = Caps->dwCaps;
1093 return IDirectDraw4_GetAvailableVidMem(&This->IDirectDraw4_iface, &caps2, total, free);
1096 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(IDirectDraw4 *iface, HDC hdc,
1097 IDirectDrawSurface4 **Surface)
1099 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1100 HRESULT hr;
1101 TRACE("(%p)->(%p, %p)\n", This, hdc, Surface);
1102 hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, Surface);
1104 return hr;
1107 static HRESULT WINAPI IDirectDraw3Impl_GetSurfaceFromDC(IDirectDraw3 *iface, HDC hdc,
1108 IDirectDrawSurface **Surface)
1110 IDirectDrawImpl *This = impl_from_IDirectDraw3(iface);
1111 IDirectDrawSurface4 *surf4, *outer;
1112 IDirectDrawSurface *inner;
1113 HRESULT hr;
1114 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, hdc, Surface);
1116 if (!Surface) return E_POINTER;
1118 hr = IDirectDraw4_GetSurfaceFromDC(This->parent, hdc, (IDirectDrawSurface4 **)&inner);
1119 if(FAILED(hr))
1121 *Surface = NULL;
1122 return hr;
1125 hr = IDirectDrawSurface_QueryInterface(inner, &IID_IDirectDrawSurface4, (void **)&surf4);
1126 IDirectDrawSurface_Release(inner);
1127 if (FAILED(hr))
1129 *Surface = NULL;
1130 return hr;
1133 outer = dds_get_outer(surf4);
1134 hr = IDirectDrawSurface4_QueryInterface(outer, &IID_IDirectDrawSurface, (void **)Surface);
1135 IDirectDrawSurface4_Release(surf4);
1136 return hr;
1139 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(IDirectDraw4 *iface)
1141 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1142 TRACE("(%p)\n", This);
1143 return IDirectDraw4_RestoreAllSurfaces(This->parent);
1146 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(IDirectDraw4 *iface)
1148 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1149 TRACE("(%p)\n", This);
1150 return IDirectDraw4_TestCooperativeLevel(This->parent);
1153 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(IDirectDraw4 *iface,
1154 DDDEVICEIDENTIFIER *DDDI, DWORD Flags)
1156 IDirectDrawImpl *This = impl_from_IDirectDraw4(iface);
1157 TRACE("(%p)->(%p,0x%08x)\n", This, DDDI, Flags);
1158 return IDirectDraw4_GetDeviceIdentifier(This->parent, DDDI, Flags);
1161 static const IDirectDrawVtbl IDirectDraw1_Vtbl =
1163 IDirectDrawImpl_QueryInterface,
1164 IDirectDrawImpl_AddRef,
1165 IDirectDrawImpl_Release,
1166 IDirectDrawImpl_Compact,
1167 IDirectDrawImpl_CreateClipper,
1168 IDirectDrawImpl_CreatePalette,
1169 IDirectDrawImpl_CreateSurface,
1170 IDirectDrawImpl_DuplicateSurface,
1171 IDirectDrawImpl_EnumDisplayModes,
1172 IDirectDrawImpl_EnumSurfaces,
1173 IDirectDrawImpl_FlipToGDISurface,
1174 IDirectDrawImpl_GetCaps,
1175 IDirectDrawImpl_GetDisplayMode,
1176 IDirectDrawImpl_GetFourCCCodes,
1177 IDirectDrawImpl_GetGDISurface,
1178 IDirectDrawImpl_GetMonitorFrequency,
1179 IDirectDrawImpl_GetScanLine,
1180 IDirectDrawImpl_GetVerticalBlankStatus,
1181 IDirectDrawImpl_Initialize,
1182 IDirectDrawImpl_RestoreDisplayMode,
1183 IDirectDrawImpl_SetCooperativeLevel,
1184 IDirectDrawImpl_SetDisplayMode,
1185 IDirectDrawImpl_WaitForVerticalBlank,
1188 static const IDirectDraw2Vtbl IDirectDraw2_Vtbl =
1190 IDirectDraw2Impl_QueryInterface,
1191 IDirectDraw2Impl_AddRef,
1192 IDirectDraw2Impl_Release,
1193 IDirectDraw2Impl_Compact,
1194 IDirectDraw2Impl_CreateClipper,
1195 IDirectDraw2Impl_CreatePalette,
1196 IDirectDraw2Impl_CreateSurface,
1197 IDirectDraw2Impl_DuplicateSurface,
1198 IDirectDraw2Impl_EnumDisplayModes,
1199 IDirectDraw2Impl_EnumSurfaces,
1200 IDirectDraw2Impl_FlipToGDISurface,
1201 IDirectDraw2Impl_GetCaps,
1202 IDirectDraw2Impl_GetDisplayMode,
1203 IDirectDraw2Impl_GetFourCCCodes,
1204 IDirectDraw2Impl_GetGDISurface,
1205 IDirectDraw2Impl_GetMonitorFrequency,
1206 IDirectDraw2Impl_GetScanLine,
1207 IDirectDraw2Impl_GetVerticalBlankStatus,
1208 IDirectDraw2Impl_Initialize,
1209 IDirectDraw2Impl_RestoreDisplayMode,
1210 IDirectDraw2Impl_SetCooperativeLevel,
1211 IDirectDraw2Impl_SetDisplayMode,
1212 IDirectDraw2Impl_WaitForVerticalBlank,
1213 IDirectDraw2Impl_GetAvailableVidMem
1216 static const IDirectDraw3Vtbl IDirectDraw3_Vtbl =
1218 IDirectDraw3Impl_QueryInterface,
1219 IDirectDraw3Impl_AddRef,
1220 IDirectDraw3Impl_Release,
1221 IDirectDraw3Impl_Compact,
1222 IDirectDraw3Impl_CreateClipper,
1223 IDirectDraw3Impl_CreatePalette,
1224 IDirectDraw3Impl_CreateSurface,
1225 IDirectDraw3Impl_DuplicateSurface,
1226 IDirectDraw3Impl_EnumDisplayModes,
1227 IDirectDraw3Impl_EnumSurfaces,
1228 IDirectDraw3Impl_FlipToGDISurface,
1229 IDirectDraw3Impl_GetCaps,
1230 IDirectDraw3Impl_GetDisplayMode,
1231 IDirectDraw3Impl_GetFourCCCodes,
1232 IDirectDraw3Impl_GetGDISurface,
1233 IDirectDraw3Impl_GetMonitorFrequency,
1234 IDirectDraw3Impl_GetScanLine,
1235 IDirectDraw3Impl_GetVerticalBlankStatus,
1236 IDirectDraw3Impl_Initialize,
1237 IDirectDraw3Impl_RestoreDisplayMode,
1238 IDirectDraw3Impl_SetCooperativeLevel,
1239 IDirectDraw3Impl_SetDisplayMode,
1240 IDirectDraw3Impl_WaitForVerticalBlank,
1241 IDirectDraw3Impl_GetAvailableVidMem,
1242 IDirectDraw3Impl_GetSurfaceFromDC,
1245 static const IDirectDraw4Vtbl IDirectDraw4_Vtbl =
1247 IDirectDraw4Impl_QueryInterface,
1248 IDirectDraw4Impl_AddRef,
1249 IDirectDraw4Impl_Release,
1250 IDirectDraw4Impl_Compact,
1251 IDirectDraw4Impl_CreateClipper,
1252 IDirectDraw4Impl_CreatePalette,
1253 IDirectDraw4Impl_CreateSurface,
1254 IDirectDraw4Impl_DuplicateSurface,
1255 IDirectDraw4Impl_EnumDisplayModes,
1256 IDirectDraw4Impl_EnumSurfaces,
1257 IDirectDraw4Impl_FlipToGDISurface,
1258 IDirectDraw4Impl_GetCaps,
1259 IDirectDraw4Impl_GetDisplayMode,
1260 IDirectDraw4Impl_GetFourCCCodes,
1261 IDirectDraw4Impl_GetGDISurface,
1262 IDirectDraw4Impl_GetMonitorFrequency,
1263 IDirectDraw4Impl_GetScanLine,
1264 IDirectDraw4Impl_GetVerticalBlankStatus,
1265 IDirectDraw4Impl_Initialize,
1266 IDirectDraw4Impl_RestoreDisplayMode,
1267 IDirectDraw4Impl_SetCooperativeLevel,
1268 IDirectDraw4Impl_SetDisplayMode,
1269 IDirectDraw4Impl_WaitForVerticalBlank,
1270 IDirectDraw4Impl_GetAvailableVidMem,
1271 IDirectDraw4Impl_GetSurfaceFromDC,
1272 IDirectDraw4Impl_RestoreAllSurfaces,
1273 IDirectDraw4Impl_TestCooperativeLevel,
1274 IDirectDraw4Impl_GetDeviceIdentifier
1277 /*******************************************************************************
1278 * IDirectDrawFactoryImpl_CreateDirectDraw
1279 *******************************************************************************/
1280 HRESULT WINAPI
1281 IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface,
1282 GUID * pGUID,
1283 HWND hWnd,
1284 DWORD dwCoopLevelFlags,
1285 DWORD dwReserved,
1286 IUnknown *pUnkOuter,
1287 IDirectDraw **ppDirectDraw)
1289 HRESULT hr;
1290 IDirectDrawImpl *object = NULL;
1291 IDirectDraw *parent = NULL;
1293 TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p,%p)\n", iface, debugstr_guid(pGUID), hWnd, dwCoopLevelFlags,
1294 dwReserved, pUnkOuter, ppDirectDraw);
1296 if(pUnkOuter)
1298 FIXME("Implement aggregation in ddrawex's IDirectDraw interface\n");
1301 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1302 if(!object)
1304 ERR("Out of memory\n");
1305 hr = E_OUTOFMEMORY;
1306 goto err;
1308 object->ref = 1;
1309 object->IDirectDraw_iface.lpVtbl = &IDirectDraw1_Vtbl;
1310 object->IDirectDraw2_iface.lpVtbl = &IDirectDraw2_Vtbl;
1311 object->IDirectDraw3_iface.lpVtbl = &IDirectDraw3_Vtbl;
1312 object->IDirectDraw4_iface.lpVtbl = &IDirectDraw4_Vtbl;
1314 hr = DirectDrawCreate(pGUID, &parent, NULL);
1315 if (FAILED(hr)) goto err;
1317 hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **) &object->parent);
1318 if(FAILED(hr)) goto err;
1320 hr = IDirectDraw_SetCooperativeLevel(&object->IDirectDraw_iface, hWnd, dwCoopLevelFlags);
1321 if (FAILED(hr)) goto err;
1323 *ppDirectDraw = &object->IDirectDraw_iface;
1324 IDirectDraw_Release(parent);
1325 return DD_OK;
1327 err:
1328 if(object && object->parent) IDirectDraw4_Release(object->parent);
1329 if(parent) IDirectDraw_Release(parent);
1330 HeapFree(GetProcessHeap(), 0, object);
1331 *ppDirectDraw = NULL;
1332 return hr;
1335 IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
1337 IDirectDrawImpl *This = impl_from_IDirectDraw4(outer);
1339 if (outer->lpVtbl != &IDirectDraw4_Vtbl) return NULL;
1340 return This->parent;