include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / ddrawex / ddraw.c
bloba03683b6c2f2fd3820ad745c77437de7c594dd73
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
21 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "wingdi.h"
26 #include "ddraw.h"
27 #include "d3d.h"
29 #include "ddrawex_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);
34 static struct ddrawex *impl_from_IDirectDraw(IDirectDraw *iface)
36 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw_iface);
39 static struct ddrawex *impl_from_IDirectDraw2(IDirectDraw2 *iface)
41 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw2_iface);
44 static struct ddrawex *impl_from_IDirectDraw3(IDirectDraw3 *iface)
46 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw3_iface);
49 static struct ddrawex *impl_from_IDirectDraw4(IDirectDraw4 *iface)
51 return CONTAINING_RECORD(iface, struct ddrawex, IDirectDraw4_iface);
54 static HRESULT WINAPI ddrawex4_QueryInterface(IDirectDraw4 *iface, REFIID riid, void **out)
56 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
58 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
60 if (!riid)
62 *out = NULL;
63 return DDERR_INVALIDPARAMS;
66 if (IsEqualGUID(&IID_IDirectDraw4, riid)
67 || IsEqualGUID(&IID_IUnknown, riid))
69 *out = &ddrawex->IDirectDraw4_iface;
71 else if (IsEqualGUID(&IID_IDirectDraw3, riid))
73 *out = &ddrawex->IDirectDraw3_iface;
75 else if (IsEqualGUID(&IID_IDirectDraw2, riid))
77 *out = &ddrawex->IDirectDraw2_iface;
79 else if (IsEqualGUID(&IID_IDirectDraw, riid))
81 *out = &ddrawex->IDirectDraw_iface;
83 else
85 *out = NULL;
86 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
87 return E_NOINTERFACE;
90 IUnknown_AddRef((IUnknown *)*out);
91 return S_OK;
94 static HRESULT WINAPI ddrawex3_QueryInterface(IDirectDraw3 *iface, REFIID riid, void **out)
96 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
98 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
100 return ddrawex4_QueryInterface(&ddrawex->IDirectDraw4_iface, riid, out);
103 static HRESULT WINAPI ddrawex2_QueryInterface(IDirectDraw2 *iface, REFIID riid, void **out)
105 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
107 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
109 return ddrawex4_QueryInterface(&ddrawex->IDirectDraw4_iface, riid, out);
112 static HRESULT WINAPI ddrawex1_QueryInterface(IDirectDraw *iface, REFIID riid, void **out)
114 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
116 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
118 return ddrawex4_QueryInterface(&ddrawex->IDirectDraw4_iface, riid, out);
121 static ULONG WINAPI ddrawex4_AddRef(IDirectDraw4 *iface)
123 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
124 ULONG refcount = InterlockedIncrement(&ddrawex->ref);
126 TRACE("%p increasing refcount to %lu.\n", iface, refcount);
128 return refcount;
131 static ULONG WINAPI ddrawex3_AddRef(IDirectDraw3 *iface)
133 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
135 TRACE("iface %p.\n", iface);
137 return ddrawex4_AddRef(&ddrawex->IDirectDraw4_iface);
140 static ULONG WINAPI ddrawex2_AddRef(IDirectDraw2 *iface)
142 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
144 TRACE("iface %p.\n", iface);
146 return ddrawex4_AddRef(&ddrawex->IDirectDraw4_iface);
149 static ULONG WINAPI ddrawex1_AddRef(IDirectDraw *iface)
151 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
153 TRACE("iface %p.\n", iface);
155 return ddrawex4_AddRef(&ddrawex->IDirectDraw4_iface);
158 static ULONG WINAPI ddrawex4_Release(IDirectDraw4 *iface)
160 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
161 ULONG refcount = InterlockedDecrement(&ddrawex->ref);
163 TRACE("%p decreasing refcount to %lu.\n", iface, refcount);
165 if (!refcount)
167 IDirectDraw4_Release(ddrawex->parent);
168 free(ddrawex);
171 return refcount;
174 static ULONG WINAPI ddrawex3_Release(IDirectDraw3 *iface)
176 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
178 TRACE("iface %p.\n", iface);
180 return ddrawex4_Release(&ddrawex->IDirectDraw4_iface);
183 static ULONG WINAPI ddrawex2_Release(IDirectDraw2 *iface)
185 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
187 TRACE("iface %p.\n", iface);
189 return ddrawex4_Release(&ddrawex->IDirectDraw4_iface);
192 static ULONG WINAPI ddrawex1_Release(IDirectDraw *iface)
194 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
196 TRACE("iface %p.\n", iface);
198 return ddrawex4_Release(&ddrawex->IDirectDraw4_iface);
201 static HRESULT WINAPI ddrawex4_Compact(IDirectDraw4 *iface)
203 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
205 TRACE("iface %p.\n", iface);
207 return IDirectDraw4_Compact(ddrawex->parent);
210 static HRESULT WINAPI ddrawex3_Compact(IDirectDraw3 *iface)
212 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
214 TRACE("iface %p.\n", iface);
216 return ddrawex4_Compact(&ddrawex->IDirectDraw4_iface);
219 static HRESULT WINAPI ddrawex2_Compact(IDirectDraw2 *iface)
221 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
223 TRACE("iface %p.\n", iface);
225 return ddrawex4_Compact(&ddrawex->IDirectDraw4_iface);
228 static HRESULT WINAPI ddrawex1_Compact(IDirectDraw *iface)
230 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
232 TRACE("iface %p.\n", iface);
234 return ddrawex4_Compact(&ddrawex->IDirectDraw4_iface);
237 static HRESULT WINAPI ddrawex4_CreateClipper(IDirectDraw4 *iface, DWORD flags,
238 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
240 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
242 TRACE("iface %p, flags %#lx, clipper %p, outer_unknown %p.\n",
243 iface, flags, clipper, outer_unknown);
245 /* This may require a wrapper interface for clippers too which handles this. */
246 if (outer_unknown)
247 FIXME("Test and implement aggregation for ddrawex clippers.\n");
249 return IDirectDraw4_CreateClipper(ddrawex->parent, flags, clipper, outer_unknown);
252 static HRESULT WINAPI ddrawex3_CreateClipper(IDirectDraw3 *iface, DWORD flags,
253 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
255 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
257 TRACE("iface %p, flags %#lx, clipper %p, outer_unknown %p.\n",
258 iface, flags, clipper, outer_unknown);
260 return ddrawex4_CreateClipper(&ddrawex->IDirectDraw4_iface, flags, clipper, outer_unknown);
263 static HRESULT WINAPI ddrawex2_CreateClipper(IDirectDraw2 *iface, DWORD flags,
264 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
266 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
268 TRACE("iface %p, flags %#lx, clipper %p, outer_unknown %p.\n",
269 iface, flags, clipper, outer_unknown);
271 return ddrawex4_CreateClipper(&ddrawex->IDirectDraw4_iface, flags, clipper, outer_unknown);
274 static HRESULT WINAPI ddrawex1_CreateClipper(IDirectDraw *iface, DWORD flags,
275 IDirectDrawClipper **clipper, IUnknown *outer_unknown)
277 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
279 TRACE("iface %p, flags %#lx, clipper %p, outer_unknown %p.\n",
280 iface, flags, clipper, outer_unknown);
282 return ddrawex4_CreateClipper(&ddrawex->IDirectDraw4_iface, flags, clipper, outer_unknown);
285 static HRESULT WINAPI ddrawex4_CreatePalette(IDirectDraw4 *iface, DWORD flags,
286 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
288 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
290 TRACE("iface %p, flags %#lx, entries %p, palette %p, outer_unknown %p.\n",
291 iface, flags, entries, palette, outer_unknown);
293 /* This may require a wrapper interface for palettes too which handles this. */
294 if (outer_unknown)
295 FIXME("Test and implement aggregation for ddrawex palettes.\n");
297 return IDirectDraw4_CreatePalette(ddrawex->parent, flags, entries, palette, outer_unknown);
300 static HRESULT WINAPI ddrawex3_CreatePalette(IDirectDraw3 *iface, DWORD flags,
301 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
303 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
305 TRACE("iface %p, flags %#lx, entries %p, palette %p, outer_unknown %p.\n",
306 iface, flags, entries, palette, outer_unknown);
308 return ddrawex4_CreatePalette(&ddrawex->IDirectDraw4_iface, flags, entries, palette, outer_unknown);
311 static HRESULT WINAPI ddrawex2_CreatePalette(IDirectDraw2 *iface, DWORD flags,
312 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
314 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
316 TRACE("iface %p, flags %#lx, entries %p, palette %p, outer_unknown %p.\n",
317 iface, flags, entries, palette, outer_unknown);
319 return ddrawex4_CreatePalette(&ddrawex->IDirectDraw4_iface, flags, entries, palette, outer_unknown);
322 static HRESULT WINAPI ddrawex1_CreatePalette(IDirectDraw *iface, DWORD flags,
323 PALETTEENTRY *entries, IDirectDrawPalette **palette, IUnknown *outer_unknown)
325 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
327 TRACE("iface %p, flags %#lx, entries %p, palette %p, outer_unknown %p.\n",
328 iface, flags, entries, palette, outer_unknown);
330 return ddrawex4_CreatePalette(&ddrawex->IDirectDraw4_iface, flags, entries, palette, outer_unknown);
333 static HRESULT WINAPI ddrawex4_CreateSurface(IDirectDraw4 *iface, DDSURFACEDESC2 *desc,
334 IDirectDrawSurface4 **surface, IUnknown *outer_unknown)
336 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
337 HRESULT hr;
338 const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
339 BOOL permanent_dc;
340 IDirectDrawSurface4 *inner_surface;
342 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
343 iface, desc, surface, outer_unknown);
345 /* Handle this in this dll. Don't forward the outer_unknown to ddraw.dll. */
346 if (outer_unknown)
347 FIXME("Implement aggregation for ddrawex surfaces.\n");
349 /* Plain ddraw.dll refuses to create a surface that has both VIDMEM and
350 * SYSMEM flags set. In ddrawex this succeeds, and the GetDC() call
351 * changes the behavior. The DC is permanently valid, and the surface can
352 * be locked between GetDC() and ReleaseDC() calls. GetDC() can be called
353 * more than once too. */
354 if ((desc->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags)
356 permanent_dc = TRUE;
357 desc->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
358 desc->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
360 else
362 permanent_dc = FALSE;
365 hr = IDirectDraw4_CreateSurface(ddrawex->parent, desc, &inner_surface, outer_unknown);
366 if (FAILED(hr))
368 *surface = NULL;
369 return hr;
372 *surface = dds_get_outer(inner_surface);
373 /* The wrapper created by dds_get_outer holds a reference to its inner surface. */
374 IDirectDrawSurface4_Release(inner_surface);
376 if (permanent_dc)
377 prepare_permanent_dc(*surface);
379 return hr;
382 void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
384 memset(out, 0, sizeof(*out));
385 out->dwSize = sizeof(*out);
386 out->dwFlags = in->dwFlags;
387 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
388 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
389 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->ddpfPixelFormat;
390 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
391 if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch;
392 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
393 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwMipMapCount = in->dwZBufferBitDepth; /* same union */
394 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
395 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
396 out->lpSurface = in->lpSurface;
397 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay;
398 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
399 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
400 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
401 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->dwMipMapCount = in->dwMipMapCount;
402 if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate;
403 if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->dwLinearSize;
404 /* Does not exist in DDSURFACEDESC:
405 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
409 void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
411 memset(out, 0, sizeof(*out));
412 out->dwSize = sizeof(*out);
413 out->dwFlags = in->dwFlags;
414 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
415 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
416 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->ddpfPixelFormat;
417 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
418 if(in->dwFlags & DDSD_PITCH) out->lPitch = in->lPitch;
419 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
420 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwZBufferBitDepth = in->dwMipMapCount; /* same union */
421 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
422 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
423 out->lpSurface = in->lpSurface;
424 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay;
425 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
426 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
427 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
428 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->dwMipMapCount = in->dwMipMapCount;
429 if(in->dwFlags & DDSD_REFRESHRATE) out->dwRefreshRate = in->dwRefreshRate;
430 if(in->dwFlags & DDSD_LINEARSIZE) out->dwLinearSize = in->dwLinearSize;
431 /* Does not exist in DDSURFACEDESC:
432 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
434 if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n");
435 if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n");
436 if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n");
437 out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE);
440 static HRESULT WINAPI ddrawex3_CreateSurface(IDirectDraw3 *iface, DDSURFACEDESC *desc,
441 IDirectDrawSurface **surface, IUnknown *outer_unknown)
443 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
444 DDSURFACEDESC2 ddsd2;
445 IDirectDrawSurface4 *surf4 = NULL;
446 HRESULT hr;
448 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
449 iface, desc, surface, outer_unknown);
451 DDSD_to_DDSD2(desc, &ddsd2);
452 if (FAILED(hr = ddrawex4_CreateSurface(&ddrawex->IDirectDraw4_iface, &ddsd2, &surf4, outer_unknown)))
454 *surface = NULL;
455 return hr;
458 TRACE("Got surface %p\n", surf4);
459 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)surface);
460 IDirectDrawSurface4_Release(surf4);
461 return hr;
464 static HRESULT WINAPI ddrawex2_CreateSurface(IDirectDraw2 *iface, DDSURFACEDESC *desc,
465 IDirectDrawSurface **surface, IUnknown *outer_unknown)
467 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
469 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
470 iface, desc, surface, outer_unknown);
472 return ddrawex3_CreateSurface(&ddrawex->IDirectDraw3_iface, desc, surface, outer_unknown);
475 static HRESULT WINAPI ddrawex1_CreateSurface(IDirectDraw *iface, DDSURFACEDESC *desc,
476 IDirectDrawSurface **surface, IUnknown *outer_unknown)
478 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
480 TRACE("iface %p, desc %p, surface %p, outer_unknown %p.\n",
481 iface, desc, surface, outer_unknown);
483 return ddrawex3_CreateSurface(&ddrawex->IDirectDraw3_iface, desc, surface, outer_unknown);
486 static HRESULT WINAPI ddrawex4_DuplicateSurface(IDirectDraw4 *iface,
487 IDirectDrawSurface4 *src, IDirectDrawSurface4 **dst)
489 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
490 struct ddrawex_surface *src_impl = unsafe_impl_from_IDirectDrawSurface4(src);
492 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
493 FIXME("Create a wrapper surface.\n");
495 return IDirectDraw4_DuplicateSurface(ddrawex->parent, src_impl ? src_impl->parent : NULL, dst);
498 static HRESULT WINAPI ddrawex3_DuplicateSurface(IDirectDraw3 *iface,
499 IDirectDrawSurface *src, IDirectDrawSurface **dst)
501 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
502 IDirectDrawSurface4 *src_4;
503 IDirectDrawSurface4 *dst_4;
504 HRESULT hr;
506 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
508 IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **)&src_4);
509 hr = ddrawex4_DuplicateSurface(&ddrawex->IDirectDraw4_iface, src_4, &dst_4);
510 IDirectDrawSurface4_Release(src_4);
511 if (FAILED(hr))
513 *dst = NULL;
514 return hr;
517 IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **)dst);
518 IDirectDrawSurface4_Release(dst_4);
520 return hr;
523 static HRESULT WINAPI ddrawex2_DuplicateSurface(IDirectDraw2 *iface,
524 IDirectDrawSurface *src, IDirectDrawSurface **dst)
526 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
528 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
530 return ddrawex3_DuplicateSurface(&ddrawex->IDirectDraw3_iface, src, dst);
533 static HRESULT WINAPI ddrawex1_DuplicateSurface(IDirectDraw *iface,
534 IDirectDrawSurface *src, IDirectDrawSurface **dst)
536 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
538 TRACE("iface %p, src %p, dst %p.\n", iface, src, dst);
540 return ddrawex3_DuplicateSurface(&ddrawex->IDirectDraw3_iface, src, dst);
543 static HRESULT WINAPI ddrawex4_EnumDisplayModes(IDirectDraw4 *iface, DWORD flags,
544 DDSURFACEDESC2 *desc, void *ctx, LPDDENUMMODESCALLBACK2 cb)
546 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
548 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
550 return IDirectDraw4_EnumDisplayModes(ddrawex->parent, flags, desc, ctx, cb);
553 struct enummodes_ctx
555 LPDDENUMMODESCALLBACK orig_cb;
556 void *orig_ctx;
559 static HRESULT WINAPI
560 enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx)
562 struct enummodes_ctx *ctx = vctx;
563 DDSURFACEDESC ddsd;
565 DDSD2_to_DDSD(ddsd2, &ddsd);
566 return ctx->orig_cb(&ddsd, ctx->orig_ctx);
569 static HRESULT WINAPI ddrawex3_EnumDisplayModes(IDirectDraw3 *iface, DWORD flags,
570 DDSURFACEDESC *desc, void *ctx, LPDDENUMMODESCALLBACK cb)
572 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
573 struct enummodes_ctx cb_ctx;
574 DDSURFACEDESC2 ddsd2;
576 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
578 DDSD_to_DDSD2(desc, &ddsd2);
579 cb_ctx.orig_cb = cb;
580 cb_ctx.orig_ctx = ctx;
581 return ddrawex4_EnumDisplayModes(&ddrawex->IDirectDraw4_iface, flags, &ddsd2, &cb_ctx, enum_modes_cb2);
584 static HRESULT WINAPI ddrawex2_EnumDisplayModes(IDirectDraw2 *iface, DWORD flags,
585 DDSURFACEDESC *desc, void *ctx, LPDDENUMMODESCALLBACK cb)
587 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
589 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
591 return ddrawex3_EnumDisplayModes(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
594 static HRESULT WINAPI ddrawex1_EnumDisplayModes(IDirectDraw *iface, DWORD flags,
595 DDSURFACEDESC *desc, void *ctx, LPDDENUMMODESCALLBACK cb)
597 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
599 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
601 return ddrawex3_EnumDisplayModes(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
604 struct enumsurfaces4_ctx
606 LPDDENUMSURFACESCALLBACK2 orig_cb;
607 void *orig_ctx;
610 static HRESULT WINAPI
611 enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
613 struct enumsurfaces4_ctx *ctx = vctx;
614 IDirectDrawSurface4 *outer = dds_get_outer(surf4);
615 IDirectDrawSurface4_AddRef(outer);
616 IDirectDrawSurface4_Release(surf4);
617 TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4);
618 return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx);
621 static HRESULT WINAPI ddrawex4_EnumSurfaces(IDirectDraw4 *iface, DWORD flags,
622 DDSURFACEDESC2 *desc, void *ctx, LPDDENUMSURFACESCALLBACK2 cb)
624 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
625 struct enumsurfaces4_ctx cb_ctx;
627 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
629 cb_ctx.orig_cb = cb;
630 cb_ctx.orig_ctx = ctx;
631 return IDirectDraw4_EnumSurfaces(ddrawex->parent, flags, desc, &cb_ctx, enum_surfaces_wrapper);
634 struct enumsurfaces_ctx
636 LPDDENUMSURFACESCALLBACK orig_cb;
637 void *orig_ctx;
640 static HRESULT WINAPI
641 enum_surfaces_cb2(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
643 struct enumsurfaces_ctx *ctx = vctx;
644 IDirectDrawSurface *surf1;
645 DDSURFACEDESC ddsd;
647 /* Keep the reference, it goes to the application */
648 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) &surf1);
649 /* Release the reference this function got */
650 IDirectDrawSurface4_Release(surf4);
652 DDSD2_to_DDSD(ddsd2, &ddsd);
653 return ctx->orig_cb(surf1, &ddsd, ctx->orig_ctx);
656 static HRESULT WINAPI ddrawex3_EnumSurfaces(IDirectDraw3 *iface, DWORD flags,
657 DDSURFACEDESC *desc, void *ctx, LPDDENUMSURFACESCALLBACK cb)
659 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
660 DDSURFACEDESC2 ddsd2;
661 struct enumsurfaces_ctx cb_ctx;
663 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
665 DDSD_to_DDSD2(desc, &ddsd2);
666 cb_ctx.orig_cb = cb;
667 cb_ctx.orig_ctx = ctx;
668 return ddrawex4_EnumSurfaces(&ddrawex->IDirectDraw4_iface, flags, &ddsd2, &cb_ctx, enum_surfaces_cb2);
671 static HRESULT WINAPI ddrawex2_EnumSurfaces(IDirectDraw2 *iface, DWORD flags,
672 DDSURFACEDESC *desc, void *ctx, LPDDENUMSURFACESCALLBACK cb)
674 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
676 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
678 return ddrawex3_EnumSurfaces(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
681 static HRESULT WINAPI ddrawex1_EnumSurfaces(IDirectDraw *iface, DWORD flags,
682 DDSURFACEDESC *desc, void *ctx, LPDDENUMSURFACESCALLBACK cb)
684 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
686 TRACE("iface %p, flags %#lx, desc %p, ctx %p, cb %p.\n", iface, flags, desc, ctx, cb);
688 return ddrawex3_EnumSurfaces(&ddrawex->IDirectDraw3_iface, flags, desc, ctx, cb);
691 static HRESULT WINAPI ddrawex4_FlipToGDISurface(IDirectDraw4 *iface)
693 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
695 TRACE("iface %p.\n", iface);
697 return IDirectDraw4_FlipToGDISurface(ddrawex->parent);
700 static HRESULT WINAPI ddrawex3_FlipToGDISurface(IDirectDraw3 *iface)
702 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
704 TRACE("iface %p.\n", iface);
706 return ddrawex4_FlipToGDISurface(&ddrawex->IDirectDraw4_iface);
709 static HRESULT WINAPI ddrawex2_FlipToGDISurface(IDirectDraw2 *iface)
711 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
713 TRACE("iface %p.\n", iface);
715 return ddrawex4_FlipToGDISurface(&ddrawex->IDirectDraw4_iface);
718 static HRESULT WINAPI ddrawex1_FlipToGDISurface(IDirectDraw *iface)
720 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
722 TRACE("iface %p.\n", iface);
724 return ddrawex4_FlipToGDISurface(&ddrawex->IDirectDraw4_iface);
727 static HRESULT WINAPI ddrawex4_GetCaps(IDirectDraw4 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
729 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
731 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
733 return IDirectDraw4_GetCaps(ddrawex->parent, driver_caps, hel_caps);
736 static HRESULT WINAPI ddrawex3_GetCaps(IDirectDraw3 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
738 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
740 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
742 return ddrawex4_GetCaps(&ddrawex->IDirectDraw4_iface, driver_caps, hel_caps);
745 static HRESULT WINAPI ddrawex2_GetCaps(IDirectDraw2 *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
747 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
749 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
751 return ddrawex4_GetCaps(&ddrawex->IDirectDraw4_iface, driver_caps, hel_caps);
754 static HRESULT WINAPI ddrawex1_GetCaps(IDirectDraw *iface, DDCAPS *driver_caps, DDCAPS *hel_caps)
756 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
758 TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, driver_caps, hel_caps);
760 return ddrawex4_GetCaps(&ddrawex->IDirectDraw4_iface, driver_caps, hel_caps);
763 static HRESULT WINAPI ddrawex4_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 *desc)
765 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
767 TRACE("iface %p, desc %p.\n", iface, desc);
769 return IDirectDraw4_GetDisplayMode(ddrawex->parent, desc);
772 static HRESULT WINAPI ddrawex3_GetDisplayMode(IDirectDraw3 *iface, DDSURFACEDESC *desc)
774 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
775 DDSURFACEDESC2 ddsd2;
776 HRESULT hr;
778 TRACE("iface %p, desc %p.\n", iface, desc);
780 hr = ddrawex4_GetDisplayMode(&ddrawex->IDirectDraw4_iface, &ddsd2);
781 DDSD2_to_DDSD(&ddsd2, desc);
783 return hr;
786 static HRESULT WINAPI ddrawex2_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC *desc)
788 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
790 TRACE("iface %p, desc %p.\n", iface, desc);
792 return ddrawex3_GetDisplayMode(&ddrawex->IDirectDraw3_iface, desc);
795 static HRESULT WINAPI ddrawex1_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *desc)
797 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
799 TRACE("iface %p, desc %p.\n", iface, desc);
801 return ddrawex3_GetDisplayMode(&ddrawex->IDirectDraw3_iface, desc);
804 static HRESULT WINAPI ddrawex4_GetFourCCCodes(IDirectDraw4 *iface, DWORD *code_count, DWORD *codes)
806 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
808 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
810 return IDirectDraw4_GetFourCCCodes(ddrawex->parent, code_count, codes);
813 static HRESULT WINAPI ddrawex3_GetFourCCCodes(IDirectDraw3 *iface, DWORD *code_count, DWORD *codes)
815 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
817 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
819 return ddrawex4_GetFourCCCodes(&ddrawex->IDirectDraw4_iface, code_count, codes);
822 static HRESULT WINAPI ddrawex2_GetFourCCCodes(IDirectDraw2 *iface, DWORD *code_count, DWORD *codes)
824 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
826 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
828 return ddrawex4_GetFourCCCodes(&ddrawex->IDirectDraw4_iface, code_count, codes);
831 static HRESULT WINAPI ddrawex1_GetFourCCCodes(IDirectDraw *iface, DWORD *code_count, DWORD *codes)
833 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
835 TRACE("iface %p, code_count %p, codes %p.\n", iface, code_count, codes);
837 return ddrawex4_GetFourCCCodes(&ddrawex->IDirectDraw4_iface, code_count, codes);
840 static HRESULT WINAPI ddrawex4_GetGDISurface(IDirectDraw4 *iface, IDirectDrawSurface4 **gdi_surface)
842 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
843 IDirectDrawSurface4 *inner = NULL;
844 HRESULT hr;
846 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
848 if (FAILED(hr = IDirectDraw4_GetGDISurface(ddrawex->parent, &inner)))
850 *gdi_surface = NULL;
851 return hr;
854 *gdi_surface = dds_get_outer(inner);
855 IDirectDrawSurface4_AddRef(*gdi_surface);
856 IDirectDrawSurface4_Release(inner);
857 return hr;
860 static HRESULT WINAPI ddrawex3_GetGDISurface(IDirectDraw3 *iface, IDirectDrawSurface **gdi_surface)
862 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
863 IDirectDrawSurface4 *surf4;
864 HRESULT hr;
866 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
868 if (FAILED(hr = ddrawex4_GetGDISurface(&ddrawex->IDirectDraw4_iface, &surf4)))
870 *gdi_surface = NULL;
871 return hr;
874 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)gdi_surface);
875 IDirectDrawSurface4_Release(surf4);
876 return hr;
879 static HRESULT WINAPI ddrawex2_GetGDISurface(IDirectDraw2 *iface, IDirectDrawSurface **gdi_surface)
881 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
883 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
885 return ddrawex3_GetGDISurface(&ddrawex->IDirectDraw3_iface, gdi_surface);
888 static HRESULT WINAPI ddrawex1_GetGDISurface(IDirectDraw *iface, IDirectDrawSurface **gdi_surface)
890 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
892 TRACE("iface %p, gdi_surface %p.\n", iface, gdi_surface);
894 return ddrawex3_GetGDISurface(&ddrawex->IDirectDraw3_iface, gdi_surface);
897 static HRESULT WINAPI ddrawex4_GetMonitorFrequency(IDirectDraw4 *iface, DWORD *frequency)
899 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
901 TRACE("iface %p, frequency %p.\n", iface, frequency);
903 return IDirectDraw4_GetMonitorFrequency(ddrawex->parent, frequency);
906 static HRESULT WINAPI ddrawex3_GetMonitorFrequency(IDirectDraw3 *iface, DWORD *frequency)
908 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
910 TRACE("iface %p, frequency %p.\n", iface, frequency);
912 return ddrawex4_GetMonitorFrequency(&ddrawex->IDirectDraw4_iface, frequency);
915 static HRESULT WINAPI ddrawex2_GetMonitorFrequency(IDirectDraw2 *iface, DWORD *frequency)
917 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
919 TRACE("iface %p, frequency %p.\n", iface, frequency);
921 return ddrawex4_GetMonitorFrequency(&ddrawex->IDirectDraw4_iface, frequency);
924 static HRESULT WINAPI ddrawex1_GetMonitorFrequency(IDirectDraw *iface, DWORD *frequency)
926 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
928 TRACE("iface %p, frequency %p.\n", iface, frequency);
930 return ddrawex4_GetMonitorFrequency(&ddrawex->IDirectDraw4_iface, frequency);
933 static HRESULT WINAPI ddrawex4_GetScanLine(IDirectDraw4 *iface, DWORD *line)
935 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
937 TRACE("iface %p, line %p.\n", iface, line);
939 return IDirectDraw4_GetScanLine(ddrawex->parent, line);
942 static HRESULT WINAPI ddrawex3_GetScanLine(IDirectDraw3 *iface, DWORD *line)
944 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
946 TRACE("iface %p, line %p.\n", iface, line);
948 return ddrawex4_GetScanLine(&ddrawex->IDirectDraw4_iface, line);
951 static HRESULT WINAPI ddrawex2_GetScanLine(IDirectDraw2 *iface, DWORD *line)
953 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
955 TRACE("iface %p, line %p.\n", iface, line);
957 return ddrawex4_GetScanLine(&ddrawex->IDirectDraw4_iface, line);
960 static HRESULT WINAPI ddrawex1_GetScanLine(IDirectDraw *iface, DWORD *line)
962 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
964 TRACE("iface %p, line %p.\n", iface, line);
966 return ddrawex4_GetScanLine(&ddrawex->IDirectDraw4_iface, line);
969 static HRESULT WINAPI ddrawex4_GetVerticalBlankStatus(IDirectDraw4 *iface, BOOL *status)
971 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
973 TRACE("iface %p, status %p.\n", iface, status);
975 return IDirectDraw4_GetVerticalBlankStatus(ddrawex->parent, status);
978 static HRESULT WINAPI ddrawex3_GetVerticalBlankStatus(IDirectDraw3 *iface, BOOL *status)
980 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
982 TRACE("iface %p, status %p.\n", iface, status);
984 return ddrawex4_GetVerticalBlankStatus(&ddrawex->IDirectDraw4_iface, status);
987 static HRESULT WINAPI ddrawex2_GetVerticalBlankStatus(IDirectDraw2 *iface, BOOL *status)
989 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
991 TRACE("iface %p, status %p.\n", iface, status);
993 return ddrawex4_GetVerticalBlankStatus(&ddrawex->IDirectDraw4_iface, status);
996 static HRESULT WINAPI ddrawex1_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *status)
998 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1000 TRACE("iface %p, status %p.\n", iface, status);
1002 return ddrawex4_GetVerticalBlankStatus(&ddrawex->IDirectDraw4_iface, status);
1005 static HRESULT WINAPI ddrawex4_Initialize(IDirectDraw4 *iface, GUID *guid)
1007 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1009 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1011 return IDirectDraw4_Initialize(ddrawex->parent, guid);
1014 static HRESULT WINAPI ddrawex3_Initialize(IDirectDraw3 *iface, GUID *guid)
1016 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1018 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1020 return ddrawex4_Initialize(&ddrawex->IDirectDraw4_iface, guid);
1023 static HRESULT WINAPI ddrawex2_Initialize(IDirectDraw2 *iface, GUID *guid)
1025 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1027 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1029 return ddrawex4_Initialize(&ddrawex->IDirectDraw4_iface, guid);
1032 static HRESULT WINAPI ddrawex1_Initialize(IDirectDraw *iface, GUID *guid)
1034 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1036 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
1038 return ddrawex4_Initialize(&ddrawex->IDirectDraw4_iface, guid);
1041 static HRESULT WINAPI ddrawex4_RestoreDisplayMode(IDirectDraw4 *iface)
1043 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1045 TRACE("iface %p.\n", iface);
1047 return IDirectDraw4_RestoreDisplayMode(ddrawex->parent);
1050 static HRESULT WINAPI ddrawex3_RestoreDisplayMode(IDirectDraw3 *iface)
1052 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1054 TRACE("iface %p.\n", iface);
1056 return ddrawex4_RestoreDisplayMode(&ddrawex->IDirectDraw4_iface);
1059 static HRESULT WINAPI ddrawex2_RestoreDisplayMode(IDirectDraw2 *iface)
1061 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1063 TRACE("iface %p.\n", iface);
1065 return ddrawex4_RestoreDisplayMode(&ddrawex->IDirectDraw4_iface);
1068 static HRESULT WINAPI ddrawex1_RestoreDisplayMode(IDirectDraw *iface)
1070 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1072 TRACE("iface %p.\n", iface);
1074 return ddrawex4_RestoreDisplayMode(&ddrawex->IDirectDraw4_iface);
1077 static HRESULT WINAPI ddrawex4_SetCooperativeLevel(IDirectDraw4 *iface, HWND window, DWORD flags)
1079 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1081 TRACE("iface %p, window %p, flags %#lx.\n", iface, window, flags);
1083 return IDirectDraw4_SetCooperativeLevel(ddrawex->parent, window, flags);
1086 static HRESULT WINAPI ddrawex3_SetCooperativeLevel(IDirectDraw3 *iface, HWND window, DWORD flags)
1088 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1090 TRACE("iface %p, window %p, flags %#lx.\n", iface, window, flags);
1092 return ddrawex4_SetCooperativeLevel(&ddrawex->IDirectDraw4_iface, window, flags);
1095 static HRESULT WINAPI ddrawex2_SetCooperativeLevel(IDirectDraw2 *iface, HWND window, DWORD flags)
1097 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1099 TRACE("iface %p, window %p, flags %#lx.\n", iface, window, flags);
1101 return ddrawex4_SetCooperativeLevel(&ddrawex->IDirectDraw4_iface, window, flags);
1104 static HRESULT WINAPI ddrawex1_SetCooperativeLevel(IDirectDraw *iface, HWND window, DWORD flags)
1106 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1108 TRACE("iface %p, window %p, flags %#lx.\n", iface, window, flags);
1110 return ddrawex4_SetCooperativeLevel(&ddrawex->IDirectDraw4_iface, window, flags);
1113 static HRESULT WINAPI ddrawex4_SetDisplayMode(IDirectDraw4 *iface, DWORD width,
1114 DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
1116 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1118 TRACE("iface %p, width %lu, height %lu, bpp %lu, refresh_rate %lu, flags %#lx.\n",
1119 iface, width, height, bpp, refresh_rate, flags);
1121 return IDirectDraw4_SetDisplayMode(ddrawex->parent, width, height, bpp, refresh_rate, flags);
1124 static HRESULT WINAPI ddrawex3_SetDisplayMode(IDirectDraw3 *iface, DWORD width,
1125 DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
1127 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1129 TRACE("iface %p, width %lu, height %lu, bpp %lu, refresh_rate %lu, flags %#lx.\n",
1130 iface, width, height, bpp, refresh_rate, flags);
1132 return ddrawex4_SetDisplayMode(&ddrawex->IDirectDraw4_iface, width, height, bpp, refresh_rate, flags);
1135 static HRESULT WINAPI ddrawex2_SetDisplayMode(IDirectDraw2 *iface, DWORD width,
1136 DWORD height, DWORD bpp, DWORD refresh_rate, DWORD flags)
1138 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1140 TRACE("iface %p, width %lu, height %lu, bpp %lu, refresh_rate %lu, flags %#lx.\n",
1141 iface, width, height, bpp, refresh_rate, flags);
1143 return ddrawex4_SetDisplayMode(&ddrawex->IDirectDraw4_iface, width, height, bpp, refresh_rate, flags);
1146 static HRESULT WINAPI ddrawex1_SetDisplayMode(IDirectDraw *iface, DWORD width,
1147 DWORD height, DWORD bpp)
1149 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1151 TRACE("iface %p, width %lu, height %lu, bpp %lu.\n", iface, width, height, bpp);
1153 return ddrawex4_SetDisplayMode(&ddrawex->IDirectDraw4_iface, width, height, bpp, 0, 0);
1156 static HRESULT WINAPI ddrawex4_WaitForVerticalBlank(IDirectDraw4 *iface, DWORD flags, HANDLE event)
1158 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1160 TRACE("iface %p, flags %#lx, event %p.\n", iface, flags, event);
1162 return IDirectDraw4_WaitForVerticalBlank(ddrawex->parent, flags, event);
1165 static HRESULT WINAPI ddrawex3_WaitForVerticalBlank(IDirectDraw3 *iface, DWORD flags, HANDLE event)
1167 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1169 TRACE("iface %p, flags %#lx, event %p.\n", iface, flags, event);
1171 return ddrawex4_WaitForVerticalBlank(&ddrawex->IDirectDraw4_iface, flags, event);
1174 static HRESULT WINAPI ddrawex2_WaitForVerticalBlank(IDirectDraw2 *iface, DWORD flags, HANDLE event)
1176 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1178 TRACE("iface %p, flags %#lx, event %p.\n", iface, flags, event);
1180 return ddrawex4_WaitForVerticalBlank(&ddrawex->IDirectDraw4_iface, flags, event);
1183 static HRESULT WINAPI ddrawex1_WaitForVerticalBlank(IDirectDraw *iface, DWORD flags, HANDLE event)
1185 struct ddrawex *ddrawex = impl_from_IDirectDraw(iface);
1187 TRACE("iface %p, flags %#lx, event %p.\n", iface, flags, event);
1189 return ddrawex4_WaitForVerticalBlank(&ddrawex->IDirectDraw4_iface, flags, event);
1192 static HRESULT WINAPI ddrawex4_GetAvailableVidMem(IDirectDraw4 *iface,
1193 DDSCAPS2 *caps, DWORD *total, DWORD *free)
1195 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1197 TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
1199 return IDirectDraw4_GetAvailableVidMem(ddrawex->parent, caps, total, free);
1202 static HRESULT WINAPI ddrawex3_GetAvailableVidMem(IDirectDraw3 *iface,
1203 DDSCAPS *caps, DWORD *total, DWORD *free)
1205 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1206 DDSCAPS2 caps2;
1208 TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
1210 memset(&caps2, 0, sizeof(caps2));
1211 caps2.dwCaps = caps->dwCaps;
1212 return ddrawex4_GetAvailableVidMem(&ddrawex->IDirectDraw4_iface, &caps2, total, free);
1215 static HRESULT WINAPI ddrawex2_GetAvailableVidMem(IDirectDraw2 *iface,
1216 DDSCAPS *caps, DWORD *total, DWORD *free)
1218 struct ddrawex *ddrawex = impl_from_IDirectDraw2(iface);
1219 DDSCAPS2 caps2;
1221 TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free);
1223 memset(&caps2, 0, sizeof(caps2));
1224 caps2.dwCaps = caps->dwCaps;
1225 return ddrawex4_GetAvailableVidMem(&ddrawex->IDirectDraw4_iface, &caps2, total, free);
1228 static HRESULT WINAPI ddrawex4_GetSurfaceFromDC(IDirectDraw4 *iface,
1229 HDC dc, IDirectDrawSurface4 **surface)
1231 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1233 TRACE("iface %p, dc %p, surface %p.\n", iface, dc, surface);
1235 return IDirectDraw4_GetSurfaceFromDC(ddrawex->parent, dc, surface);
1238 static HRESULT WINAPI ddrawex3_GetSurfaceFromDC(IDirectDraw3 *iface,
1239 HDC dc, IDirectDrawSurface **surface)
1241 struct ddrawex *ddrawex = impl_from_IDirectDraw3(iface);
1242 IDirectDrawSurface4 *surf4, *outer;
1243 IDirectDrawSurface *inner;
1244 HRESULT hr;
1246 TRACE("iface %p, dc %p, surface %p.\n", iface, dc, surface);
1248 if (!surface)
1249 return E_POINTER;
1251 if (FAILED(hr = IDirectDraw4_GetSurfaceFromDC(ddrawex->parent, dc, (IDirectDrawSurface4 **)&inner)))
1253 *surface = NULL;
1254 return hr;
1257 hr = IDirectDrawSurface_QueryInterface(inner, &IID_IDirectDrawSurface4, (void **)&surf4);
1258 IDirectDrawSurface_Release(inner);
1259 if (FAILED(hr))
1261 *surface = NULL;
1262 return hr;
1265 outer = dds_get_outer(surf4);
1266 hr = IDirectDrawSurface4_QueryInterface(outer, &IID_IDirectDrawSurface, (void **)surface);
1267 IDirectDrawSurface4_Release(surf4);
1268 return hr;
1271 static HRESULT WINAPI ddrawex4_RestoreAllSurfaces(IDirectDraw4 *iface)
1273 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1275 TRACE("iface %p.\n", iface);
1277 return IDirectDraw4_RestoreAllSurfaces(ddrawex->parent);
1280 static HRESULT WINAPI ddrawex4_TestCooperativeLevel(IDirectDraw4 *iface)
1282 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1284 TRACE("iface %p.\n", iface);
1286 return IDirectDraw4_TestCooperativeLevel(ddrawex->parent);
1289 static HRESULT WINAPI ddrawex4_GetDeviceIdentifier(IDirectDraw4 *iface,
1290 DDDEVICEIDENTIFIER *identifier, DWORD flags)
1292 struct ddrawex *ddrawex = impl_from_IDirectDraw4(iface);
1294 TRACE("iface %p, identifier %p, flags %#lx.\n", iface, identifier, flags);
1296 return IDirectDraw4_GetDeviceIdentifier(ddrawex->parent, identifier, flags);
1299 static const IDirectDraw4Vtbl ddrawex4_vtbl =
1301 ddrawex4_QueryInterface,
1302 ddrawex4_AddRef,
1303 ddrawex4_Release,
1304 ddrawex4_Compact,
1305 ddrawex4_CreateClipper,
1306 ddrawex4_CreatePalette,
1307 ddrawex4_CreateSurface,
1308 ddrawex4_DuplicateSurface,
1309 ddrawex4_EnumDisplayModes,
1310 ddrawex4_EnumSurfaces,
1311 ddrawex4_FlipToGDISurface,
1312 ddrawex4_GetCaps,
1313 ddrawex4_GetDisplayMode,
1314 ddrawex4_GetFourCCCodes,
1315 ddrawex4_GetGDISurface,
1316 ddrawex4_GetMonitorFrequency,
1317 ddrawex4_GetScanLine,
1318 ddrawex4_GetVerticalBlankStatus,
1319 ddrawex4_Initialize,
1320 ddrawex4_RestoreDisplayMode,
1321 ddrawex4_SetCooperativeLevel,
1322 ddrawex4_SetDisplayMode,
1323 ddrawex4_WaitForVerticalBlank,
1324 ddrawex4_GetAvailableVidMem,
1325 ddrawex4_GetSurfaceFromDC,
1326 ddrawex4_RestoreAllSurfaces,
1327 ddrawex4_TestCooperativeLevel,
1328 ddrawex4_GetDeviceIdentifier,
1331 static const IDirectDraw3Vtbl ddrawex3_vtbl =
1333 ddrawex3_QueryInterface,
1334 ddrawex3_AddRef,
1335 ddrawex3_Release,
1336 ddrawex3_Compact,
1337 ddrawex3_CreateClipper,
1338 ddrawex3_CreatePalette,
1339 ddrawex3_CreateSurface,
1340 ddrawex3_DuplicateSurface,
1341 ddrawex3_EnumDisplayModes,
1342 ddrawex3_EnumSurfaces,
1343 ddrawex3_FlipToGDISurface,
1344 ddrawex3_GetCaps,
1345 ddrawex3_GetDisplayMode,
1346 ddrawex3_GetFourCCCodes,
1347 ddrawex3_GetGDISurface,
1348 ddrawex3_GetMonitorFrequency,
1349 ddrawex3_GetScanLine,
1350 ddrawex3_GetVerticalBlankStatus,
1351 ddrawex3_Initialize,
1352 ddrawex3_RestoreDisplayMode,
1353 ddrawex3_SetCooperativeLevel,
1354 ddrawex3_SetDisplayMode,
1355 ddrawex3_WaitForVerticalBlank,
1356 ddrawex3_GetAvailableVidMem,
1357 ddrawex3_GetSurfaceFromDC,
1360 static const IDirectDraw2Vtbl ddrawex2_vtbl =
1362 ddrawex2_QueryInterface,
1363 ddrawex2_AddRef,
1364 ddrawex2_Release,
1365 ddrawex2_Compact,
1366 ddrawex2_CreateClipper,
1367 ddrawex2_CreatePalette,
1368 ddrawex2_CreateSurface,
1369 ddrawex2_DuplicateSurface,
1370 ddrawex2_EnumDisplayModes,
1371 ddrawex2_EnumSurfaces,
1372 ddrawex2_FlipToGDISurface,
1373 ddrawex2_GetCaps,
1374 ddrawex2_GetDisplayMode,
1375 ddrawex2_GetFourCCCodes,
1376 ddrawex2_GetGDISurface,
1377 ddrawex2_GetMonitorFrequency,
1378 ddrawex2_GetScanLine,
1379 ddrawex2_GetVerticalBlankStatus,
1380 ddrawex2_Initialize,
1381 ddrawex2_RestoreDisplayMode,
1382 ddrawex2_SetCooperativeLevel,
1383 ddrawex2_SetDisplayMode,
1384 ddrawex2_WaitForVerticalBlank,
1385 ddrawex2_GetAvailableVidMem,
1388 static const IDirectDrawVtbl ddrawex1_vtbl =
1390 ddrawex1_QueryInterface,
1391 ddrawex1_AddRef,
1392 ddrawex1_Release,
1393 ddrawex1_Compact,
1394 ddrawex1_CreateClipper,
1395 ddrawex1_CreatePalette,
1396 ddrawex1_CreateSurface,
1397 ddrawex1_DuplicateSurface,
1398 ddrawex1_EnumDisplayModes,
1399 ddrawex1_EnumSurfaces,
1400 ddrawex1_FlipToGDISurface,
1401 ddrawex1_GetCaps,
1402 ddrawex1_GetDisplayMode,
1403 ddrawex1_GetFourCCCodes,
1404 ddrawex1_GetGDISurface,
1405 ddrawex1_GetMonitorFrequency,
1406 ddrawex1_GetScanLine,
1407 ddrawex1_GetVerticalBlankStatus,
1408 ddrawex1_Initialize,
1409 ddrawex1_RestoreDisplayMode,
1410 ddrawex1_SetCooperativeLevel,
1411 ddrawex1_SetDisplayMode,
1412 ddrawex1_WaitForVerticalBlank,
1415 HRESULT WINAPI ddrawex_factory_CreateDirectDraw(IDirectDrawFactory *iface, GUID *guid, HWND window,
1416 DWORD coop_level, DWORD reserved, IUnknown *outer_unknown, IDirectDraw **ddraw)
1418 IDirectDraw *parent = NULL;
1419 struct ddrawex *object;
1420 HRESULT hr;
1422 TRACE("iface %p, guid %s, window %p, coop_level %#lx, reserved %#lx, outer_unknown %p, ddraw %p.\n",
1423 iface, debugstr_guid(guid), window, coop_level, reserved, outer_unknown, ddraw);
1425 if (outer_unknown)
1426 FIXME("Implement aggregation in ddrawex's IDirectDraw interface.\n");
1428 if (!(object = calloc(1, sizeof(*object))))
1429 return E_OUTOFMEMORY;
1431 object->ref = 1;
1432 object->IDirectDraw_iface.lpVtbl = &ddrawex1_vtbl;
1433 object->IDirectDraw2_iface.lpVtbl = &ddrawex2_vtbl;
1434 object->IDirectDraw3_iface.lpVtbl = &ddrawex3_vtbl;
1435 object->IDirectDraw4_iface.lpVtbl = &ddrawex4_vtbl;
1437 if (FAILED(hr = DirectDrawCreate(guid, &parent, NULL)))
1438 goto err;
1439 if (FAILED(hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **)&object->parent)))
1440 goto err;
1441 if (FAILED(hr = IDirectDraw_SetCooperativeLevel(&object->IDirectDraw_iface, window, coop_level)))
1442 goto err;
1444 *ddraw = &object->IDirectDraw_iface;
1445 IDirectDraw_Release(parent);
1446 return DD_OK;
1448 err:
1449 if (object && object->parent)
1450 IDirectDraw4_Release(object->parent);
1451 if (parent)
1452 IDirectDraw_Release(parent);
1453 free(object);
1454 *ddraw = NULL;
1455 return hr;
1458 IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
1460 struct ddrawex *ddrawex = impl_from_IDirectDraw4(outer);
1462 if (outer->lpVtbl != &ddrawex4_vtbl)
1463 return NULL;
1464 return ddrawex->parent;