wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / ddrawex / ddraw.c
blob2bb7e90fa4286749aaec808e3dc19a658edd1dc7
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 static struct ddrawex *impl_from_IDirectDraw(IDirectDraw *iface)
37 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw_iface);
40 static struct ddrawex *impl_from_IDirectDraw2(IDirectDraw2 *iface)
42 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw2_iface);
45 static struct ddrawex *impl_from_IDirectDraw3(IDirectDraw3 *iface)
47 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw3_iface);
50 static struct ddrawex *impl_from_IDirectDraw4(IDirectDraw4 *iface)
52 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw4_iface);
55 static HRESULT WINAPI ddrawex4_QueryInterface(IDirectDraw4 *iface, REFIID riid, void **out)
57 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
59 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
61 if (!riid)
63 *out = NULL;
64 return DDERR_INVALIDPARAMS;
67 if (IsEqualGUID(&IID_IDirectDraw4, riid)
68 || IsEqualGUID(&IID_IUnknown, riid))
70 *out = &ddrawex->IDirectDraw4_iface;
72 else if (IsEqualGUID(&IID_IDirectDraw3, riid))
74 *out = &ddrawex->IDirectDraw3_iface;
76 else if (IsEqualGUID(&IID_IDirectDraw2, riid))
78 *out = &ddrawex->IDirectDraw2_iface;
80 else if (IsEqualGUID(&IID_IDirectDraw, riid))
82 *out = &ddrawex->IDirectDraw_iface;
84 else
86 *out = NULL;
87 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
88 return E_NOINTERFACE;
91 IUnknown_AddRef((IUnknown *)*out);
92 return S_OK;
95 static HRESULT WINAPI ddrawex3_QueryInterface(IDirectDraw3 *iface, REFIID riid, void **out)
97 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
99 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
101 return ddrawex4_QueryInterface(&ddrawex->IDirectDraw4_iface, riid, out);
104 static HRESULT WINAPI ddrawex2_QueryInterface(IDirectDraw2 *iface, REFIID riid, void **out)
106 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
108 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
110 return ddrawex4_QueryInterface(&ddrawex->IDirectDraw4_iface, riid, out);
113 static HRESULT WINAPI ddrawex1_QueryInterface(IDirectDraw *iface, REFIID riid, void **out)
115 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
117 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
119 return ddrawex4_QueryInterface(&ddrawex->IDirectDraw4_iface, riid, out);
122 static ULONG WINAPI ddrawex4_AddRef(IDirectDraw4 *iface)
124 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
125 ULONG refcount = InterlockedIncrement(&ddrawex->ref);
127 TRACE("%p increasing refcount to %u.\n", iface, refcount);
129 return refcount;
132 static ULONG WINAPI ddrawex3_AddRef(IDirectDraw3 *iface)
134 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
136 TRACE("iface %p.\n", iface);
138 return ddrawex4_AddRef(&ddrawex->IDirectDraw4_iface);
141 static ULONG WINAPI ddrawex2_AddRef(IDirectDraw2 *iface)
143 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
145 TRACE("iface %p.\n", iface);
147 return ddrawex4_AddRef(&ddrawex->IDirectDraw4_iface);
150 static ULONG WINAPI ddrawex1_AddRef(IDirectDraw *iface)
152 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
154 TRACE("iface %p.\n", iface);
156 return ddrawex4_AddRef(&ddrawex->IDirectDraw4_iface);
159 static ULONG WINAPI ddrawex4_Release(IDirectDraw4 *iface)
161 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
162 ULONG refcount = InterlockedDecrement(&ddrawex->ref);
164 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
166 if (!refcount)
168 IDirectDraw4_Release(ddrawex->parent);
169 heap_free(ddrawex);
172 return refcount;
175 static ULONG WINAPI ddrawex3_Release(IDirectDraw3 *iface)
177 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
179 TRACE("iface %p.\n", iface);
181 return ddrawex4_Release(&ddrawex->IDirectDraw4_iface);
184 static ULONG WINAPI ddrawex2_Release(IDirectDraw2 *iface)
186 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
188 TRACE("iface %p.\n", iface);
190 return ddrawex4_Release(&ddrawex->IDirectDraw4_iface);
193 static ULONG WINAPI ddrawex1_Release(IDirectDraw *iface)
195 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
197 TRACE("iface %p.\n", iface);
199 return ddrawex4_Release(&ddrawex->IDirectDraw4_iface);
202 static HRESULT WINAPI ddrawex4_Compact(IDirectDraw4 *iface)
204 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
206 TRACE("iface %p.\n", iface);
208 return IDirectDraw4_Compact(ddrawex->parent);
211 static HRESULT WINAPI ddrawex3_Compact(IDirectDraw3 *iface)
213 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
215 TRACE("iface %p.\n", iface);
217 return ddrawex4_Compact(&ddrawex->IDirectDraw4_iface);
220 static HRESULT WINAPI ddrawex2_Compact(IDirectDraw2 *iface)
222 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
224 TRACE("iface %p.\n", iface);
226 return ddrawex4_Compact(&ddrawex->IDirectDraw4_iface);
229 static HRESULT WINAPI ddrawex1_Compact(IDirectDraw *iface)
231 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
233 TRACE("iface %p.\n", iface);
235 return ddrawex4_Compact(&ddrawex->IDirectDraw4_iface);
238 static HRESULT WINAPI ddrawex4_CreateClipper(IDirectDraw4 *iface, DWORD flags,
239 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
241 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
243 TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
244 iface, flags, clipper, outer_unknown);
246 /* This may require a wrapper interface for clippers too which handles this. */
247 if (outer_unknown)
248 FIXME("Test and implement aggregation for ddrawex clippers.\n");
250 return IDirectDraw4_CreateClipper(ddrawex->parent, flags, clipper, outer_unknown);
253 static HRESULT WINAPI ddrawex3_CreateClipper(IDirectDraw3 *iface, DWORD flags,
254 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
256 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
258 TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
259 iface, flags, clipper, outer_unknown);
261 return ddrawex4_CreateClipper(&ddrawex->IDirectDraw4_iface, flags, clipper, outer_unknown);
264 static HRESULT WINAPI ddrawex2_CreateClipper(IDirectDraw2 *iface, DWORD flags,
265 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
267 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
269 TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
270 iface, flags, clipper, outer_unknown);
272 return ddrawex4_CreateClipper(&ddrawex->IDirectDraw4_iface, flags, clipper, outer_unknown);
275 static HRESULT WINAPI ddrawex1_CreateClipper(IDirectDraw *iface, DWORD flags,
276 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
278 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
280 TRACE("iface %p, flags %#x, clipper %p, outer_unknown %p.\n",
281 iface, flags, clipper, outer_unknown);
283 return ddrawex4_CreateClipper(&ddrawex->IDirectDraw4_iface, flags, clipper, outer_unknown);
286 static HRESULT WINAPI ddrawex4_CreatePalette(IDirectDraw4 *iface, DWORD flags,
287 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
289 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
291 TRACE("iface %p, flags %#x. entries %p, palette %p, outer_unknown %p.\n",
292 iface, flags, entries, palette, outer_unknown);
294 /* This may require a wrapper interface for palettes too which handles this. */
295 if (outer_unknown)
296 FIXME("Test and implement aggregation for ddrawex palettes.\n");
298 return IDirectDraw4_CreatePalette(ddrawex->parent, flags, entries, palette, outer_unknown);
301 static HRESULT WINAPI ddrawex3_CreatePalette(IDirectDraw3 *iface, DWORD flags,
302 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
304 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
306 TRACE("iface %p, flags %#x. entries %p, palette %p, outer_unknown %p.\n",
307 iface, flags, entries, palette, outer_unknown);
309 return ddrawex4_CreatePalette(&ddrawex->IDirectDraw4_iface, flags, entries, palette, outer_unknown);
312 static HRESULT WINAPI ddrawex2_CreatePalette(IDirectDraw2 *iface, DWORD flags,
313 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
315 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
317 TRACE("iface %p, flags %#x. entries %p, palette %p, outer_unknown %p.\n",
318 iface, flags, entries, palette, outer_unknown);
320 return ddrawex4_CreatePalette(&ddrawex->IDirectDraw4_iface, flags, entries, palette, outer_unknown);
323 static HRESULT WINAPI ddrawex1_CreatePalette(IDirectDraw *iface, DWORD flags,
324 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
326 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
328 TRACE("iface %p, flags %#x. entries %p, palette %p, outer_unknown %p.\n",
329 iface, flags, entries, palette, outer_unknown);
331 return ddrawex4_CreatePalette(&ddrawex->IDirectDraw4_iface, flags, entries, palette, outer_unknown);
334 static HRESULT WINAPI ddrawex4_CreateSurface(IDirectDraw4 *iface, DDSURFACEDESC2 *desc,
335 IDirectDrawSurface4 **surface, IUnknown *outer_unknown)
337 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
338 HRESULT hr;
339 const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
340 BOOL permanent_dc;
341 IDirectDrawSurface4 *inner_surface;
343 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
344 iface, desc, surface, outer_unknown);
346 /* Handle this in this dll. Don't forward the outer_unknown to ddraw.dll. */
347 if (outer_unknown)
348 FIXME("Implement aggregation for ddrawex surfaces.\n");
350 /* Plain ddraw.dll refuses to create a surface that has both VIDMEM and
351 * SYSMEM flags set. In ddrawex this succeeds, and the GetDC() call
352 * changes the behavior. The DC is permanently valid, and the surface can
353 * be locked between GetDC() and ReleaseDC() calls. GetDC() can be called
354 * more than once too. */
355 if ((desc->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags)
357 permanent_dc = TRUE;
358 desc->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
359 desc->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
361 else
363 permanent_dc = FALSE;
366 hr = IDirectDraw4_CreateSurface(ddrawex->parent, desc, &inner_surface, outer_unknown);
367 if (FAILED(hr))
369 *surface = NULL;
370 return hr;
373 *surface = dds_get_outer(inner_surface);
374 /* The wrapper created by dds_get_outer holds a reference to its inner surface. */
375 IDirectDrawSurface4_Release(inner_surface);
377 if (permanent_dc)
378 prepare_permanent_dc(*surface);
380 return hr;
383 void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
385 memset(out, 0, sizeof(*out));
386 out->dwSize = sizeof(*out);
387 out->dwFlags = in->dwFlags;
388 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
389 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
390 if(in->dwFlags & DDSD_PIXELFORMAT) out->u4.ddpfPixelFormat = in->ddpfPixelFormat;
391 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
392 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
393 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->u5.dwBackBufferCount = in->dwBackBufferCount;
394 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwMipMapCount = in->u2.dwZBufferBitDepth; /* same union */
395 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
396 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
397 out->lpSurface = in->lpSurface;
398 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->u3.ddckCKDestOverlay = in->ddckCKDestOverlay;
399 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
400 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
401 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
402 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
403 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
404 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
405 /* Does not exist in DDSURFACEDESC:
406 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
410 void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
412 memset(out, 0, sizeof(*out));
413 out->dwSize = sizeof(*out);
414 out->dwFlags = in->dwFlags;
415 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
416 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
417 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->u4.ddpfPixelFormat;
418 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
419 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
420 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->u5.dwBackBufferCount;
421 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwZBufferBitDepth = in->u2.dwMipMapCount; /* same union */
422 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
423 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
424 out->lpSurface = in->lpSurface;
425 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->u3.ddckCKDestOverlay;
426 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
427 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
428 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
429 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
430 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
431 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
432 /* Does not exist in DDSURFACEDESC:
433 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
435 if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n");
436 if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n");
437 if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n");
438 out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE);
441 static HRESULT WINAPI ddrawex3_CreateSurface(IDirectDraw3 *iface, DDSURFACEDESC *desc,
442 IDirectDrawSurface **surface, IUnknown *outer_unknown)
444 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
445 DDSURFACEDESC2 ddsd2;
446 IDirectDrawSurface4 *surf4 = NULL;
447 HRESULT hr;
449 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
450 iface, desc, surface, outer_unknown);
452 DDSD_to_DDSD2(desc, &ddsd2);
453 if (FAILED(hr = ddrawex4_CreateSurface(&ddrawex->IDirectDraw4_iface, &ddsd2, &surf4, outer_unknown)))
455 *surface = NULL;
456 return hr;
459 TRACE("Got surface %p\n", surf4);
460 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)surface);
461 IDirectDrawSurface4_Release(surf4);
462 return hr;
465 static HRESULT WINAPI ddrawex2_CreateSurface(IDirectDraw2 *iface, DDSURFACEDESC *desc,
466 IDirectDrawSurface **surface, IUnknown *outer_unknown)
468 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
470 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
471 iface, desc, surface, outer_unknown);
473 return ddrawex3_CreateSurface(&ddrawex->IDirectDraw3_iface, desc, surface, outer_unknown);
476 static HRESULT WINAPI ddrawex1_CreateSurface(IDirectDraw *iface, DDSURFACEDESC *desc,
477 IDirectDrawSurface **surface, IUnknown *outer_unknown)
479 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
481 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
482 iface, desc, surface, outer_unknown);
484 return ddrawex3_CreateSurface(&ddrawex->IDirectDraw3_iface, desc, surface, outer_unknown);
487 static HRESULT WINAPI ddrawex4_DuplicateSurface(IDirectDraw4 *iface,
488 IDirectDrawSurface4 *src, IDirectDrawSurface4 **dst)
490 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
491 struct ddrawex_surface *src_impl = unsafe_impl_from_IDirectDrawSurface4(src);
493 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
494 FIXME("Create a wrapper surface.\n");
496 return IDirectDraw4_DuplicateSurface(ddrawex->parent, src_impl ? src_impl->parent : NULL, dst);
499 static HRESULT WINAPI ddrawex3_DuplicateSurface(IDirectDraw3 *iface,
500 IDirectDrawSurface *src, IDirectDrawSurface **dst)
502 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
503 IDirectDrawSurface4 *src_4;
504 IDirectDrawSurface4 *dst_4;
505 HRESULT hr;
507 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
509 IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **)&src_4);
510 hr = ddrawex4_DuplicateSurface(&ddrawex->IDirectDraw4_iface, src_4, &dst_4);
511 IDirectDrawSurface4_Release(src_4);
512 if (FAILED(hr))
514 *dst = NULL;
515 return hr;
518 IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **)dst);
519 IDirectDrawSurface4_Release(dst_4);
521 return hr;
524 static HRESULT WINAPI ddrawex2_DuplicateSurface(IDirectDraw2 *iface,
525 IDirectDrawSurface *src, IDirectDrawSurface **dst)
527 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
529 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
531 return ddrawex3_DuplicateSurface(&ddrawex->IDirectDraw3_iface, src, dst);
534 static HRESULT WINAPI ddrawex1_DuplicateSurface(IDirectDraw *iface,
535 IDirectDrawSurface *src, IDirectDrawSurface **dst)
537 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
539 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
541 return ddrawex3_DuplicateSurface(&ddrawex->IDirectDraw3_iface, src, dst);
544 static HRESULT WINAPI ddrawex4_EnumDisplayModes(IDirectDraw4 *iface, DWORD flags,
545 DDSURFACEDESC2 *desc, void *ctx, LPDDENUMMODESCALLBACK2 cb)
547 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
549 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
551 return IDirectDraw4_EnumDisplayModes(ddrawex->parent, flags, desc, ctx, cb);
554 struct enummodes_ctx
556 LPDDENUMMODESCALLBACK orig_cb;
557 void *orig_ctx;
560 static HRESULT WINAPI
561 enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx)
563 struct enummodes_ctx *ctx = vctx;
564 DDSURFACEDESC ddsd;
566 DDSD2_to_DDSD(ddsd2, &ddsd);
567 return ctx->orig_cb(&ddsd, ctx->orig_ctx);
570 static HRESULT WINAPI ddrawex3_EnumDisplayModes(IDirectDraw3 *iface, DWORD flags,
571 DDSURFACEDESC *desc, void *ctx, LPDDENUMMODESCALLBACK cb)
573 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
574 struct enummodes_ctx cb_ctx;
575 DDSURFACEDESC2 ddsd2;
577 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
579 DDSD_to_DDSD2(desc, &ddsd2);
580 cb_ctx.orig_cb = cb;
581 cb_ctx.orig_ctx = ctx;
582 return ddrawex4_EnumDisplayModes(&ddrawex->IDirectDraw4_iface, flags, &ddsd2, &cb_ctx, enum_modes_cb2);
585 static HRESULT WINAPI ddrawex2_EnumDisplayModes(IDirectDraw2 *iface, DWORD flags,
586 DDSURFACEDESC *desc, void *ctx, LPDDENUMMODESCALLBACK cb)
588 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
590 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
592 return ddrawex3_EnumDisplayModes(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
595 static HRESULT WINAPI ddrawex1_EnumDisplayModes(IDirectDraw *iface, DWORD flags,
596 DDSURFACEDESC *desc, void *ctx, LPDDENUMMODESCALLBACK cb)
598 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
600 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
602 return ddrawex3_EnumDisplayModes(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
605 struct enumsurfaces4_ctx
607 LPDDENUMSURFACESCALLBACK2 orig_cb;
608 void *orig_ctx;
611 static HRESULT WINAPI
612 enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
614 struct enumsurfaces4_ctx *ctx = vctx;
615 IDirectDrawSurface4 *outer = dds_get_outer(surf4);
616 IDirectDrawSurface4_AddRef(outer);
617 IDirectDrawSurface4_Release(surf4);
618 TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4);
619 return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx);
622 static HRESULT WINAPI ddrawex4_EnumSurfaces(IDirectDraw4 *iface, DWORD flags,
623 DDSURFACEDESC2 *desc, void *ctx, LPDDENUMSURFACESCALLBACK2 cb)
625 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
626 struct enumsurfaces4_ctx cb_ctx;
628 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
630 cb_ctx.orig_cb = cb;
631 cb_ctx.orig_ctx = ctx;
632 return IDirectDraw4_EnumSurfaces(ddrawex->parent, flags, desc, &cb_ctx, enum_surfaces_wrapper);
635 struct enumsurfaces_ctx
637 LPDDENUMSURFACESCALLBACK orig_cb;
638 void *orig_ctx;
641 static HRESULT WINAPI
642 enum_surfaces_cb2(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
644 struct enumsurfaces_ctx *ctx = vctx;
645 IDirectDrawSurface *surf1;
646 DDSURFACEDESC ddsd;
648 /* Keep the reference, it goes to the application */
649 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) &surf1);
650 /* Release the reference this function got */
651 IDirectDrawSurface4_Release(surf4);
653 DDSD2_to_DDSD(ddsd2, &ddsd);
654 return ctx->orig_cb(surf1, &ddsd, ctx->orig_ctx);
657 static HRESULT WINAPI ddrawex3_EnumSurfaces(IDirectDraw3 *iface, DWORD flags,
658 DDSURFACEDESC *desc, void *ctx, LPDDENUMSURFACESCALLBACK cb)
660 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
661 DDSURFACEDESC2 ddsd2;
662 struct enumsurfaces_ctx cb_ctx;
664 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
666 DDSD_to_DDSD2(desc, &ddsd2);
667 cb_ctx.orig_cb = cb;
668 cb_ctx.orig_ctx = ctx;
669 return ddrawex4_EnumSurfaces(&ddrawex->IDirectDraw4_iface, flags, &ddsd2, &cb_ctx, enum_surfaces_cb2);
672 static HRESULT WINAPI ddrawex2_EnumSurfaces(IDirectDraw2 *iface, DWORD flags,
673 DDSURFACEDESC *desc, void *ctx, LPDDENUMSURFACESCALLBACK cb)
675 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
677 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
679 return ddrawex3_EnumSurfaces(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
682 static HRESULT WINAPI ddrawex1_EnumSurfaces(IDirectDraw *iface, DWORD flags,
683 DDSURFACEDESC *desc, void *ctx, LPDDENUMSURFACESCALLBACK cb)
685 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
687 TRACE("iface %p, flags %#x, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
689 return ddrawex3_EnumSurfaces(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
692 static HRESULT WINAPI ddrawex4_FlipToGDISurface(IDirectDraw4 *iface)
694 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
696 TRACE("iface %p.\n", iface);
698 return IDirectDraw4_FlipToGDISurface(ddrawex->parent);
701 static HRESULT WINAPI ddrawex3_FlipToGDISurface(IDirectDraw3 *iface)
703 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
705 TRACE("iface %p.\n", iface);
707 return ddrawex4_FlipToGDISurface(&ddrawex->IDirectDraw4_iface);
710 static HRESULT WINAPI ddrawex2_FlipToGDISurface(IDirectDraw2 *iface)
712 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
714 TRACE("iface %p.\n", iface);
716 return ddrawex4_FlipToGDISurface(&ddrawex->IDirectDraw4_iface);
719 static HRESULT WINAPI ddrawex1_FlipToGDISurface(IDirectDraw *iface)
721 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
723 TRACE("iface %p.\n", iface);
725 return ddrawex4_FlipToGDISurface(&ddrawex->IDirectDraw4_iface);
728 static HRESULT WINAPI ddrawex4_GetCaps(IDirectDraw4 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
730 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
732 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
734 return IDirectDraw4_GetCaps(ddrawex->parent, driver_caps, hel_caps);
737 static HRESULT WINAPI ddrawex3_GetCaps(IDirectDraw3 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
739 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
741 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
743 return ddrawex4_GetCaps(&ddrawex->IDirectDraw4_iface, driver_caps, hel_caps);
746 static HRESULT WINAPI ddrawex2_GetCaps(IDirectDraw2 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
748 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
750 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
752 return ddrawex4_GetCaps(&ddrawex->IDirectDraw4_iface, driver_caps, hel_caps);
755 static HRESULT WINAPI ddrawex1_GetCaps(IDirectDraw *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
757 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
759 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
761 return ddrawex4_GetCaps(&ddrawex->IDirectDraw4_iface, driver_caps, hel_caps);
764 static HRESULT WINAPI ddrawex4_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 *desc)
766 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
768 TRACE("iface %p, desc %p.\n", iface, desc);
770 return IDirectDraw4_GetDisplayMode(ddrawex->parent, desc);
773 static HRESULT WINAPI ddrawex3_GetDisplayMode(IDirectDraw3 *iface, DDSURFACEDESC *desc)
775 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
776 DDSURFACEDESC2 ddsd2;
777 HRESULT hr;
779 TRACE("iface %p, desc %p.\n", iface, desc);
781 hr = ddrawex4_GetDisplayMode(&ddrawex->IDirectDraw4_iface, &ddsd2);
782 DDSD2_to_DDSD(&ddsd2, desc);
784 return hr;
787 static HRESULT WINAPI ddrawex2_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC *desc)
789 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
791 TRACE("iface %p, desc %p.\n", iface, desc);
793 return ddrawex3_GetDisplayMode(&ddrawex->IDirectDraw3_iface, desc);
796 static HRESULT WINAPI ddrawex1_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *desc)
798 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
800 TRACE("iface %p, desc %p.\n", iface, desc);
802 return ddrawex3_GetDisplayMode(&ddrawex->IDirectDraw3_iface, desc);
805 static HRESULT WINAPI ddrawex4_GetFourCCCodes(IDirectDraw4 *iface, DWORD *code_count, DWORD *codes)
807 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
809 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
811 return IDirectDraw4_GetFourCCCodes(ddrawex->parent, code_count, codes);
814 static HRESULT WINAPI ddrawex3_GetFourCCCodes(IDirectDraw3 *iface, DWORD *code_count, DWORD *codes)
816 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
818 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
820 return ddrawex4_GetFourCCCodes(&ddrawex->IDirectDraw4_iface, code_count, codes);
823 static HRESULT WINAPI ddrawex2_GetFourCCCodes(IDirectDraw2 *iface, DWORD *code_count, DWORD *codes)
825 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
827 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
829 return ddrawex4_GetFourCCCodes(&ddrawex->IDirectDraw4_iface, code_count, codes);
832 static HRESULT WINAPI ddrawex1_GetFourCCCodes(IDirectDraw *iface, DWORD *code_count, DWORD *codes)
834 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
836 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
838 return ddrawex4_GetFourCCCodes(&ddrawex->IDirectDraw4_iface, code_count, codes);
841 static HRESULT WINAPI ddrawex4_GetGDISurface(IDirectDraw4 *iface, IDirectDrawSurface4 **gdi_surface)
843 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
844 IDirectDrawSurface4 *inner = NULL;
845 HRESULT hr;
847 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
849 if (FAILED(hr = IDirectDraw4_GetGDISurface(ddrawex->parent, &inner)))
851 *gdi_surface = NULL;
852 return hr;
855 *gdi_surface = dds_get_outer(inner);
856 IDirectDrawSurface4_AddRef(*gdi_surface);
857 IDirectDrawSurface4_Release(inner);
858 return hr;
861 static HRESULT WINAPI ddrawex3_GetGDISurface(IDirectDraw3 *iface, IDirectDrawSurface **gdi_surface)
863 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
864 IDirectDrawSurface4 *surf4;
865 HRESULT hr;
867 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
869 if (FAILED(hr = ddrawex4_GetGDISurface(&ddrawex->IDirectDraw4_iface, &surf4)))
871 *gdi_surface = NULL;
872 return hr;
875 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)gdi_surface);
876 IDirectDrawSurface4_Release(surf4);
877 return hr;
880 static HRESULT WINAPI ddrawex2_GetGDISurface(IDirectDraw2 *iface, IDirectDrawSurface **gdi_surface)
882 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
884 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
886 return ddrawex3_GetGDISurface(&ddrawex->IDirectDraw3_iface, gdi_surface);
889 static HRESULT WINAPI ddrawex1_GetGDISurface(IDirectDraw *iface, IDirectDrawSurface **gdi_surface)
891 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
893 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
895 return ddrawex3_GetGDISurface(&ddrawex->IDirectDraw3_iface, gdi_surface);
898 static HRESULT WINAPI ddrawex4_GetMonitorFrequency(IDirectDraw4 *iface, DWORD *frequency)
900 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
902 TRACE("iface %p, frequency %p.\n", iface, frequency);
904 return IDirectDraw4_GetMonitorFrequency(ddrawex->parent, frequency);
907 static HRESULT WINAPI ddrawex3_GetMonitorFrequency(IDirectDraw3 *iface, DWORD *frequency)
909 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
911 TRACE("iface %p, frequency %p.\n", iface, frequency);
913 return ddrawex4_GetMonitorFrequency(&ddrawex->IDirectDraw4_iface, frequency);
916 static HRESULT WINAPI ddrawex2_GetMonitorFrequency(IDirectDraw2 *iface, DWORD *frequency)
918 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
920 TRACE("iface %p, frequency %p.\n", iface, frequency);
922 return ddrawex4_GetMonitorFrequency(&ddrawex->IDirectDraw4_iface, frequency);
925 static HRESULT WINAPI ddrawex1_GetMonitorFrequency(IDirectDraw *iface, DWORD *frequency)
927 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
929 TRACE("iface %p, frequency %p.\n", iface, frequency);
931 return ddrawex4_GetMonitorFrequency(&ddrawex->IDirectDraw4_iface, frequency);
934 static HRESULT WINAPI ddrawex4_GetScanLine(IDirectDraw4 *iface, DWORD *line)
936 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
938 TRACE("iface %p, line %p.\n", iface, line);
940 return IDirectDraw4_GetScanLine(ddrawex->parent, line);
943 static HRESULT WINAPI ddrawex3_GetScanLine(IDirectDraw3 *iface, DWORD *line)
945 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
947 TRACE("iface %p, line %p.\n", iface, line);
949 return ddrawex4_GetScanLine(&ddrawex->IDirectDraw4_iface, line);
952 static HRESULT WINAPI ddrawex2_GetScanLine(IDirectDraw2 *iface, DWORD *line)
954 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
956 TRACE("iface %p, line %p.\n", iface, line);
958 return ddrawex4_GetScanLine(&ddrawex->IDirectDraw4_iface, line);
961 static HRESULT WINAPI ddrawex1_GetScanLine(IDirectDraw *iface, DWORD *line)
963 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
965 TRACE("iface %p, line %p.\n", iface, line);
967 return ddrawex4_GetScanLine(&ddrawex->IDirectDraw4_iface, line);
970 static HRESULT WINAPI ddrawex4_GetVerticalBlankStatus(IDirectDraw4 *iface, BOOL *status)
972 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
974 TRACE("iface %p, status %p.\n", iface, status);
976 return IDirectDraw4_GetVerticalBlankStatus(ddrawex->parent, status);
979 static HRESULT WINAPI ddrawex3_GetVerticalBlankStatus(IDirectDraw3 *iface, BOOL *status)
981 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
983 TRACE("iface %p, status %p.\n", iface, status);
985 return ddrawex4_GetVerticalBlankStatus(&ddrawex->IDirectDraw4_iface, status);
988 static HRESULT WINAPI ddrawex2_GetVerticalBlankStatus(IDirectDraw2 *iface, BOOL *status)
990 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
992 TRACE("iface %p, status %p.\n", iface, status);
994 return ddrawex4_GetVerticalBlankStatus(&ddrawex->IDirectDraw4_iface, status);
997 static HRESULT WINAPI ddrawex1_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *status)
999 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1001 TRACE("iface %p, status %p.\n", iface, status);
1003 return ddrawex4_GetVerticalBlankStatus(&ddrawex->IDirectDraw4_iface, status);
1006 static HRESULT WINAPI ddrawex4_Initialize(IDirectDraw4 *iface, GUID *guid)
1008 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1010 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1012 return IDirectDraw4_Initialize(ddrawex->parent, guid);
1015 static HRESULT WINAPI ddrawex3_Initialize(IDirectDraw3 *iface, GUID *guid)
1017 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1019 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1021 return ddrawex4_Initialize(&ddrawex->IDirectDraw4_iface, guid);
1024 static HRESULT WINAPI ddrawex2_Initialize(IDirectDraw2 *iface, GUID *guid)
1026 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1028 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1030 return ddrawex4_Initialize(&ddrawex->IDirectDraw4_iface, guid);
1033 static HRESULT WINAPI ddrawex1_Initialize(IDirectDraw *iface, GUID *guid)
1035 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1037 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1039 return ddrawex4_Initialize(&ddrawex->IDirectDraw4_iface, guid);
1042 static HRESULT WINAPI ddrawex4_RestoreDisplayMode(IDirectDraw4 *iface)
1044 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1046 TRACE("iface %p.\n", iface);
1048 return IDirectDraw4_RestoreDisplayMode(ddrawex->parent);
1051 static HRESULT WINAPI ddrawex3_RestoreDisplayMode(IDirectDraw3 *iface)
1053 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1055 TRACE("iface %p.\n", iface);
1057 return ddrawex4_RestoreDisplayMode(&ddrawex->IDirectDraw4_iface);
1060 static HRESULT WINAPI ddrawex2_RestoreDisplayMode(IDirectDraw2 *iface)
1062 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1064 TRACE("iface %p.\n", iface);
1066 return ddrawex4_RestoreDisplayMode(&ddrawex->IDirectDraw4_iface);
1069 static HRESULT WINAPI ddrawex1_RestoreDisplayMode(IDirectDraw *iface)
1071 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1073 TRACE("iface %p.\n", iface);
1075 return ddrawex4_RestoreDisplayMode(&ddrawex->IDirectDraw4_iface);
1078 static HRESULT WINAPI ddrawex4_SetCooperativeLevel(IDirectDraw4 *iface, HWND window, DWORD flags)
1080 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1082 TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
1084 return IDirectDraw4_SetCooperativeLevel(ddrawex->parent, window, flags);
1087 static HRESULT WINAPI ddrawex3_SetCooperativeLevel(IDirectDraw3 *iface, HWND window, DWORD flags)
1089 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1091 TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
1093 return ddrawex4_SetCooperativeLevel(&ddrawex->IDirectDraw4_iface, window, flags);
1096 static HRESULT WINAPI ddrawex2_SetCooperativeLevel(IDirectDraw2 *iface, HWND window, DWORD flags)
1098 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1100 TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
1102 return ddrawex4_SetCooperativeLevel(&ddrawex->IDirectDraw4_iface, window, flags);
1105 static HRESULT WINAPI ddrawex1_SetCooperativeLevel(IDirectDraw *iface, HWND window, DWORD flags)
1107 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1109 TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
1111 return ddrawex4_SetCooperativeLevel(&ddrawex->IDirectDraw4_iface, window, flags);
1114 static HRESULT WINAPI ddrawex4_SetDisplayMode(IDirectDraw4 *iface, DWORD width,
1115 DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
1117 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1119 TRACE("iface %p, width %u, height %u, bpp %u, refresh_rate %u, flags %#x.\n",
1120 iface, width, height, bpp, refresh_rate, flags);
1122 return IDirectDraw4_SetDisplayMode(ddrawex->parent, width, height, bpp, refresh_rate, flags);
1125 static HRESULT WINAPI ddrawex3_SetDisplayMode(IDirectDraw3 *iface, DWORD width,
1126 DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
1128 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1130 TRACE("iface %p, width %u, height %u, bpp %u, refresh_rate %u, flags %#x.\n",
1131 iface, width, height, bpp, refresh_rate, flags);
1133 return ddrawex4_SetDisplayMode(&ddrawex->IDirectDraw4_iface, width, height, bpp, refresh_rate, flags);
1136 static HRESULT WINAPI ddrawex2_SetDisplayMode(IDirectDraw2 *iface, DWORD width,
1137 DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
1139 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1141 TRACE("iface %p, width %u, height %u, bpp %u, refresh_rate %u, flags %#x.\n",
1142 iface, width, height, bpp, refresh_rate, flags);
1144 return ddrawex4_SetDisplayMode(&ddrawex->IDirectDraw4_iface, width, height, bpp, refresh_rate, flags);
1147 static HRESULT WINAPI ddrawex1_SetDisplayMode(IDirectDraw *iface, DWORD width,
1148 DWORD height, DWORD bpp)
1150 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1152 TRACE("iface %p, width %u, height %u, bpp %u.\n", iface, width, height, bpp);
1154 return ddrawex4_SetDisplayMode(&ddrawex->IDirectDraw4_iface, width, height, bpp, 0, 0);
1157 static HRESULT WINAPI ddrawex4_WaitForVerticalBlank(IDirectDraw4 *iface, DWORD flags, HANDLE event)
1159 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1161 TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
1163 return IDirectDraw4_WaitForVerticalBlank(ddrawex->parent, flags, event);
1166 static HRESULT WINAPI ddrawex3_WaitForVerticalBlank(IDirectDraw3 *iface, DWORD flags, HANDLE event)
1168 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1170 TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
1172 return ddrawex4_WaitForVerticalBlank(&ddrawex->IDirectDraw4_iface, flags, event);
1175 static HRESULT WINAPI ddrawex2_WaitForVerticalBlank(IDirectDraw2 *iface, DWORD flags, HANDLE event)
1177 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1179 TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
1181 return ddrawex4_WaitForVerticalBlank(&ddrawex->IDirectDraw4_iface, flags, event);
1184 static HRESULT WINAPI ddrawex1_WaitForVerticalBlank(IDirectDraw *iface, DWORD flags, HANDLE event)
1186 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1188 TRACE("iface %p, flags %#x, event %p.\n", iface, flags, event);
1190 return ddrawex4_WaitForVerticalBlank(&ddrawex->IDirectDraw4_iface, flags, event);
1193 static HRESULT WINAPI ddrawex4_GetAvailableVidMem(IDirectDraw4 *iface,
1194 DDSCAPS2 *caps, DWORD *total, DWORD *free)
1196 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1198 TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
1200 return IDirectDraw4_GetAvailableVidMem(ddrawex->parent, caps, total, free);
1203 static HRESULT WINAPI ddrawex3_GetAvailableVidMem(IDirectDraw3 *iface,
1204 DDSCAPS *caps, DWORD *total, DWORD *free)
1206 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1207 DDSCAPS2 caps2;
1209 TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
1211 memset(&caps2, 0, sizeof(caps2));
1212 caps2.dwCaps = caps->dwCaps;
1213 return ddrawex4_GetAvailableVidMem(&ddrawex->IDirectDraw4_iface, &caps2, total, free);
1216 static HRESULT WINAPI ddrawex2_GetAvailableVidMem(IDirectDraw2 *iface,
1217 DDSCAPS *caps, DWORD *total, DWORD *free)
1219 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1220 DDSCAPS2 caps2;
1222 TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
1224 memset(&caps2, 0, sizeof(caps2));
1225 caps2.dwCaps = caps->dwCaps;
1226 return ddrawex4_GetAvailableVidMem(&ddrawex->IDirectDraw4_iface, &caps2, total, free);
1229 static HRESULT WINAPI ddrawex4_GetSurfaceFromDC(IDirectDraw4 *iface,
1230 HDC dc, IDirectDrawSurface4 **surface)
1232 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1234 TRACE("iface %p, dc %p, surface %p.\n", iface, dc, surface);
1236 return IDirectDraw4_GetSurfaceFromDC(ddrawex->parent, dc, surface);
1239 static HRESULT WINAPI ddrawex3_GetSurfaceFromDC(IDirectDraw3 *iface,
1240 HDC dc, IDirectDrawSurface **surface)
1242 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1243 IDirectDrawSurface4 *surf4, *outer;
1244 IDirectDrawSurface *inner;
1245 HRESULT hr;
1247 TRACE("iface %p, dc %p, surface %p.\n", iface, dc, surface);
1249 if (!surface)
1250 return E_POINTER;
1252 if (FAILED(hr = IDirectDraw4_GetSurfaceFromDC(ddrawex->parent, dc, (IDirectDrawSurface4 **)&inner)))
1254 *surface = NULL;
1255 return hr;
1258 hr = IDirectDrawSurface_QueryInterface(inner, &IID_IDirectDrawSurface4, (void **)&surf4);
1259 IDirectDrawSurface_Release(inner);
1260 if (FAILED(hr))
1262 *surface = NULL;
1263 return hr;
1266 outer = dds_get_outer(surf4);
1267 hr = IDirectDrawSurface4_QueryInterface(outer, &IID_IDirectDrawSurface, (void **)surface);
1268 IDirectDrawSurface4_Release(surf4);
1269 return hr;
1272 static HRESULT WINAPI ddrawex4_RestoreAllSurfaces(IDirectDraw4 *iface)
1274 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1276 TRACE("iface %p.\n", iface);
1278 return IDirectDraw4_RestoreAllSurfaces(ddrawex->parent);
1281 static HRESULT WINAPI ddrawex4_TestCooperativeLevel(IDirectDraw4 *iface)
1283 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1285 TRACE("iface %p.\n", iface);
1287 return IDirectDraw4_TestCooperativeLevel(ddrawex->parent);
1290 static HRESULT WINAPI ddrawex4_GetDeviceIdentifier(IDirectDraw4 *iface,
1291 DDDEVICEIDENTIFIER *identifier, DWORD flags)
1293 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1295 TRACE("iface %p, identifier %p, flags %#x.\n", iface, identifier, flags);
1297 return IDirectDraw4_GetDeviceIdentifier(ddrawex->parent, identifier, flags);
1300 static const IDirectDraw4Vtbl ddrawex4_vtbl =
1302 ddrawex4_QueryInterface,
1303 ddrawex4_AddRef,
1304 ddrawex4_Release,
1305 ddrawex4_Compact,
1306 ddrawex4_CreateClipper,
1307 ddrawex4_CreatePalette,
1308 ddrawex4_CreateSurface,
1309 ddrawex4_DuplicateSurface,
1310 ddrawex4_EnumDisplayModes,
1311 ddrawex4_EnumSurfaces,
1312 ddrawex4_FlipToGDISurface,
1313 ddrawex4_GetCaps,
1314 ddrawex4_GetDisplayMode,
1315 ddrawex4_GetFourCCCodes,
1316 ddrawex4_GetGDISurface,
1317 ddrawex4_GetMonitorFrequency,
1318 ddrawex4_GetScanLine,
1319 ddrawex4_GetVerticalBlankStatus,
1320 ddrawex4_Initialize,
1321 ddrawex4_RestoreDisplayMode,
1322 ddrawex4_SetCooperativeLevel,
1323 ddrawex4_SetDisplayMode,
1324 ddrawex4_WaitForVerticalBlank,
1325 ddrawex4_GetAvailableVidMem,
1326 ddrawex4_GetSurfaceFromDC,
1327 ddrawex4_RestoreAllSurfaces,
1328 ddrawex4_TestCooperativeLevel,
1329 ddrawex4_GetDeviceIdentifier,
1332 static const IDirectDraw3Vtbl ddrawex3_vtbl =
1334 ddrawex3_QueryInterface,
1335 ddrawex3_AddRef,
1336 ddrawex3_Release,
1337 ddrawex3_Compact,
1338 ddrawex3_CreateClipper,
1339 ddrawex3_CreatePalette,
1340 ddrawex3_CreateSurface,
1341 ddrawex3_DuplicateSurface,
1342 ddrawex3_EnumDisplayModes,
1343 ddrawex3_EnumSurfaces,
1344 ddrawex3_FlipToGDISurface,
1345 ddrawex3_GetCaps,
1346 ddrawex3_GetDisplayMode,
1347 ddrawex3_GetFourCCCodes,
1348 ddrawex3_GetGDISurface,
1349 ddrawex3_GetMonitorFrequency,
1350 ddrawex3_GetScanLine,
1351 ddrawex3_GetVerticalBlankStatus,
1352 ddrawex3_Initialize,
1353 ddrawex3_RestoreDisplayMode,
1354 ddrawex3_SetCooperativeLevel,
1355 ddrawex3_SetDisplayMode,
1356 ddrawex3_WaitForVerticalBlank,
1357 ddrawex3_GetAvailableVidMem,
1358 ddrawex3_GetSurfaceFromDC,
1361 static const IDirectDraw2Vtbl ddrawex2_vtbl =
1363 ddrawex2_QueryInterface,
1364 ddrawex2_AddRef,
1365 ddrawex2_Release,
1366 ddrawex2_Compact,
1367 ddrawex2_CreateClipper,
1368 ddrawex2_CreatePalette,
1369 ddrawex2_CreateSurface,
1370 ddrawex2_DuplicateSurface,
1371 ddrawex2_EnumDisplayModes,
1372 ddrawex2_EnumSurfaces,
1373 ddrawex2_FlipToGDISurface,
1374 ddrawex2_GetCaps,
1375 ddrawex2_GetDisplayMode,
1376 ddrawex2_GetFourCCCodes,
1377 ddrawex2_GetGDISurface,
1378 ddrawex2_GetMonitorFrequency,
1379 ddrawex2_GetScanLine,
1380 ddrawex2_GetVerticalBlankStatus,
1381 ddrawex2_Initialize,
1382 ddrawex2_RestoreDisplayMode,
1383 ddrawex2_SetCooperativeLevel,
1384 ddrawex2_SetDisplayMode,
1385 ddrawex2_WaitForVerticalBlank,
1386 ddrawex2_GetAvailableVidMem,
1389 static const IDirectDrawVtbl ddrawex1_vtbl =
1391 ddrawex1_QueryInterface,
1392 ddrawex1_AddRef,
1393 ddrawex1_Release,
1394 ddrawex1_Compact,
1395 ddrawex1_CreateClipper,
1396 ddrawex1_CreatePalette,
1397 ddrawex1_CreateSurface,
1398 ddrawex1_DuplicateSurface,
1399 ddrawex1_EnumDisplayModes,
1400 ddrawex1_EnumSurfaces,
1401 ddrawex1_FlipToGDISurface,
1402 ddrawex1_GetCaps,
1403 ddrawex1_GetDisplayMode,
1404 ddrawex1_GetFourCCCodes,
1405 ddrawex1_GetGDISurface,
1406 ddrawex1_GetMonitorFrequency,
1407 ddrawex1_GetScanLine,
1408 ddrawex1_GetVerticalBlankStatus,
1409 ddrawex1_Initialize,
1410 ddrawex1_RestoreDisplayMode,
1411 ddrawex1_SetCooperativeLevel,
1412 ddrawex1_SetDisplayMode,
1413 ddrawex1_WaitForVerticalBlank,
1416 HRESULT WINAPI ddrawex_factory_CreateDirectDraw(IDirectDrawFactory *iface, GUID *guid, HWND window,
1417 DWORD coop_level, DWORD reserved, IUnknown *outer_unknown, IDirectDraw **ddraw)
1419 IDirectDraw *parent = NULL;
1420 struct ddrawex *object;
1421 HRESULT hr;
1423 TRACE("iface %p, guid %s, window %p, coop_level %#x, reserved %#x, outer_unknown %p, ddraw %p.\n",
1424 iface, debugstr_guid(guid), window, coop_level, reserved, outer_unknown, ddraw);
1426 if (outer_unknown)
1427 FIXME("Implement aggregation in ddrawex's IDirectDraw interface.\n");
1429 if (!(object = heap_alloc_zero(sizeof(*object))))
1430 return E_OUTOFMEMORY;
1432 object->ref = 1;
1433 object->IDirectDraw_iface.lpVtbl = &ddrawex1_vtbl;
1434 object->IDirectDraw2_iface.lpVtbl = &ddrawex2_vtbl;
1435 object->IDirectDraw3_iface.lpVtbl = &ddrawex3_vtbl;
1436 object->IDirectDraw4_iface.lpVtbl = &ddrawex4_vtbl;
1438 if (FAILED(hr = DirectDrawCreate(guid, &parent, NULL)))
1439 goto err;
1440 if (FAILED(hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **)&object->parent)))
1441 goto err;
1442 if (FAILED(hr = IDirectDraw_SetCooperativeLevel(&object->IDirectDraw_iface, window, coop_level)))
1443 goto err;
1445 *ddraw = &object->IDirectDraw_iface;
1446 IDirectDraw_Release(parent);
1447 return DD_OK;
1449 err:
1450 if (object && object->parent)
1451 IDirectDraw4_Release(object->parent);
1452 if (parent)
1453 IDirectDraw_Release(parent);
1454 heap_free(object);
1455 *ddraw = NULL;
1456 return hr;
1459 IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
1461 struct ddrawex *ddrawex = impl_from_IDirectDraw4(outer);
1463 if (outer->lpVtbl != &ddrawex4_vtbl)
1464 return NULL;
1465 return ddrawex->parent;