push c6fcfc519a04d046be60ec60e33d075a2146cc03
[wine/hacks.git] / dlls / ddrawex / ddraw.c
blobb581529944ff6f503f5d233b54acc05285ad8fa7
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
18 #include "wine/debug.h"
20 #define COBJMACROS
22 #include "winbase.h"
23 #include "wingdi.h"
25 #include "ddraw.h"
26 #include "d3d.h"
28 #include "ddrawex_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);
32 /******************************************************************************
33 * Helper functions for COM management
34 ******************************************************************************/
35 static IDirectDrawImpl *impl_from_dd1(IDirectDraw *iface)
37 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw_Vtbl));
39 static IDirectDraw *dd1_from_impl(IDirectDrawImpl *This)
41 return (IDirectDraw *) &This->IDirectDraw_Vtbl;
44 static IDirectDrawImpl *impl_from_dd2(IDirectDraw2 *iface)
46 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw2_Vtbl));
48 static IDirectDraw2 *dd2_from_impl(IDirectDrawImpl *This)
50 return (IDirectDraw2 *) &This->IDirectDraw2_Vtbl;
53 static IDirectDrawImpl *impl_from_dd3(IDirectDraw3 *iface)
55 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw3_Vtbl));
57 static IDirectDraw3 *dd3_from_impl(IDirectDrawImpl *This)
59 return (IDirectDraw3 *) &This->IDirectDraw3_Vtbl;
62 static IDirectDrawImpl *impl_from_dd4(IDirectDraw4 *iface)
64 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw4_Vtbl));
66 static IDirectDraw4 *dd4_from_impl(IDirectDrawImpl *This)
68 return (IDirectDraw4 *) &This->IDirectDraw4_Vtbl;
71 /******************************************************************************
72 * IDirectDraw4 -> ddraw.dll wrappers
73 ******************************************************************************/
74 static HRESULT WINAPI
75 IDirectDraw4Impl_QueryInterface(IDirectDraw4 *iface,
76 REFIID refiid,
77 void **obj)
79 IDirectDrawImpl *This = impl_from_dd4(iface);
81 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
82 *obj = NULL;
84 if(!refiid)
86 return DDERR_INVALIDPARAMS;
89 if (IsEqualGUID( &IID_IDirectDraw7, refiid ) )
91 WARN("IDirectDraw7 not allowed in ddrawex.dll\n");
92 return E_NOINTERFACE;
94 else if ( IsEqualGUID( &IID_IUnknown, refiid ) ||
95 IsEqualGUID( &IID_IDirectDraw4, refiid ) )
97 *obj = dd4_from_impl(This);
98 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
99 IDirectDraw4_AddRef((IDirectDraw4 *) *obj);
101 else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) )
103 *obj = dd3_from_impl(This);
104 TRACE("(%p) Returning IDirectDraw3 interface at %p\n", This, *obj);
105 IDirectDraw3_AddRef((IDirectDraw3 *) *obj);
107 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
109 *obj = dd2_from_impl(This);
110 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
111 IDirectDraw2_AddRef((IDirectDraw2 *) *obj);
113 else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
115 *obj = dd1_from_impl(This);
116 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
117 IDirectDraw_AddRef((IDirectDraw *) *obj);
119 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
120 IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
121 IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
122 IsEqualGUID( &IID_IDirect3D7 , refiid ) )
124 WARN("Direct3D not allowed in ddrawex.dll\n");
125 return E_NOINTERFACE;
127 /* Unknown interface */
128 else
130 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
131 return E_NOINTERFACE;
133 TRACE("Returning S_OK\n");
134 return S_OK;
137 static HRESULT WINAPI
138 IDirectDraw3Impl_QueryInterface(IDirectDraw3 *iface,
139 REFIID refiid,
140 void **obj)
142 IDirectDrawImpl *This = impl_from_dd3(iface);
143 TRACE("Thunking to IDirectDraw4\n");
144 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
147 static HRESULT WINAPI
148 IDirectDraw2Impl_QueryInterface(IDirectDraw2 *iface,
149 REFIID refiid,
150 void **obj)
152 IDirectDrawImpl *This = impl_from_dd2(iface);
153 TRACE("Thunking to IDirectDraw4\n");
154 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
157 static HRESULT WINAPI
158 IDirectDrawImpl_QueryInterface(IDirectDraw *iface,
159 REFIID refiid,
160 void **obj)
162 IDirectDrawImpl *This = impl_from_dd1(iface);
163 TRACE("Thunking to IDirectDraw4\n");
164 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
167 static ULONG WINAPI
168 IDirectDraw4Impl_AddRef(IDirectDraw4 *iface)
170 IDirectDrawImpl *This = impl_from_dd4(iface);
171 ULONG ref = InterlockedIncrement(&This->ref);
173 TRACE("(%p) : incrementing refcount from %u.\n", This, ref - 1);
175 return ref;
178 static ULONG WINAPI
179 IDirectDraw3Impl_AddRef(IDirectDraw3 *iface)
181 IDirectDrawImpl *This = impl_from_dd3(iface);
182 TRACE("Thunking to IDirectDraw4\n");
183 return IDirectDraw4_AddRef(dd4_from_impl(This));
186 static ULONG WINAPI
187 IDirectDraw2Impl_AddRef(IDirectDraw2 *iface)
189 IDirectDrawImpl *This = impl_from_dd2(iface);
190 TRACE("Thunking to IDirectDraw4\n");
191 return IDirectDraw4_AddRef(dd4_from_impl(This));
194 static ULONG WINAPI
195 IDirectDrawImpl_AddRef(IDirectDraw *iface)
197 IDirectDrawImpl *This = impl_from_dd1(iface);
198 TRACE("Thunking to IDirectDraw4\n");
199 return IDirectDraw4_AddRef(dd4_from_impl(This));
202 static ULONG WINAPI
203 IDirectDraw4Impl_Release(IDirectDraw4 *iface)
205 IDirectDrawImpl *This = impl_from_dd4(iface);
206 ULONG ref = InterlockedDecrement(&This->ref);
208 TRACE("(%p) : decrementing refcount to %u.\n", This, ref);
210 if(ref == 0)
212 TRACE("Destroying object\n");
213 IDirectDraw4_Release(This->parent);
214 HeapFree(GetProcessHeap(), 0, This);
216 return ref;
219 static ULONG WINAPI
220 IDirectDraw3Impl_Release(IDirectDraw3 *iface)
222 IDirectDrawImpl *This = impl_from_dd3(iface);
223 TRACE("Thunking to IDirectDraw4\n");
224 return IDirectDraw4_Release(dd4_from_impl(This));
227 static ULONG WINAPI
228 IDirectDraw2Impl_Release(IDirectDraw2 *iface)
230 IDirectDrawImpl *This = impl_from_dd2(iface);
231 TRACE("Thunking to IDirectDraw4\n");
232 return IDirectDraw4_Release(dd4_from_impl(This));
235 static ULONG WINAPI
236 IDirectDrawImpl_Release(IDirectDraw *iface)
238 IDirectDrawImpl *This = impl_from_dd1(iface);
239 TRACE("Thunking to IDirectDraw4\n");
240 return IDirectDraw4_Release(dd4_from_impl(This));
243 static HRESULT WINAPI
244 IDirectDraw4Impl_Compact(IDirectDraw4 *iface)
246 IDirectDrawImpl *This = impl_from_dd4(iface);
247 TRACE("(%p)\n", This);
249 return IDirectDraw4_Compact(This->parent);
252 static HRESULT WINAPI
253 IDirectDraw3Impl_Compact(IDirectDraw3 *iface)
255 IDirectDrawImpl *This = impl_from_dd3(iface);
256 TRACE("Thunking to IDirectDraw4\n");
257 return IDirectDraw4_Compact(dd4_from_impl(This));
260 static HRESULT WINAPI
261 IDirectDraw2Impl_Compact(IDirectDraw2 *iface)
263 IDirectDrawImpl *This = impl_from_dd2(iface);
264 TRACE("Thunking to IDirectDraw4\n");
265 return IDirectDraw4_Compact(dd4_from_impl(This));
268 static HRESULT WINAPI
269 IDirectDrawImpl_Compact(IDirectDraw *iface)
271 IDirectDrawImpl *This = impl_from_dd1(iface);
272 TRACE("Thunking to IDirectDraw4\n");
273 return IDirectDraw4_Compact(dd4_from_impl(This));
276 static HRESULT WINAPI
277 IDirectDraw4Impl_CreateClipper(IDirectDraw4 *iface,
278 DWORD Flags,
279 IDirectDrawClipper **clipper,
280 IUnknown *UnkOuter)
282 IDirectDrawImpl *This = impl_from_dd4(iface);
283 TRACE("(%p)->(0x%08x, %p, %p)\n", This, Flags, clipper, UnkOuter);
285 if(UnkOuter != NULL)
287 /* This may require a wrapper interface for clippers too which handles this */
288 FIXME("Test and implement Aggregation for ddrawex clippers\n");
291 return IDirectDraw4_CreateClipper(This->parent, Flags, clipper, UnkOuter);
294 static HRESULT WINAPI
295 IDirectDraw3Impl_CreateClipper(IDirectDraw3 *iface,
296 DWORD Flags,
297 IDirectDrawClipper **clipper,
298 IUnknown *UnkOuter)
300 IDirectDrawImpl *This = impl_from_dd3(iface);
301 TRACE("Thunking to IDirectDraw4\n");
302 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
305 static HRESULT WINAPI
306 IDirectDraw2Impl_CreateClipper(IDirectDraw2 *iface,
307 DWORD Flags,
308 IDirectDrawClipper **clipper,
309 IUnknown *UnkOuter)
311 IDirectDrawImpl *This = impl_from_dd2(iface);
312 TRACE("Thunking to IDirectDraw4\n");
313 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
316 static HRESULT WINAPI
317 IDirectDrawImpl_CreateClipper(IDirectDraw *iface,
318 DWORD Flags,
319 IDirectDrawClipper **clipper,
320 IUnknown *UnkOuter)
322 IDirectDrawImpl *This = impl_from_dd1(iface);
323 TRACE("Thunking to IDirectDraw4\n");
324 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
327 static HRESULT WINAPI
328 IDirectDraw4Impl_CreatePalette(IDirectDraw4 *iface,
329 DWORD Flags,
330 PALETTEENTRY *ColorTable,
331 IDirectDrawPalette **Palette,
332 IUnknown *UnkOuter)
334 IDirectDrawImpl *This = impl_from_dd4(iface);
335 TRACE("(%p)(0x%08x,%p,%p,%p)\n", This, Flags, ColorTable, Palette, UnkOuter);
337 if(UnkOuter != NULL)
339 /* This may require a wrapper interface for palettes too which handles this */
340 FIXME("Test and implement Aggregation for ddrawex palettes\n");
343 return IDirectDraw4_CreatePalette(This->parent, Flags, ColorTable, Palette, UnkOuter);
346 static HRESULT WINAPI
347 IDirectDraw3Impl_CreatePalette(IDirectDraw3 *iface,
348 DWORD Flags,
349 PALETTEENTRY *ColorTable,
350 IDirectDrawPalette **Palette,
351 IUnknown *UnkOuter)
353 IDirectDrawImpl *This = impl_from_dd3(iface);
354 TRACE("Thunking to IDirectDraw4\n");
355 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
358 static HRESULT WINAPI
359 IDirectDraw2Impl_CreatePalette(IDirectDraw2 *iface,
360 DWORD Flags,
361 PALETTEENTRY *ColorTable,
362 IDirectDrawPalette **Palette,
363 IUnknown *UnkOuter)
365 IDirectDrawImpl *This = impl_from_dd2(iface);
366 TRACE("Thunking to IDirectDraw4\n");
367 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
370 static HRESULT WINAPI
371 IDirectDrawImpl_CreatePalette(IDirectDraw *iface,
372 DWORD Flags,
373 PALETTEENTRY *ColorTable,
374 IDirectDrawPalette **Palette,
375 IUnknown *UnkOuter)
377 IDirectDrawImpl *This = impl_from_dd1(iface);
378 TRACE("Thunking to IDirectDraw4\n");
379 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
382 static HRESULT WINAPI
383 IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface,
384 DDSURFACEDESC2 *DDSD,
385 IDirectDrawSurface4 **Surf,
386 IUnknown *UnkOuter)
388 IDirectDrawImpl *This = impl_from_dd4(iface);
389 HRESULT hr;
390 const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
391 BOOL permanent_dc;
392 TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter);
394 if(UnkOuter != NULL)
396 /* Handle this in this dll. Don't forward the UnkOuter to ddraw.dll */
397 FIXME("Implement aggregation for ddrawex surfaces\n");
400 /* plain ddraw.dll refuses to create a surface that has both VIDMEM and SYSMEM flags
401 * set. In ddrawex this succeeds, and the GetDC() call changes the behavior. The DC
402 * is permanently valid, and the surface can be locked between GetDC() and ReleaseDC()
403 * calls. GetDC() can be called more than once too
405 if((DDSD->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags)
407 permanent_dc = TRUE;
408 DDSD->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
409 DDSD->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
411 else
413 permanent_dc = FALSE;
416 hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter);
417 *Surf = dds_get_outer(*Surf);
418 if(permanent_dc) prepare_permanent_dc(*Surf);
419 return hr;
422 void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
424 memset(out, 0, sizeof(*out));
425 out->dwSize = sizeof(*out);
426 out->dwFlags = in->dwFlags;
427 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
428 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
429 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->ddpfPixelFormat;
430 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
431 if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch;
432 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
433 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwMipMapCount = in->dwZBufferBitDepth; /* same union */
434 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
435 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
436 out->lpSurface = in->lpSurface;
437 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay;
438 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
439 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
440 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
441 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->dwMipMapCount = in->dwMipMapCount;
442 if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate;
443 if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->dwLinearSize;
444 /* Does not exist in DDSURFACEDESC:
445 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
449 void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
451 memset(out, 0, sizeof(*out));
452 out->dwSize = sizeof(*out);
453 out->dwFlags = in->dwFlags;
454 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
455 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
456 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->ddpfPixelFormat;
457 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
458 if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch;
459 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
460 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwZBufferBitDepth = in->dwMipMapCount; /* same union */
461 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
462 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
463 out->lpSurface = in->lpSurface;
464 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay;
465 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
466 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
467 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
468 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->dwMipMapCount = in->dwMipMapCount;
469 if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate;
470 if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->dwLinearSize;
471 /* Does not exist in DDSURFACEDESC:
472 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
474 if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n");
475 if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n");
476 if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n");
477 out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE);
480 static HRESULT WINAPI
481 IDirectDraw3Impl_CreateSurface(IDirectDraw3 *iface,
482 DDSURFACEDESC *DDSD,
483 IDirectDrawSurface **Surf,
484 IUnknown *UnkOuter)
486 IDirectDrawImpl *This = impl_from_dd3(iface);
487 DDSURFACEDESC2 ddsd2;
488 IDirectDrawSurface4 *surf4 = NULL;
489 HRESULT hr;
490 TRACE("Thunking to IDirectDraw4\n");
492 DDSD_to_DDSD2(DDSD, &ddsd2);
494 hr = IDirectDraw4_CreateSurface(dd4_from_impl(This), &ddsd2, &surf4, UnkOuter);
495 if(FAILED(hr))
497 *Surf = NULL;
498 return hr;
501 TRACE("Got surface %p\n", surf4);
502 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf);
503 IDirectDrawSurface4_Release(surf4);
504 return hr;
507 static HRESULT WINAPI
508 IDirectDraw2Impl_CreateSurface(IDirectDraw2 *iface,
509 DDSURFACEDESC *DDSD,
510 IDirectDrawSurface **Surf,
511 IUnknown *UnkOuter)
513 IDirectDrawImpl *This = impl_from_dd2(iface);
514 TRACE("Thunking to IDirectDraw3\n");
515 return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter);
518 static HRESULT WINAPI
519 IDirectDrawImpl_CreateSurface(IDirectDraw *iface,
520 DDSURFACEDESC *DDSD,
521 IDirectDrawSurface **Surf,
522 IUnknown *UnkOuter)
524 IDirectDrawImpl *This = impl_from_dd1(iface);
525 TRACE("Thunking to IDirectDraw3\n");
526 return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter);
529 static HRESULT WINAPI
530 IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface,
531 IDirectDrawSurface4 *src,
532 IDirectDrawSurface4 **dst)
534 IDirectDrawImpl *This = impl_from_dd4(iface);
535 FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst);
537 return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(src), dst);
540 static HRESULT WINAPI
541 IDirectDraw3Impl_DuplicateSurface(IDirectDraw3 *iface,
542 IDirectDrawSurface *src,
543 IDirectDrawSurface **dst)
545 IDirectDrawImpl *This = impl_from_dd3(iface);
546 IDirectDrawSurface4 *src_4;
547 IDirectDrawSurface4 *dst_4;
548 HRESULT hr;
550 TRACE("Thunking to IDirectDraw4\n");
551 IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **) &src_4);
552 hr = IDirectDraw4_DuplicateSurface(dd4_from_impl(This), src_4, &dst_4);
553 IDirectDrawSurface4_Release(src_4);
555 if(FAILED(hr))
557 *dst = NULL;
558 return hr;
560 IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **) dst);
561 IDirectDrawSurface4_Release(dst_4);
562 return hr;
565 static HRESULT WINAPI
566 IDirectDraw2Impl_DuplicateSurface(IDirectDraw2 *iface,
567 IDirectDrawSurface *src,
568 IDirectDrawSurface **dst)
570 IDirectDrawImpl *This = impl_from_dd2(iface);
571 TRACE("Thunking to IDirectDraw3\n");
572 return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst);
575 static HRESULT WINAPI
576 IDirectDrawImpl_DuplicateSurface(IDirectDraw *iface,
577 IDirectDrawSurface *src,
578 IDirectDrawSurface **dst)
580 IDirectDrawImpl *This = impl_from_dd1(iface);
581 TRACE("Thunking to IDirectDraw3\n");
582 return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst);
585 static HRESULT WINAPI
586 IDirectDraw4Impl_EnumDisplayModes(IDirectDraw4 *iface,
587 DWORD Flags,
588 DDSURFACEDESC2 *DDSD,
589 void *Context,
590 LPDDENUMMODESCALLBACK2 cb)
592 IDirectDrawImpl *This = impl_from_dd4(iface);
593 TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, cb);
595 return IDirectDraw4_EnumDisplayModes(This->parent, Flags, DDSD, Context, cb);
598 struct enummodes_ctx
600 LPDDENUMMODESCALLBACK orig_cb;
601 void *orig_ctx;
604 static HRESULT WINAPI
605 enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx)
607 struct enummodes_ctx *ctx = vctx;
608 DDSURFACEDESC ddsd;
610 DDSD2_to_DDSD(ddsd2, &ddsd);
611 return ctx->orig_cb(&ddsd, ctx->orig_ctx);
614 static HRESULT WINAPI
615 IDirectDraw3Impl_EnumDisplayModes(IDirectDraw3 *iface,
616 DWORD Flags,
617 DDSURFACEDESC *DDSD,
618 void *Context,
619 LPDDENUMMODESCALLBACK cb)
621 IDirectDrawImpl *This = impl_from_dd3(iface);
622 DDSURFACEDESC2 ddsd2;
623 struct enummodes_ctx ctx;
624 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, cb);
626 DDSD_to_DDSD2(DDSD, &ddsd2);
627 ctx.orig_cb = cb;
628 ctx.orig_ctx = Context;
629 return IDirectDraw4_EnumDisplayModes(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_modes_cb2);
632 static HRESULT WINAPI
633 IDirectDraw2Impl_EnumDisplayModes(IDirectDraw2 *iface,
634 DWORD Flags,
635 DDSURFACEDESC *DDSD,
636 void *Context,
637 LPDDENUMMODESCALLBACK cb)
639 IDirectDrawImpl *This = impl_from_dd2(iface);
640 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
641 return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb);
644 static HRESULT WINAPI
645 IDirectDrawImpl_EnumDisplayModes(IDirectDraw *iface,
646 DWORD Flags,
647 DDSURFACEDESC *DDSD,
648 void *Context,
649 LPDDENUMMODESCALLBACK cb)
651 IDirectDrawImpl *This = impl_from_dd1(iface);
652 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
653 return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb);
656 struct enumsurfaces4_ctx
658 LPDDENUMSURFACESCALLBACK2 orig_cb;
659 void *orig_ctx;
662 static HRESULT WINAPI
663 enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
665 struct enumsurfaces4_ctx *ctx = vctx;
666 IDirectDrawSurface4 *outer = dds_get_outer(surf4);
667 IDirectDrawSurface4_AddRef(outer);
668 IDirectDrawSurface4_Release(surf4);
669 TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4);
670 return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx);
673 static HRESULT WINAPI
674 IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface,
675 DWORD Flags,
676 DDSURFACEDESC2 *DDSD,
677 void *Context,
678 LPDDENUMSURFACESCALLBACK2 Callback)
680 IDirectDrawImpl *This = impl_from_dd4(iface);
681 struct enumsurfaces4_ctx *ctx;
682 TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback);
684 ctx->orig_cb = Callback;
685 ctx->orig_ctx = Context;
686 return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, &ctx, enum_surfaces_wrapper);
689 struct enumsurfaces_ctx
691 LPDDENUMSURFACESCALLBACK orig_cb;
692 void *orig_ctx;
695 static HRESULT WINAPI
696 enum_surfaces_cb2(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
698 struct enumsurfaces_ctx *ctx = vctx;
699 IDirectDrawSurface *surf1;
700 DDSURFACEDESC ddsd;
702 /* Keep the reference, it goes to the application */
703 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) &surf1);
704 /* Release the reference this function got */
705 IDirectDrawSurface4_Release(surf4);
707 DDSD2_to_DDSD(ddsd2, &ddsd);
708 return ctx->orig_cb(surf1, &ddsd, ctx->orig_ctx);
711 static HRESULT WINAPI
712 IDirectDraw3Impl_EnumSurfaces(IDirectDraw3 *iface,
713 DWORD Flags,
714 DDSURFACEDESC *DDSD,
715 void *Context,
716 LPDDENUMSURFACESCALLBACK Callback)
718 IDirectDrawImpl *This = impl_from_dd3(iface);
719 DDSURFACEDESC2 ddsd2;
720 struct enumsurfaces_ctx ctx;
721 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, Callback);
723 DDSD_to_DDSD2(DDSD, &ddsd2);
724 ctx.orig_cb = Callback;
725 ctx.orig_ctx = Context;
726 return IDirectDraw4_EnumSurfaces(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_surfaces_cb2);
729 static HRESULT WINAPI
730 IDirectDraw2Impl_EnumSurfaces(IDirectDraw2 *iface,
731 DWORD Flags,
732 DDSURFACEDESC *DDSD,
733 void *Context,
734 LPDDENUMSURFACESCALLBACK Callback)
736 IDirectDrawImpl *This = impl_from_dd2(iface);
737 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
738 return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback);
741 static HRESULT WINAPI
742 IDirectDrawImpl_EnumSurfaces(IDirectDraw *iface,
743 DWORD Flags,
744 DDSURFACEDESC *DDSD,
745 void *Context,
746 LPDDENUMSURFACESCALLBACK Callback)
748 IDirectDrawImpl *This = impl_from_dd1(iface);
749 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
750 return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback);
753 static HRESULT WINAPI
754 IDirectDraw4Impl_FlipToGDISurface(IDirectDraw4 *iface)
756 IDirectDrawImpl *This = impl_from_dd4(iface);
757 TRACE("(%p)\n", This);
759 return IDirectDraw4_FlipToGDISurface(This->parent);
762 static HRESULT WINAPI
763 IDirectDraw3Impl_FlipToGDISurface(IDirectDraw3 *iface)
765 IDirectDrawImpl *This = impl_from_dd3(iface);
766 TRACE("(%p). Thunking to IDirectDraw4\n", This);
767 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
770 static HRESULT WINAPI
771 IDirectDraw2Impl_FlipToGDISurface(IDirectDraw2 *iface)
773 IDirectDrawImpl *This = impl_from_dd2(iface);
774 TRACE("(%p). Thunking to IDirectDraw4\n", This);
775 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
778 static HRESULT WINAPI
779 IDirectDrawImpl_FlipToGDISurface(IDirectDraw *iface)
781 IDirectDrawImpl *This = impl_from_dd1(iface);
782 TRACE("(%p). Thunking to IDirectDraw4\n", This);
783 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
786 static HRESULT WINAPI
787 IDirectDraw4Impl_GetCaps(IDirectDraw4 *iface,
788 DDCAPS *DriverCaps,
789 DDCAPS *HELCaps)
791 IDirectDrawImpl *This = impl_from_dd4(iface);
792 TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps);
793 return IDirectDraw4_GetCaps(This->parent, DriverCaps, HELCaps);
796 static HRESULT WINAPI
797 IDirectDraw3Impl_GetCaps(IDirectDraw3 *iface,
798 DDCAPS *DriverCaps,
799 DDCAPS *HELCaps)
801 IDirectDrawImpl *This = impl_from_dd3(iface);
802 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
803 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
806 static HRESULT WINAPI
807 IDirectDraw2Impl_GetCaps(IDirectDraw2 *iface,
808 DDCAPS *DriverCaps,
809 DDCAPS *HELCaps)
811 IDirectDrawImpl *This = impl_from_dd2(iface);
812 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
813 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
816 static HRESULT WINAPI
817 IDirectDrawImpl_GetCaps(IDirectDraw *iface,
818 DDCAPS *DriverCaps,
819 DDCAPS *HELCaps)
821 IDirectDrawImpl *This = impl_from_dd1(iface);
822 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
823 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
826 static HRESULT WINAPI
827 IDirectDraw4Impl_GetDisplayMode(IDirectDraw4 *iface,
828 DDSURFACEDESC2 *DDSD)
830 IDirectDrawImpl *This = impl_from_dd4(iface);
831 TRACE("(%p)->(%p)\n", This, DDSD);
832 return IDirectDraw4_GetDisplayMode(This->parent, DDSD);
835 static HRESULT WINAPI
836 IDirectDraw3Impl_GetDisplayMode(IDirectDraw3 *iface,
837 DDSURFACEDESC *DDSD)
839 IDirectDrawImpl *This = impl_from_dd3(iface);
840 DDSURFACEDESC2 ddsd2;
841 HRESULT hr;
843 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, DDSD);
844 hr = IDirectDraw4_GetDisplayMode(dd4_from_impl(This), &ddsd2);
845 DDSD2_to_DDSD(&ddsd2, DDSD);
846 return hr;
849 static HRESULT WINAPI
850 IDirectDraw2Impl_GetDisplayMode(IDirectDraw2 *iface,
851 DDSURFACEDESC *DDSD)
853 IDirectDrawImpl *This = impl_from_dd2(iface);
854 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
855 return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD);
858 static HRESULT WINAPI
859 IDirectDrawImpl_GetDisplayMode(IDirectDraw *iface,
860 DDSURFACEDESC *DDSD)
862 IDirectDrawImpl *This = impl_from_dd1(iface);
863 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
864 return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD);
867 static HRESULT WINAPI
868 IDirectDraw4Impl_GetFourCCCodes(IDirectDraw4 *iface,
869 DWORD *NumCodes,
870 DWORD *Codes)
872 IDirectDrawImpl *This = impl_from_dd4(iface);
873 TRACE("(%p)->(%p, %p):\n", This, NumCodes, Codes);
874 return IDirectDraw4_GetFourCCCodes(This->parent, NumCodes, Codes);
877 static HRESULT WINAPI
878 IDirectDraw3Impl_GetFourCCCodes(IDirectDraw3 *iface,
879 DWORD *NumCodes,
880 DWORD *Codes)
882 IDirectDrawImpl *This = impl_from_dd3(iface);
883 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
884 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
887 static HRESULT WINAPI
888 IDirectDraw2Impl_GetFourCCCodes(IDirectDraw2 *iface,
889 DWORD *NumCodes,
890 DWORD *Codes)
892 IDirectDrawImpl *This = impl_from_dd2(iface);
893 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
894 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
897 static HRESULT WINAPI
898 IDirectDrawImpl_GetFourCCCodes(IDirectDraw *iface,
899 DWORD *NumCodes,
900 DWORD *Codes)
902 IDirectDrawImpl *This = impl_from_dd1(iface);
903 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
904 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
907 static HRESULT WINAPI
908 IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface,
909 IDirectDrawSurface4 **GDISurface)
911 IDirectDrawImpl *This = impl_from_dd4(iface);
912 IDirectDrawSurface4 *inner = NULL;
913 HRESULT hr;
914 TRACE("(%p)->(%p)\n", This, GDISurface);
916 hr = IDirectDraw4_GetGDISurface(This->parent, &inner);
917 if(SUCCEEDED(hr))
919 *GDISurface = dds_get_outer(inner);
920 IDirectDrawSurface4_AddRef(*GDISurface);
921 IDirectDrawSurface4_Release(inner);
923 else
925 *GDISurface = NULL;
927 return hr;
930 static HRESULT WINAPI
931 IDirectDraw3Impl_GetGDISurface(IDirectDraw3 *iface,
932 IDirectDrawSurface **GDISurface)
934 IDirectDrawImpl *This = impl_from_dd3(iface);
935 IDirectDrawSurface4 *surf4;
936 HRESULT hr;
937 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, GDISurface);
939 hr = IDirectDraw4_GetGDISurface(dd4_from_impl(This), &surf4);
940 if(FAILED(hr)) {
941 *GDISurface = NULL;
942 return hr;
945 /* Release the reference we got from the DDraw4 call, and pass a reference to the caller */
946 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) GDISurface);
947 IDirectDrawSurface4_Release(surf4);
948 return hr;
951 static HRESULT WINAPI
952 IDirectDraw2Impl_GetGDISurface(IDirectDraw2 *iface,
953 IDirectDrawSurface **GDISurface)
955 IDirectDrawImpl *This = impl_from_dd2(iface);
956 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
957 return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface);
960 static HRESULT WINAPI
961 IDirectDrawImpl_GetGDISurface(IDirectDraw *iface,
962 IDirectDrawSurface **GDISurface)
964 IDirectDrawImpl *This = impl_from_dd1(iface);
965 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
966 return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface);
969 static HRESULT WINAPI
970 IDirectDraw4Impl_GetMonitorFrequency(IDirectDraw4 *iface,
971 DWORD *Freq)
973 IDirectDrawImpl *This = impl_from_dd4(iface);
974 TRACE("(%p)->(%p)\n", This, Freq);
975 return IDirectDraw4_GetMonitorFrequency(This->parent, Freq);
978 static HRESULT WINAPI
979 IDirectDraw3Impl_GetMonitorFrequency(IDirectDraw3 *iface,
980 DWORD *Freq)
982 IDirectDrawImpl *This = impl_from_dd3(iface);
983 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
984 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
987 static HRESULT WINAPI
988 IDirectDraw2Impl_GetMonitorFrequency(IDirectDraw2 *iface,
989 DWORD *Freq)
991 IDirectDrawImpl *This = impl_from_dd2(iface);
992 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
993 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
996 static HRESULT WINAPI
997 IDirectDrawImpl_GetMonitorFrequency(IDirectDraw *iface,
998 DWORD *Freq)
1000 IDirectDrawImpl *This = impl_from_dd1(iface);
1001 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
1002 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
1005 static HRESULT WINAPI
1006 IDirectDraw4Impl_GetScanLine(IDirectDraw4 *iface,
1007 DWORD *Scanline)
1009 IDirectDrawImpl *This = impl_from_dd4(iface);
1010 TRACE("(%p)->(%p)\n", This, Scanline);
1011 return IDirectDraw4_GetScanLine(This->parent, Scanline);
1014 static HRESULT WINAPI
1015 IDirectDraw3Impl_GetScanLine(IDirectDraw3 *iface,
1016 DWORD *Scanline)
1018 IDirectDrawImpl *This = impl_from_dd3(iface);
1019 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
1020 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
1023 static HRESULT WINAPI
1024 IDirectDraw2Impl_GetScanLine(IDirectDraw2 *iface,
1025 DWORD *Scanline)
1027 IDirectDrawImpl *This = impl_from_dd2(iface);
1028 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
1029 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
1032 static HRESULT WINAPI
1033 IDirectDrawImpl_GetScanLine(IDirectDraw *iface,
1034 DWORD *Scanline)
1036 IDirectDrawImpl *This = impl_from_dd1(iface);
1037 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
1038 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
1041 static HRESULT WINAPI
1042 IDirectDraw4Impl_GetVerticalBlankStatus(IDirectDraw4 *iface,
1043 BOOL *status)
1045 IDirectDrawImpl *This = impl_from_dd4(iface);
1046 TRACE("(%p)->(%p)\n", This, status);
1047 return IDirectDraw4_GetVerticalBlankStatus(This->parent, status);
1050 static HRESULT WINAPI
1051 IDirectDraw3Impl_GetVerticalBlankStatus(IDirectDraw3 *iface,
1052 BOOL *status)
1054 IDirectDrawImpl *This = impl_from_dd3(iface);
1055 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
1056 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
1059 static HRESULT WINAPI
1060 IDirectDraw2Impl_GetVerticalBlankStatus(IDirectDraw2 *iface,
1061 BOOL *status)
1063 IDirectDrawImpl *This = impl_from_dd2(iface);
1064 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
1065 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
1068 static HRESULT WINAPI
1069 IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw *iface,
1070 BOOL *status)
1072 IDirectDrawImpl *This = impl_from_dd1(iface);
1073 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
1074 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
1077 static HRESULT WINAPI
1078 IDirectDraw4Impl_Initialize(IDirectDraw4 *iface,
1079 GUID *Guid)
1081 IDirectDrawImpl *This = impl_from_dd4(iface);
1082 TRACE("(%p)->(%s)\n", This, debugstr_guid(Guid));
1083 return IDirectDraw4_Initialize(This->parent, Guid);
1086 static HRESULT WINAPI
1087 IDirectDraw3Impl_Initialize(IDirectDraw3 *iface,
1088 GUID *Guid)
1090 IDirectDrawImpl *This = impl_from_dd3(iface);
1091 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
1092 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
1095 static HRESULT WINAPI
1096 IDirectDraw2Impl_Initialize(IDirectDraw2 *iface,
1097 GUID *Guid)
1099 IDirectDrawImpl *This = impl_from_dd2(iface);
1100 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
1101 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
1104 static HRESULT WINAPI
1105 IDirectDrawImpl_Initialize(IDirectDraw *iface,
1106 GUID *Guid)
1108 IDirectDrawImpl *This = impl_from_dd1(iface);
1109 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
1110 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
1113 static HRESULT WINAPI
1114 IDirectDraw4Impl_RestoreDisplayMode(IDirectDraw4 *iface)
1116 IDirectDrawImpl *This = impl_from_dd4(iface);
1117 TRACE("(%p)\n", This);
1118 return IDirectDraw4_RestoreDisplayMode(This->parent);
1121 static HRESULT WINAPI
1122 IDirectDraw3Impl_RestoreDisplayMode(IDirectDraw3 *iface)
1124 IDirectDrawImpl *This = impl_from_dd3(iface);
1125 TRACE("(%p): Thunking to IDirectDraw4\n", This);
1126 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
1129 static HRESULT WINAPI
1130 IDirectDraw2Impl_RestoreDisplayMode(IDirectDraw2 *iface)
1132 IDirectDrawImpl *This = impl_from_dd2(iface);
1133 TRACE("(%p): Thunking to IDirectDraw4\n", This);
1134 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
1137 static HRESULT WINAPI
1138 IDirectDrawImpl_RestoreDisplayMode(IDirectDraw *iface)
1140 IDirectDrawImpl *This = impl_from_dd1(iface);
1141 TRACE("(%p): Thunking to IDirectDraw4\n", This);
1142 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
1145 static HRESULT WINAPI
1146 IDirectDraw4Impl_SetCooperativeLevel(IDirectDraw4 *iface,
1147 HWND hwnd,
1148 DWORD cooplevel)
1150 IDirectDrawImpl *This = impl_from_dd4(iface);
1151 TRACE("(%p)->(%p, 0x%08x)\n", This, hwnd, cooplevel);
1152 return IDirectDraw4_SetCooperativeLevel(This->parent, hwnd, cooplevel);
1155 static HRESULT WINAPI
1156 IDirectDraw3Impl_SetCooperativeLevel(IDirectDraw3 *iface,
1157 HWND hwnd,
1158 DWORD cooplevel)
1160 IDirectDrawImpl *This = impl_from_dd3(iface);
1161 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
1162 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
1165 static HRESULT WINAPI
1166 IDirectDraw2Impl_SetCooperativeLevel(IDirectDraw2 *iface,
1167 HWND hwnd,
1168 DWORD cooplevel)
1170 IDirectDrawImpl *This = impl_from_dd2(iface);
1171 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
1172 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
1175 static HRESULT WINAPI
1176 IDirectDrawImpl_SetCooperativeLevel(IDirectDraw *iface,
1177 HWND hwnd,
1178 DWORD cooplevel)
1180 IDirectDrawImpl *This = impl_from_dd1(iface);
1181 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
1182 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
1185 static HRESULT WINAPI
1186 IDirectDraw4Impl_SetDisplayMode(IDirectDraw4 *iface,
1187 DWORD Width,
1188 DWORD Height,
1189 DWORD BPP,
1190 DWORD RefreshRate,
1191 DWORD Flags)
1193 IDirectDrawImpl *This = impl_from_dd4(iface);
1194 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x)\n", This, Width, Height, BPP, RefreshRate, Flags);
1195 return IDirectDraw4_SetDisplayMode(This->parent, Width, Height, BPP, RefreshRate, Flags);
1198 static HRESULT WINAPI
1199 IDirectDraw3Impl_SetDisplayMode(IDirectDraw3 *iface,
1200 DWORD Width,
1201 DWORD Height,
1202 DWORD BPP,
1203 DWORD RefreshRate,
1204 DWORD Flags)
1206 IDirectDrawImpl *This = impl_from_dd3(iface);
1207 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1208 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
1211 static HRESULT WINAPI
1212 IDirectDraw2Impl_SetDisplayMode(IDirectDraw2 *iface,
1213 DWORD Width,
1214 DWORD Height,
1215 DWORD BPP,
1216 DWORD RefreshRate,
1217 DWORD Flags)
1219 IDirectDrawImpl *This = impl_from_dd2(iface);
1220 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1221 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
1224 static HRESULT WINAPI
1225 IDirectDrawImpl_SetDisplayMode(IDirectDraw *iface,
1226 DWORD Width,
1227 DWORD Height,
1228 DWORD BPP)
1230 IDirectDrawImpl *This = impl_from_dd1(iface);
1231 TRACE("(%p)->(%u, %u, %u): Thunking to IDirectDraw4\n", This, Width, Height, BPP);
1232 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, 0, 0);
1235 static HRESULT WINAPI
1236 IDirectDraw4Impl_WaitForVerticalBlank(IDirectDraw4 *iface,
1237 DWORD Flags,
1238 HANDLE h)
1240 IDirectDrawImpl *This = impl_from_dd4(iface);
1241 TRACE("(%p)->(0x%08x, %p)\n", This, Flags, h);
1242 return IDirectDraw4_WaitForVerticalBlank(This->parent, Flags, h);
1245 static HRESULT WINAPI
1246 IDirectDraw3Impl_WaitForVerticalBlank(IDirectDraw3 *iface,
1247 DWORD Flags,
1248 HANDLE h)
1250 IDirectDrawImpl *This = impl_from_dd3(iface);
1251 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1252 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1255 static HRESULT WINAPI
1256 IDirectDraw2Impl_WaitForVerticalBlank(IDirectDraw2 *iface,
1257 DWORD Flags,
1258 HANDLE h)
1260 IDirectDrawImpl *This = impl_from_dd2(iface);
1261 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1262 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1265 static HRESULT WINAPI
1266 IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw *iface,
1267 DWORD Flags,
1268 HANDLE h)
1270 IDirectDrawImpl *This = impl_from_dd1(iface);
1271 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1272 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1275 static HRESULT WINAPI
1276 IDirectDraw4Impl_GetAvailableVidMem(IDirectDraw4 *iface,
1277 DDSCAPS2 *Caps,
1278 DWORD *total,
1279 DWORD *free)
1281 IDirectDrawImpl *This = impl_from_dd4(iface);
1282 TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
1283 return IDirectDraw4_GetAvailableVidMem(This->parent, Caps, total, free);
1286 static HRESULT WINAPI
1287 IDirectDraw3Impl_GetAvailableVidMem(IDirectDraw3 *iface,
1288 DDSCAPS *Caps,
1289 DWORD *total,
1290 DWORD *free)
1292 IDirectDrawImpl *This = impl_from_dd3(iface);
1293 DDSCAPS2 caps2;
1294 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1295 memset(&caps2, 0, sizeof(caps2));
1296 caps2.dwCaps = Caps->dwCaps;
1297 return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
1300 static HRESULT WINAPI
1301 IDirectDraw2Impl_GetAvailableVidMem(IDirectDraw2 *iface,
1302 DDSCAPS *Caps,
1303 DWORD *total,
1304 DWORD *free)
1306 IDirectDrawImpl *This = impl_from_dd2(iface);
1307 DDSCAPS2 caps2;
1308 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1309 memset(&caps2, 0, sizeof(caps2));
1310 caps2.dwCaps = Caps->dwCaps;
1311 return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
1314 static HRESULT WINAPI
1315 IDirectDraw4Impl_GetSurfaceFromDC(IDirectDraw4 *iface,
1316 HDC hdc,
1317 IDirectDrawSurface4 **Surface)
1319 IDirectDrawImpl *This = impl_from_dd4(iface);
1320 IDirectDrawSurface4 *inner;
1321 HRESULT hr;
1322 TRACE("(%p)->(%p, %p)\n", This, hdc, Surface);
1323 hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, &inner);
1324 if(SUCCEEDED(hr))
1326 *Surface = dds_get_outer(inner);
1327 IDirectDrawSurface4_AddRef(*Surface);
1328 IDirectDrawSurface4_Release(inner);
1330 else
1332 *Surface = NULL;
1335 return hr;
1338 static HRESULT WINAPI
1339 IDirectDraw3Impl_GetSurfaceFromDC(IDirectDraw3 *iface,
1340 HDC hdc,
1341 IDirectDrawSurface **Surface)
1343 IDirectDrawImpl *This = impl_from_dd3(iface);
1344 IDirectDrawSurface4 *surf4;
1345 HRESULT hr;
1346 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, hdc, Surface);
1348 hr = IDirectDraw4_GetSurfaceFromDC(dd4_from_impl(This), hdc, &surf4);
1349 if(FAILED(hr))
1351 *Surface = NULL;
1352 return hr;
1354 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surface);
1355 IDirectDrawSurface4_Release(surf4);
1356 return hr;
1359 static HRESULT WINAPI
1360 IDirectDraw4Impl_RestoreAllSurfaces(IDirectDraw4 *iface)
1362 IDirectDrawImpl *This = impl_from_dd4(iface);
1363 TRACE("(%p)\n", This);
1364 return IDirectDraw4_RestoreAllSurfaces(This->parent);
1367 static HRESULT WINAPI
1368 IDirectDraw4Impl_TestCooperativeLevel(IDirectDraw4 *iface)
1370 IDirectDrawImpl *This = impl_from_dd4(iface);
1371 TRACE("(%p)\n", This);
1372 return IDirectDraw4_TestCooperativeLevel(This->parent);
1375 static HRESULT WINAPI
1376 IDirectDraw4Impl_GetDeviceIdentifier(IDirectDraw4 *iface,
1377 DDDEVICEIDENTIFIER *DDDI,
1378 DWORD Flags)
1380 IDirectDrawImpl *This = impl_from_dd4(iface);
1381 TRACE("(%p)->(%p,0x%08x)\n", This, DDDI, Flags);
1382 return IDirectDraw4_GetDeviceIdentifier(This->parent, DDDI, Flags);
1385 static const IDirectDrawVtbl IDirectDraw1_Vtbl =
1387 IDirectDrawImpl_QueryInterface,
1388 IDirectDrawImpl_AddRef,
1389 IDirectDrawImpl_Release,
1390 IDirectDrawImpl_Compact,
1391 IDirectDrawImpl_CreateClipper,
1392 IDirectDrawImpl_CreatePalette,
1393 IDirectDrawImpl_CreateSurface,
1394 IDirectDrawImpl_DuplicateSurface,
1395 IDirectDrawImpl_EnumDisplayModes,
1396 IDirectDrawImpl_EnumSurfaces,
1397 IDirectDrawImpl_FlipToGDISurface,
1398 IDirectDrawImpl_GetCaps,
1399 IDirectDrawImpl_GetDisplayMode,
1400 IDirectDrawImpl_GetFourCCCodes,
1401 IDirectDrawImpl_GetGDISurface,
1402 IDirectDrawImpl_GetMonitorFrequency,
1403 IDirectDrawImpl_GetScanLine,
1404 IDirectDrawImpl_GetVerticalBlankStatus,
1405 IDirectDrawImpl_Initialize,
1406 IDirectDrawImpl_RestoreDisplayMode,
1407 IDirectDrawImpl_SetCooperativeLevel,
1408 IDirectDrawImpl_SetDisplayMode,
1409 IDirectDrawImpl_WaitForVerticalBlank,
1412 static const IDirectDraw2Vtbl IDirectDraw2_Vtbl =
1414 IDirectDraw2Impl_QueryInterface,
1415 IDirectDraw2Impl_AddRef,
1416 IDirectDraw2Impl_Release,
1417 IDirectDraw2Impl_Compact,
1418 IDirectDraw2Impl_CreateClipper,
1419 IDirectDraw2Impl_CreatePalette,
1420 IDirectDraw2Impl_CreateSurface,
1421 IDirectDraw2Impl_DuplicateSurface,
1422 IDirectDraw2Impl_EnumDisplayModes,
1423 IDirectDraw2Impl_EnumSurfaces,
1424 IDirectDraw2Impl_FlipToGDISurface,
1425 IDirectDraw2Impl_GetCaps,
1426 IDirectDraw2Impl_GetDisplayMode,
1427 IDirectDraw2Impl_GetFourCCCodes,
1428 IDirectDraw2Impl_GetGDISurface,
1429 IDirectDraw2Impl_GetMonitorFrequency,
1430 IDirectDraw2Impl_GetScanLine,
1431 IDirectDraw2Impl_GetVerticalBlankStatus,
1432 IDirectDraw2Impl_Initialize,
1433 IDirectDraw2Impl_RestoreDisplayMode,
1434 IDirectDraw2Impl_SetCooperativeLevel,
1435 IDirectDraw2Impl_SetDisplayMode,
1436 IDirectDraw2Impl_WaitForVerticalBlank,
1437 IDirectDraw2Impl_GetAvailableVidMem
1440 static const IDirectDraw3Vtbl IDirectDraw3_Vtbl =
1442 IDirectDraw3Impl_QueryInterface,
1443 IDirectDraw3Impl_AddRef,
1444 IDirectDraw3Impl_Release,
1445 IDirectDraw3Impl_Compact,
1446 IDirectDraw3Impl_CreateClipper,
1447 IDirectDraw3Impl_CreatePalette,
1448 IDirectDraw3Impl_CreateSurface,
1449 IDirectDraw3Impl_DuplicateSurface,
1450 IDirectDraw3Impl_EnumDisplayModes,
1451 IDirectDraw3Impl_EnumSurfaces,
1452 IDirectDraw3Impl_FlipToGDISurface,
1453 IDirectDraw3Impl_GetCaps,
1454 IDirectDraw3Impl_GetDisplayMode,
1455 IDirectDraw3Impl_GetFourCCCodes,
1456 IDirectDraw3Impl_GetGDISurface,
1457 IDirectDraw3Impl_GetMonitorFrequency,
1458 IDirectDraw3Impl_GetScanLine,
1459 IDirectDraw3Impl_GetVerticalBlankStatus,
1460 IDirectDraw3Impl_Initialize,
1461 IDirectDraw3Impl_RestoreDisplayMode,
1462 IDirectDraw3Impl_SetCooperativeLevel,
1463 IDirectDraw3Impl_SetDisplayMode,
1464 IDirectDraw3Impl_WaitForVerticalBlank,
1465 IDirectDraw3Impl_GetAvailableVidMem,
1466 IDirectDraw3Impl_GetSurfaceFromDC,
1469 static const IDirectDraw4Vtbl IDirectDraw4_Vtbl =
1471 IDirectDraw4Impl_QueryInterface,
1472 IDirectDraw4Impl_AddRef,
1473 IDirectDraw4Impl_Release,
1474 IDirectDraw4Impl_Compact,
1475 IDirectDraw4Impl_CreateClipper,
1476 IDirectDraw4Impl_CreatePalette,
1477 IDirectDraw4Impl_CreateSurface,
1478 IDirectDraw4Impl_DuplicateSurface,
1479 IDirectDraw4Impl_EnumDisplayModes,
1480 IDirectDraw4Impl_EnumSurfaces,
1481 IDirectDraw4Impl_FlipToGDISurface,
1482 IDirectDraw4Impl_GetCaps,
1483 IDirectDraw4Impl_GetDisplayMode,
1484 IDirectDraw4Impl_GetFourCCCodes,
1485 IDirectDraw4Impl_GetGDISurface,
1486 IDirectDraw4Impl_GetMonitorFrequency,
1487 IDirectDraw4Impl_GetScanLine,
1488 IDirectDraw4Impl_GetVerticalBlankStatus,
1489 IDirectDraw4Impl_Initialize,
1490 IDirectDraw4Impl_RestoreDisplayMode,
1491 IDirectDraw4Impl_SetCooperativeLevel,
1492 IDirectDraw4Impl_SetDisplayMode,
1493 IDirectDraw4Impl_WaitForVerticalBlank,
1494 IDirectDraw4Impl_GetAvailableVidMem,
1495 IDirectDraw4Impl_GetSurfaceFromDC,
1496 IDirectDraw4Impl_RestoreAllSurfaces,
1497 IDirectDraw4Impl_TestCooperativeLevel,
1498 IDirectDraw4Impl_GetDeviceIdentifier
1501 /*******************************************************************************
1502 * IDirectDrawFactoryImpl_CreateDirectDraw
1503 *******************************************************************************/
1504 HRESULT WINAPI
1505 IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface,
1506 GUID * pGUID,
1507 HWND hWnd,
1508 DWORD dwCoopLevelFlags,
1509 DWORD dwReserved,
1510 IUnknown *pUnkOuter,
1511 IDirectDraw **ppDirectDraw)
1513 HRESULT hr;
1514 IDirectDrawImpl *object = NULL;
1515 IDirectDraw *parent = NULL;
1517 TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p,%p)\n", iface, debugstr_guid(pGUID), hWnd, dwCoopLevelFlags,
1518 dwReserved, pUnkOuter, ppDirectDraw);
1520 if(pUnkOuter)
1522 FIXME("Implement aggregation in ddrawex's IDirectDraw interface\n");
1525 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1526 if(!object)
1528 ERR("Out of memory\n");
1529 hr = E_OUTOFMEMORY;
1530 goto err;
1532 object->ref = 1;
1533 object->IDirectDraw_Vtbl = &IDirectDraw1_Vtbl;
1534 object->IDirectDraw2_Vtbl = &IDirectDraw2_Vtbl;
1535 object->IDirectDraw3_Vtbl = &IDirectDraw3_Vtbl;
1536 object->IDirectDraw4_Vtbl = &IDirectDraw4_Vtbl;
1538 hr = DirectDrawCreate(pGUID, &parent, NULL);
1539 if (FAILED(hr)) goto err;
1541 hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **) &object->parent);
1542 if(FAILED(hr)) goto err;
1544 hr = IDirectDraw_SetCooperativeLevel(dd1_from_impl(object), hWnd, dwCoopLevelFlags);
1545 if (FAILED(hr)) goto err;
1547 *ppDirectDraw = dd1_from_impl(object);
1548 IDirectDraw_Release(parent);
1549 return DD_OK;
1551 err:
1552 if(object && object->parent) IDirectDraw4_Release(object->parent);
1553 if(parent) IDirectDraw_Release(parent);
1554 HeapFree(GetProcessHeap(), 0, object);
1555 *ppDirectDraw = NULL;
1556 return hr;
1559 IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
1561 IDirectDrawImpl *This = impl_from_dd4(outer);
1562 return This->parent;