1 /*
2 * Copyright 2008 Stefan Dösinger for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #define COBJMACROS
20 #define NONAMELESSUNION
21
22 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26
27 #include "ddraw.h"
28 #include "d3d.h"
29
30 #include "ddrawex_private.h"
31 #include "wine/debug.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);
34
35 /******************************************************************************
36 * Helper functions for COM management
37 ******************************************************************************/
38 static IDirectDrawImpl *impl_from_dd1(IDirectDraw *iface)
39 {
40 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw_Vtbl));
41 }
42 static IDirectDraw *dd1_from_impl(IDirectDrawImpl *This)
43 {
44 return (IDirectDraw *) &This->IDirectDraw_Vtbl;
45 }
46
47 static IDirectDrawImpl *impl_from_dd2(IDirectDraw2 *iface)
48 {
49 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw2_Vtbl));
50 }
51 static IDirectDraw2 *dd2_from_impl(IDirectDrawImpl *This)
52 {
53 return (IDirectDraw2 *) &This->IDirectDraw2_Vtbl;
54 }
55
56 static IDirectDrawImpl *impl_from_dd3(IDirectDraw3 *iface)
57 {
58 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw3_Vtbl));
59 }
60 static IDirectDraw3 *dd3_from_impl(IDirectDrawImpl *This)
61 {
62 return (IDirectDraw3 *) &This->IDirectDraw3_Vtbl;
63 }
64
65 static IDirectDrawImpl *impl_from_dd4(IDirectDraw4 *iface)
66 {
67 return (IDirectDrawImpl *)((char*)iface - FIELD_OFFSET(IDirectDrawImpl, IDirectDraw4_Vtbl));
68 }
69 static IDirectDraw4 *dd4_from_impl(IDirectDrawImpl *This)
70 {
71 return (IDirectDraw4 *) &This->IDirectDraw4_Vtbl;
72 }
73
74 /******************************************************************************
75 * IDirectDraw4 -> ddraw.dll wrappers
76 ******************************************************************************/
77 static HRESULT WINAPI
78 IDirectDraw4Impl_QueryInterface(IDirectDraw4 *iface,
79 REFIID refiid,
80 void **obj)
81 {
82 IDirectDrawImpl *This = impl_from_dd4(iface);
83
84 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
85 *obj = NULL;
86
87 if(!refiid)
88 {
89 return DDERR_INVALIDPARAMS;
90 }
91
92 if (IsEqualGUID( &IID_IDirectDraw7, refiid ) )
93 {
94 WARN("IDirectDraw7 not allowed in ddrawex.dll\n");
95 return E_NOINTERFACE;
96 }
97 else if ( IsEqualGUID( &IID_IUnknown, refiid ) ||
98 IsEqualGUID( &IID_IDirectDraw4, refiid ) )
99 {
100 *obj = dd4_from_impl(This);
101 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
102 IDirectDraw4_AddRef((IDirectDraw4 *) *obj);
103 }
104 else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) )
105 {
106 *obj = dd3_from_impl(This);
107 TRACE("(%p) Returning IDirectDraw3 interface at %p\n", This, *obj);
108 IDirectDraw3_AddRef((IDirectDraw3 *) *obj);
109 }
110 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
111 {
112 *obj = dd2_from_impl(This);
113 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
114 IDirectDraw2_AddRef((IDirectDraw2 *) *obj);
115 }
116 else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
117 {
118 *obj = dd1_from_impl(This);
119 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
120 IDirectDraw_AddRef((IDirectDraw *) *obj);
121 }
122 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
123 IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
124 IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
125 IsEqualGUID( &IID_IDirect3D7 , refiid ) )
126 {
127 WARN("Direct3D not allowed in ddrawex.dll\n");
128 return E_NOINTERFACE;
129 }
130 /* Unknown interface */
131 else
132 {
133 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
134 return E_NOINTERFACE;
135 }
136 TRACE("Returning S_OK\n");
137 return S_OK;
138 }
139
140 static HRESULT WINAPI
141 IDirectDraw3Impl_QueryInterface(IDirectDraw3 *iface,
142 REFIID refiid,
143 void **obj)
144 {
145 IDirectDrawImpl *This = impl_from_dd3(iface);
146 TRACE("Thunking to IDirectDraw4\n");
147 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
148 }
149
150 static HRESULT WINAPI
151 IDirectDraw2Impl_QueryInterface(IDirectDraw2 *iface,
152 REFIID refiid,
153 void **obj)
154 {
155 IDirectDrawImpl *This = impl_from_dd2(iface);
156 TRACE("Thunking to IDirectDraw4\n");
157 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
158 }
159
160 static HRESULT WINAPI
161 IDirectDrawImpl_QueryInterface(IDirectDraw *iface,
162 REFIID refiid,
163 void **obj)
164 {
165 IDirectDrawImpl *This = impl_from_dd1(iface);
166 TRACE("Thunking to IDirectDraw4\n");
167 return IDirectDraw4_QueryInterface(dd4_from_impl(This), refiid, obj);
168 }
169
170 static ULONG WINAPI
171 IDirectDraw4Impl_AddRef(IDirectDraw4 *iface)
172 {
173 IDirectDrawImpl *This = impl_from_dd4(iface);
174 ULONG ref = InterlockedIncrement(&This->ref);
175
176 TRACE("(%p) : incrementing refcount from %u.\n", This, ref - 1);
177
178 return ref;
179 }
180
181 static ULONG WINAPI
182 IDirectDraw3Impl_AddRef(IDirectDraw3 *iface)
183 {
184 IDirectDrawImpl *This = impl_from_dd3(iface);
185 TRACE("Thunking to IDirectDraw4\n");
186 return IDirectDraw4_AddRef(dd4_from_impl(This));
187 }
188
189 static ULONG WINAPI
190 IDirectDraw2Impl_AddRef(IDirectDraw2 *iface)
191 {
192 IDirectDrawImpl *This = impl_from_dd2(iface);
193 TRACE("Thunking to IDirectDraw4\n");
194 return IDirectDraw4_AddRef(dd4_from_impl(This));
195 }
196
197 static ULONG WINAPI
198 IDirectDrawImpl_AddRef(IDirectDraw *iface)
199 {
200 IDirectDrawImpl *This = impl_from_dd1(iface);
201 TRACE("Thunking to IDirectDraw4\n");
202 return IDirectDraw4_AddRef(dd4_from_impl(This));
203 }
204
205 static ULONG WINAPI
206 IDirectDraw4Impl_Release(IDirectDraw4 *iface)
207 {
208 IDirectDrawImpl *This = impl_from_dd4(iface);
209 ULONG ref = InterlockedDecrement(&This->ref);
210
211 TRACE("(%p) : decrementing refcount to %u.\n", This, ref);
212
213 if(ref == 0)
214 {
215 TRACE("Destroying object\n");
216 IDirectDraw4_Release(This->parent);
217 HeapFree(GetProcessHeap(), 0, This);
218 }
219 return ref;
220 }
221
222 static ULONG WINAPI
223 IDirectDraw3Impl_Release(IDirectDraw3 *iface)
224 {
225 IDirectDrawImpl *This = impl_from_dd3(iface);
226 TRACE("Thunking to IDirectDraw4\n");
227 return IDirectDraw4_Release(dd4_from_impl(This));
228 }
229
230 static ULONG WINAPI
231 IDirectDraw2Impl_Release(IDirectDraw2 *iface)
232 {
233 IDirectDrawImpl *This = impl_from_dd2(iface);
234 TRACE("Thunking to IDirectDraw4\n");
235 return IDirectDraw4_Release(dd4_from_impl(This));
236 }
237
238 static ULONG WINAPI
239 IDirectDrawImpl_Release(IDirectDraw *iface)
240 {
241 IDirectDrawImpl *This = impl_from_dd1(iface);
242 TRACE("Thunking to IDirectDraw4\n");
243 return IDirectDraw4_Release(dd4_from_impl(This));
244 }
245
246 static HRESULT WINAPI
247 IDirectDraw4Impl_Compact(IDirectDraw4 *iface)
248 {
249 IDirectDrawImpl *This = impl_from_dd4(iface);
250 TRACE("(%p)\n", This);
251
252 return IDirectDraw4_Compact(This->parent);
253 }
254
255 static HRESULT WINAPI
256 IDirectDraw3Impl_Compact(IDirectDraw3 *iface)
257 {
258 IDirectDrawImpl *This = impl_from_dd3(iface);
259 TRACE("Thunking to IDirectDraw4\n");
260 return IDirectDraw4_Compact(dd4_from_impl(This));
261 }
262
263 static HRESULT WINAPI
264 IDirectDraw2Impl_Compact(IDirectDraw2 *iface)
265 {
266 IDirectDrawImpl *This = impl_from_dd2(iface);
267 TRACE("Thunking to IDirectDraw4\n");
268 return IDirectDraw4_Compact(dd4_from_impl(This));
269 }
270
271 static HRESULT WINAPI
272 IDirectDrawImpl_Compact(IDirectDraw *iface)
273 {
274 IDirectDrawImpl *This = impl_from_dd1(iface);
275 TRACE("Thunking to IDirectDraw4\n");
276 return IDirectDraw4_Compact(dd4_from_impl(This));
277 }
278
279 static HRESULT WINAPI
280 IDirectDraw4Impl_CreateClipper(IDirectDraw4 *iface,
281 DWORD Flags,
282 IDirectDrawClipper **clipper,
283 IUnknown *UnkOuter)
284 {
285 IDirectDrawImpl *This = impl_from_dd4(iface);
286 TRACE("(%p)->(0x%08x, %p, %p)\n", This, Flags, clipper, UnkOuter);
287
288 if(UnkOuter != NULL)
289 {
290 /* This may require a wrapper interface for clippers too which handles this */
291 FIXME("Test and implement Aggregation for ddrawex clippers\n");
292 }
293
294 return IDirectDraw4_CreateClipper(This->parent, Flags, clipper, UnkOuter);
295 }
296
297 static HRESULT WINAPI
298 IDirectDraw3Impl_CreateClipper(IDirectDraw3 *iface,
299 DWORD Flags,
300 IDirectDrawClipper **clipper,
301 IUnknown *UnkOuter)
302 {
303 IDirectDrawImpl *This = impl_from_dd3(iface);
304 TRACE("Thunking to IDirectDraw4\n");
305 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
306 }
307
308 static HRESULT WINAPI
309 IDirectDraw2Impl_CreateClipper(IDirectDraw2 *iface,
310 DWORD Flags,
311 IDirectDrawClipper **clipper,
312 IUnknown *UnkOuter)
313 {
314 IDirectDrawImpl *This = impl_from_dd2(iface);
315 TRACE("Thunking to IDirectDraw4\n");
316 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
317 }
318
319 static HRESULT WINAPI
320 IDirectDrawImpl_CreateClipper(IDirectDraw *iface,
321 DWORD Flags,
322 IDirectDrawClipper **clipper,
323 IUnknown *UnkOuter)
324 {
325 IDirectDrawImpl *This = impl_from_dd1(iface);
326 TRACE("Thunking to IDirectDraw4\n");
327 return IDirectDraw4_CreateClipper(dd4_from_impl(This), Flags, clipper, UnkOuter);
328 }
329
330 static HRESULT WINAPI
331 IDirectDraw4Impl_CreatePalette(IDirectDraw4 *iface,
332 DWORD Flags,
333 PALETTEENTRY *ColorTable,
334 IDirectDrawPalette **Palette,
335 IUnknown *UnkOuter)
336 {
337 IDirectDrawImpl *This = impl_from_dd4(iface);
338 TRACE("(%p)(0x%08x,%p,%p,%p)\n", This, Flags, ColorTable, Palette, UnkOuter);
339
340 if(UnkOuter != NULL)
341 {
342 /* This may require a wrapper interface for palettes too which handles this */
343 FIXME("Test and implement Aggregation for ddrawex palettes\n");
344 }
345
346 return IDirectDraw4_CreatePalette(This->parent, Flags, ColorTable, Palette, UnkOuter);
347 }
348
349 static HRESULT WINAPI
350 IDirectDraw3Impl_CreatePalette(IDirectDraw3 *iface,
351 DWORD Flags,
352 PALETTEENTRY *ColorTable,
353 IDirectDrawPalette **Palette,
354 IUnknown *UnkOuter)
355 {
356 IDirectDrawImpl *This = impl_from_dd3(iface);
357 TRACE("Thunking to IDirectDraw4\n");
358 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
359 }
360
361 static HRESULT WINAPI
362 IDirectDraw2Impl_CreatePalette(IDirectDraw2 *iface,
363 DWORD Flags,
364 PALETTEENTRY *ColorTable,
365 IDirectDrawPalette **Palette,
366 IUnknown *UnkOuter)
367 {
368 IDirectDrawImpl *This = impl_from_dd2(iface);
369 TRACE("Thunking to IDirectDraw4\n");
370 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
371 }
372
373 static HRESULT WINAPI
374 IDirectDrawImpl_CreatePalette(IDirectDraw *iface,
375 DWORD Flags,
376 PALETTEENTRY *ColorTable,
377 IDirectDrawPalette **Palette,
378 IUnknown *UnkOuter)
379 {
380 IDirectDrawImpl *This = impl_from_dd1(iface);
381 TRACE("Thunking to IDirectDraw4\n");
382 return IDirectDraw4_CreatePalette(dd4_from_impl(This), Flags, ColorTable, Palette, UnkOuter);
383 }
384
385 static HRESULT WINAPI
386 IDirectDraw4Impl_CreateSurface(IDirectDraw4 *iface,
387 DDSURFACEDESC2 *DDSD,
388 IDirectDrawSurface4 **Surf,
389 IUnknown *UnkOuter)
390 {
391 IDirectDrawImpl *This = impl_from_dd4(iface);
392 HRESULT hr;
393 const DWORD perm_dc_flags = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
394 BOOL permanent_dc;
395 TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter);
396
397 if(UnkOuter != NULL)
398 {
399 /* Handle this in this dll. Don't forward the UnkOuter to ddraw.dll */
400 FIXME("Implement aggregation for ddrawex surfaces\n");
401 }
402
403 /* plain ddraw.dll refuses to create a surface that has both VIDMEM and SYSMEM flags
404 * set. In ddrawex this succeeds, and the GetDC() call changes the behavior. The DC
405 * is permanently valid, and the surface can be locked between GetDC() and ReleaseDC()
406 * calls. GetDC() can be called more than once too
407 */
408 if((DDSD->ddsCaps.dwCaps & perm_dc_flags) == perm_dc_flags)
409 {
410 permanent_dc = TRUE;
411 DDSD->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
412 DDSD->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
413 }
414 else
415 {
416 permanent_dc = FALSE;
417 }
418
419 hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter);
420 *Surf = dds_get_outer(*Surf);
421 if(permanent_dc) prepare_permanent_dc(*Surf);
422 return hr;
423 }
424
425 void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
426 {
427 memset(out, 0, sizeof(*out));
428 out->dwSize = sizeof(*out);
429 out->dwFlags = in->dwFlags;
430 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
431 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
432 if(in->dwFlags & DDSD_PIXELFORMAT) out->u4.ddpfPixelFormat = in->ddpfPixelFormat;
433 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
434 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
435 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
436 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwMipMapCount = in->u2.dwZBufferBitDepth; /* same union */
437 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
438 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
439 out->lpSurface = in->lpSurface;
440 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->u3.ddckCKDestOverlay = in->ddckCKDestOverlay;
441 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
442 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
443 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
444 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
445 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
446 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
447 /* Does not exist in DDSURFACEDESC:
448 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
449 */
450 }
451
452 void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
453 {
454 memset(out, 0, sizeof(*out));
455 out->dwSize = sizeof(*out);
456 out->dwFlags = in->dwFlags;
457 if(in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
458 if(in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
459 if(in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->u4.ddpfPixelFormat;
460 if(in->dwFlags & DDSD_CAPS) out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
461 if(in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
462 if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
463 if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwZBufferBitDepth = in->u2.dwMipMapCount; /* same union */
464 if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
465 /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
466 out->lpSurface = in->lpSurface;
467 if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->u3.ddckCKDestOverlay;
468 if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
469 if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
470 if(in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt;
471 if(in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount;
472 if(in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate;
473 if(in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize;
474 /* Does not exist in DDSURFACEDESC:
475 * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE,
476 */
477 if(in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n");
478 if(in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n");
479 if(in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n");
480 out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE);
481 }
482
483 static HRESULT WINAPI
484 IDirectDraw3Impl_CreateSurface(IDirectDraw3 *iface,
485 DDSURFACEDESC *DDSD,
486 IDirectDrawSurface **Surf,
487 IUnknown *UnkOuter)
488 {
489 IDirectDrawImpl *This = impl_from_dd3(iface);
490 DDSURFACEDESC2 ddsd2;
491 IDirectDrawSurface4 *surf4 = NULL;
492 HRESULT hr;
493 TRACE("Thunking to IDirectDraw4\n");
494
495 DDSD_to_DDSD2(DDSD, &ddsd2);
496
497 hr = IDirectDraw4_CreateSurface(dd4_from_impl(This), &ddsd2, &surf4, UnkOuter);
498 if(FAILED(hr))
499 {
500 *Surf = NULL;
501 return hr;
502 }
503
504 TRACE("Got surface %p\n", surf4);
505 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf);
506 IDirectDrawSurface4_Release(surf4);
507 return hr;
508 }
509
510 static HRESULT WINAPI
511 IDirectDraw2Impl_CreateSurface(IDirectDraw2 *iface,
512 DDSURFACEDESC *DDSD,
513 IDirectDrawSurface **Surf,
514 IUnknown *UnkOuter)
515 {
516 IDirectDrawImpl *This = impl_from_dd2(iface);
517 TRACE("Thunking to IDirectDraw3\n");
518 return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter);
519 }
520
521 static HRESULT WINAPI
522 IDirectDrawImpl_CreateSurface(IDirectDraw *iface,
523 DDSURFACEDESC *DDSD,
524 IDirectDrawSurface **Surf,
525 IUnknown *UnkOuter)
526 {
527 IDirectDrawImpl *This = impl_from_dd1(iface);
528 TRACE("Thunking to IDirectDraw3\n");
529 return IDirectDraw3_CreateSurface(dd3_from_impl(This), DDSD, Surf, UnkOuter);
530 }
531
532 static HRESULT WINAPI
533 IDirectDraw4Impl_DuplicateSurface(IDirectDraw4 *iface,
534 IDirectDrawSurface4 *src,
535 IDirectDrawSurface4 **dst)
536 {
537 IDirectDrawImpl *This = impl_from_dd4(iface);
538 FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst);
539
540 return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(src), dst);
541 }
542
543 static HRESULT WINAPI
544 IDirectDraw3Impl_DuplicateSurface(IDirectDraw3 *iface,
545 IDirectDrawSurface *src,
546 IDirectDrawSurface **dst)
547 {
548 IDirectDrawImpl *This = impl_from_dd3(iface);
549 IDirectDrawSurface4 *src_4;
550 IDirectDrawSurface4 *dst_4;
551 HRESULT hr;
552
553 TRACE("Thunking to IDirectDraw4\n");
554 IDirectDrawSurface_QueryInterface(src, &IID_IDirectDrawSurface4, (void **) &src_4);
555 hr = IDirectDraw4_DuplicateSurface(dd4_from_impl(This), src_4, &dst_4);
556 IDirectDrawSurface4_Release(src_4);
557
558 if(FAILED(hr))
559 {
560 *dst = NULL;
561 return hr;
562 }
563 IDirectDrawSurface4_QueryInterface(dst_4, &IID_IDirectDrawSurface, (void **) dst);
564 IDirectDrawSurface4_Release(dst_4);
565 return hr;
566 }
567
568 static HRESULT WINAPI
569 IDirectDraw2Impl_DuplicateSurface(IDirectDraw2 *iface,
570 IDirectDrawSurface *src,
571 IDirectDrawSurface **dst)
572 {
573 IDirectDrawImpl *This = impl_from_dd2(iface);
574 TRACE("Thunking to IDirectDraw3\n");
575 return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst);
576 }
577
578 static HRESULT WINAPI
579 IDirectDrawImpl_DuplicateSurface(IDirectDraw *iface,
580 IDirectDrawSurface *src,
581 IDirectDrawSurface **dst)
582 {
583 IDirectDrawImpl *This = impl_from_dd1(iface);
584 TRACE("Thunking to IDirectDraw3\n");
585 return IDirectDraw3_DuplicateSurface(dd3_from_impl(This), src, dst);
586 }
587
588 static HRESULT WINAPI
589 IDirectDraw4Impl_EnumDisplayModes(IDirectDraw4 *iface,
590 DWORD Flags,
591 DDSURFACEDESC2 *DDSD,
592 void *Context,
593 LPDDENUMMODESCALLBACK2 cb)
594 {
595 IDirectDrawImpl *This = impl_from_dd4(iface);
596 TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, cb);
597
598 return IDirectDraw4_EnumDisplayModes(This->parent, Flags, DDSD, Context, cb);
599 }
600
601 struct enummodes_ctx
602 {
603 LPDDENUMMODESCALLBACK orig_cb;
604 void *orig_ctx;
605 };
606
607 static HRESULT WINAPI
608 enum_modes_cb2(DDSURFACEDESC2 *ddsd2, void *vctx)
609 {
610 struct enummodes_ctx *ctx = vctx;
611 DDSURFACEDESC ddsd;
612
613 DDSD2_to_DDSD(ddsd2, &ddsd);
614 return ctx->orig_cb(&ddsd, ctx->orig_ctx);
615 }
616
617 static HRESULT WINAPI
618 IDirectDraw3Impl_EnumDisplayModes(IDirectDraw3 *iface,
619 DWORD Flags,
620 DDSURFACEDESC *DDSD,
621 void *Context,
622 LPDDENUMMODESCALLBACK cb)
623 {
624 IDirectDrawImpl *This = impl_from_dd3(iface);
625 DDSURFACEDESC2 ddsd2;
626 struct enummodes_ctx ctx;
627 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, cb);
628
629 DDSD_to_DDSD2(DDSD, &ddsd2);
630 ctx.orig_cb = cb;
631 ctx.orig_ctx = Context;
632 return IDirectDraw4_EnumDisplayModes(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_modes_cb2);
633 }
634
635 static HRESULT WINAPI
636 IDirectDraw2Impl_EnumDisplayModes(IDirectDraw2 *iface,
637 DWORD Flags,
638 DDSURFACEDESC *DDSD,
639 void *Context,
640 LPDDENUMMODESCALLBACK cb)
641 {
642 IDirectDrawImpl *This = impl_from_dd2(iface);
643 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
644 return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb);
645 }
646
647 static HRESULT WINAPI
648 IDirectDrawImpl_EnumDisplayModes(IDirectDraw *iface,
649 DWORD Flags,
650 DDSURFACEDESC *DDSD,
651 void *Context,
652 LPDDENUMMODESCALLBACK cb)
653 {
654 IDirectDrawImpl *This = impl_from_dd1(iface);
655 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, cb);
656 return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb);
657 }
658
659 struct enumsurfaces4_ctx
660 {
661 LPDDENUMSURFACESCALLBACK2 orig_cb;
662 void *orig_ctx;
663 };
664
665 static HRESULT WINAPI
666 enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
667 {
668 struct enumsurfaces4_ctx *ctx = vctx;
669 IDirectDrawSurface4 *outer = dds_get_outer(surf4);
670 IDirectDrawSurface4_AddRef(outer);
671 IDirectDrawSurface4_Release(surf4);
672 TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4);
673 return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx);
674 }
675
676 static HRESULT WINAPI
677 IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface,
678 DWORD Flags,
679 DDSURFACEDESC2 *DDSD,
680 void *Context,
681 LPDDENUMSURFACESCALLBACK2 Callback)
682 {
683 IDirectDrawImpl *This = impl_from_dd4(iface);
684 struct enumsurfaces4_ctx ctx;
685 TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback);
686
687 ctx.orig_cb = Callback;
688 ctx.orig_ctx = Context;
689 return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, &ctx, enum_surfaces_wrapper);
690 }
691
692 struct enumsurfaces_ctx
693 {
694 LPDDENUMSURFACESCALLBACK orig_cb;
695 void *orig_ctx;
696 };
697
698 static HRESULT WINAPI
699 enum_surfaces_cb2(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
700 {
701 struct enumsurfaces_ctx *ctx = vctx;
702 IDirectDrawSurface *surf1;
703 DDSURFACEDESC ddsd;
704
705 /* Keep the reference, it goes to the application */
706 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) &surf1);
707 /* Release the reference this function got */
708 IDirectDrawSurface4_Release(surf4);
709
710 DDSD2_to_DDSD(ddsd2, &ddsd);
711 return ctx->orig_cb(surf1, &ddsd, ctx->orig_ctx);
712 }
713
714 static HRESULT WINAPI
715 IDirectDraw3Impl_EnumSurfaces(IDirectDraw3 *iface,
716 DWORD Flags,
717 DDSURFACEDESC *DDSD,
718 void *Context,
719 LPDDENUMSURFACESCALLBACK Callback)
720 {
721 IDirectDrawImpl *This = impl_from_dd3(iface);
722 DDSURFACEDESC2 ddsd2;
723 struct enumsurfaces_ctx ctx;
724 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw4\n", This, Flags, DDSD, Context, Callback);
725
726 DDSD_to_DDSD2(DDSD, &ddsd2);
727 ctx.orig_cb = Callback;
728 ctx.orig_ctx = Context;
729 return IDirectDraw4_EnumSurfaces(dd4_from_impl(This), Flags, &ddsd2, &ctx, enum_surfaces_cb2);
730 }
731
732 static HRESULT WINAPI
733 IDirectDraw2Impl_EnumSurfaces(IDirectDraw2 *iface,
734 DWORD Flags,
735 DDSURFACEDESC *DDSD,
736 void *Context,
737 LPDDENUMSURFACESCALLBACK Callback)
738 {
739 IDirectDrawImpl *This = impl_from_dd2(iface);
740 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
741 return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback);
742 }
743
744 static HRESULT WINAPI
745 IDirectDrawImpl_EnumSurfaces(IDirectDraw *iface,
746 DWORD Flags,
747 DDSURFACEDESC *DDSD,
748 void *Context,
749 LPDDENUMSURFACESCALLBACK Callback)
750 {
751 IDirectDrawImpl *This = impl_from_dd1(iface);
752 TRACE("(%p)->(0x%08x,%p,%p,%p): Thunking to IDirectDraw3\n", This, Flags, DDSD, Context, Callback);
753 return IDirectDraw3_EnumSurfaces(dd3_from_impl(This), Flags, DDSD, Context, Callback);
754 }
755
756 static HRESULT WINAPI
757 IDirectDraw4Impl_FlipToGDISurface(IDirectDraw4 *iface)
758 {
759 IDirectDrawImpl *This = impl_from_dd4(iface);
760 TRACE("(%p)\n", This);
761
762 return IDirectDraw4_FlipToGDISurface(This->parent);
763 }
764
765 static HRESULT WINAPI
766 IDirectDraw3Impl_FlipToGDISurface(IDirectDraw3 *iface)
767 {
768 IDirectDrawImpl *This = impl_from_dd3(iface);
769 TRACE("(%p). Thunking to IDirectDraw4\n", This);
770 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
771 }
772
773 static HRESULT WINAPI
774 IDirectDraw2Impl_FlipToGDISurface(IDirectDraw2 *iface)
775 {
776 IDirectDrawImpl *This = impl_from_dd2(iface);
777 TRACE("(%p). Thunking to IDirectDraw4\n", This);
778 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
779 }
780
781 static HRESULT WINAPI
782 IDirectDrawImpl_FlipToGDISurface(IDirectDraw *iface)
783 {
784 IDirectDrawImpl *This = impl_from_dd1(iface);
785 TRACE("(%p). Thunking to IDirectDraw4\n", This);
786 return IDirectDraw4_FlipToGDISurface(dd4_from_impl(This));
787 }
788
789 static HRESULT WINAPI
790 IDirectDraw4Impl_GetCaps(IDirectDraw4 *iface,
791 DDCAPS *DriverCaps,
792 DDCAPS *HELCaps)
793 {
794 IDirectDrawImpl *This = impl_from_dd4(iface);
795 TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps);
796 return IDirectDraw4_GetCaps(This->parent, DriverCaps, HELCaps);
797 }
798
799 static HRESULT WINAPI
800 IDirectDraw3Impl_GetCaps(IDirectDraw3 *iface,
801 DDCAPS *DriverCaps,
802 DDCAPS *HELCaps)
803 {
804 IDirectDrawImpl *This = impl_from_dd3(iface);
805 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
806 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
807 }
808
809 static HRESULT WINAPI
810 IDirectDraw2Impl_GetCaps(IDirectDraw2 *iface,
811 DDCAPS *DriverCaps,
812 DDCAPS *HELCaps)
813 {
814 IDirectDrawImpl *This = impl_from_dd2(iface);
815 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
816 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
817 }
818
819 static HRESULT WINAPI
820 IDirectDrawImpl_GetCaps(IDirectDraw *iface,
821 DDCAPS *DriverCaps,
822 DDCAPS *HELCaps)
823 {
824 IDirectDrawImpl *This = impl_from_dd1(iface);
825 TRACE("(%p)->(%p,%p). Thunking to IDirectDraw4\n", This, DriverCaps, HELCaps);
826 return IDirectDraw4_GetCaps(dd4_from_impl(This), DriverCaps, HELCaps);
827 }
828
829 static HRESULT WINAPI
830 IDirectDraw4Impl_GetDisplayMode(IDirectDraw4 *iface,
831 DDSURFACEDESC2 *DDSD)
832 {
833 IDirectDrawImpl *This = impl_from_dd4(iface);
834 TRACE("(%p)->(%p)\n", This, DDSD);
835 return IDirectDraw4_GetDisplayMode(This->parent, DDSD);
836 }
837
838 static HRESULT WINAPI
839 IDirectDraw3Impl_GetDisplayMode(IDirectDraw3 *iface,
840 DDSURFACEDESC *DDSD)
841 {
842 IDirectDrawImpl *This = impl_from_dd3(iface);
843 DDSURFACEDESC2 ddsd2;
844 HRESULT hr;
845
846 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, DDSD);
847 hr = IDirectDraw4_GetDisplayMode(dd4_from_impl(This), &ddsd2);
848 DDSD2_to_DDSD(&ddsd2, DDSD);
849 return hr;
850 }
851
852 static HRESULT WINAPI
853 IDirectDraw2Impl_GetDisplayMode(IDirectDraw2 *iface,
854 DDSURFACEDESC *DDSD)
855 {
856 IDirectDrawImpl *This = impl_from_dd2(iface);
857 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
858 return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD);
859 }
860
861 static HRESULT WINAPI
862 IDirectDrawImpl_GetDisplayMode(IDirectDraw *iface,
863 DDSURFACEDESC *DDSD)
864 {
865 IDirectDrawImpl *This = impl_from_dd1(iface);
866 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, DDSD);
867 return IDirectDraw3_GetDisplayMode(dd3_from_impl(This), DDSD);
868 }
869
870 static HRESULT WINAPI
871 IDirectDraw4Impl_GetFourCCCodes(IDirectDraw4 *iface,
872 DWORD *NumCodes,
873 DWORD *Codes)
874 {
875 IDirectDrawImpl *This = impl_from_dd4(iface);
876 TRACE("(%p)->(%p, %p):\n", This, NumCodes, Codes);
877 return IDirectDraw4_GetFourCCCodes(This->parent, NumCodes, Codes);
878 }
879
880 static HRESULT WINAPI
881 IDirectDraw3Impl_GetFourCCCodes(IDirectDraw3 *iface,
882 DWORD *NumCodes,
883 DWORD *Codes)
884 {
885 IDirectDrawImpl *This = impl_from_dd3(iface);
886 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
887 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
888 }
889
890 static HRESULT WINAPI
891 IDirectDraw2Impl_GetFourCCCodes(IDirectDraw2 *iface,
892 DWORD *NumCodes,
893 DWORD *Codes)
894 {
895 IDirectDrawImpl *This = impl_from_dd2(iface);
896 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
897 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
898 }
899
900 static HRESULT WINAPI
901 IDirectDrawImpl_GetFourCCCodes(IDirectDraw *iface,
902 DWORD *NumCodes,
903 DWORD *Codes)
904 {
905 IDirectDrawImpl *This = impl_from_dd1(iface);
906 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, NumCodes, Codes);
907 return IDirectDraw4_GetFourCCCodes(dd4_from_impl(This), NumCodes, Codes);
908 }
909
910 static HRESULT WINAPI
911 IDirectDraw4Impl_GetGDISurface(IDirectDraw4 *iface,
912 IDirectDrawSurface4 **GDISurface)
913 {
914 IDirectDrawImpl *This = impl_from_dd4(iface);
915 IDirectDrawSurface4 *inner = NULL;
916 HRESULT hr;
917 TRACE("(%p)->(%p)\n", This, GDISurface);
918
919 hr = IDirectDraw4_GetGDISurface(This->parent, &inner);
920 if(SUCCEEDED(hr))
921 {
922 *GDISurface = dds_get_outer(inner);
923 IDirectDrawSurface4_AddRef(*GDISurface);
924 IDirectDrawSurface4_Release(inner);
925 }
926 else
927 {
928 *GDISurface = NULL;
929 }
930 return hr;
931 }
932
933 static HRESULT WINAPI
934 IDirectDraw3Impl_GetGDISurface(IDirectDraw3 *iface,
935 IDirectDrawSurface **GDISurface)
936 {
937 IDirectDrawImpl *This = impl_from_dd3(iface);
938 IDirectDrawSurface4 *surf4;
939 HRESULT hr;
940 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, GDISurface);
941
942 hr = IDirectDraw4_GetGDISurface(dd4_from_impl(This), &surf4);
943 if(FAILED(hr)) {
944 *GDISurface = NULL;
945 return hr;
946 }
947
948 /* Release the reference we got from the DDraw4 call, and pass a reference to the caller */
949 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) GDISurface);
950 IDirectDrawSurface4_Release(surf4);
951 return hr;
952 }
953
954 static HRESULT WINAPI
955 IDirectDraw2Impl_GetGDISurface(IDirectDraw2 *iface,
956 IDirectDrawSurface **GDISurface)
957 {
958 IDirectDrawImpl *This = impl_from_dd2(iface);
959 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
960 return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface);
961 }
962
963 static HRESULT WINAPI
964 IDirectDrawImpl_GetGDISurface(IDirectDraw *iface,
965 IDirectDrawSurface **GDISurface)
966 {
967 IDirectDrawImpl *This = impl_from_dd1(iface);
968 TRACE("(%p)->(%p): Thunking to IDirectDraw3\n", This, GDISurface);
969 return IDirectDraw3_GetGDISurface(dd3_from_impl(This), GDISurface);
970 }
971
972 static HRESULT WINAPI
973 IDirectDraw4Impl_GetMonitorFrequency(IDirectDraw4 *iface,
974 DWORD *Freq)
975 {
976 IDirectDrawImpl *This = impl_from_dd4(iface);
977 TRACE("(%p)->(%p)\n", This, Freq);
978 return IDirectDraw4_GetMonitorFrequency(This->parent, Freq);
979 }
980
981 static HRESULT WINAPI
982 IDirectDraw3Impl_GetMonitorFrequency(IDirectDraw3 *iface,
983 DWORD *Freq)
984 {
985 IDirectDrawImpl *This = impl_from_dd3(iface);
986 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
987 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
988 }
989
990 static HRESULT WINAPI
991 IDirectDraw2Impl_GetMonitorFrequency(IDirectDraw2 *iface,
992 DWORD *Freq)
993 {
994 IDirectDrawImpl *This = impl_from_dd2(iface);
995 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
996 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
997 }
998
999 static HRESULT WINAPI
1000 IDirectDrawImpl_GetMonitorFrequency(IDirectDraw *iface,
1001 DWORD *Freq)
1002 {
1003 IDirectDrawImpl *This = impl_from_dd1(iface);
1004 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Freq);
1005 return IDirectDraw4_GetMonitorFrequency(dd4_from_impl(This), Freq);
1006 }
1007
1008 static HRESULT WINAPI
1009 IDirectDraw4Impl_GetScanLine(IDirectDraw4 *iface,
1010 DWORD *Scanline)
1011 {
1012 IDirectDrawImpl *This = impl_from_dd4(iface);
1013 TRACE("(%p)->(%p)\n", This, Scanline);
1014 return IDirectDraw4_GetScanLine(This->parent, Scanline);
1015 }
1016
1017 static HRESULT WINAPI
1018 IDirectDraw3Impl_GetScanLine(IDirectDraw3 *iface,
1019 DWORD *Scanline)
1020 {
1021 IDirectDrawImpl *This = impl_from_dd3(iface);
1022 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
1023 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
1024 }
1025
1026 static HRESULT WINAPI
1027 IDirectDraw2Impl_GetScanLine(IDirectDraw2 *iface,
1028 DWORD *Scanline)
1029 {
1030 IDirectDrawImpl *This = impl_from_dd2(iface);
1031 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
1032 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
1033 }
1034
1035 static HRESULT WINAPI
1036 IDirectDrawImpl_GetScanLine(IDirectDraw *iface,
1037 DWORD *Scanline)
1038 {
1039 IDirectDrawImpl *This = impl_from_dd1(iface);
1040 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, Scanline);
1041 return IDirectDraw4_GetScanLine(dd4_from_impl(This), Scanline);
1042 }
1043
1044 static HRESULT WINAPI
1045 IDirectDraw4Impl_GetVerticalBlankStatus(IDirectDraw4 *iface,
1046 BOOL *status)
1047 {
1048 IDirectDrawImpl *This = impl_from_dd4(iface);
1049 TRACE("(%p)->(%p)\n", This, status);
1050 return IDirectDraw4_GetVerticalBlankStatus(This->parent, status);
1051 }
1052
1053 static HRESULT WINAPI
1054 IDirectDraw3Impl_GetVerticalBlankStatus(IDirectDraw3 *iface,
1055 BOOL *status)
1056 {
1057 IDirectDrawImpl *This = impl_from_dd3(iface);
1058 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
1059 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
1060 }
1061
1062 static HRESULT WINAPI
1063 IDirectDraw2Impl_GetVerticalBlankStatus(IDirectDraw2 *iface,
1064 BOOL *status)
1065 {
1066 IDirectDrawImpl *This = impl_from_dd2(iface);
1067 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
1068 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
1069 }
1070
1071 static HRESULT WINAPI
1072 IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw *iface,
1073 BOOL *status)
1074 {
1075 IDirectDrawImpl *This = impl_from_dd1(iface);
1076 TRACE("(%p)->(%p): Thunking to IDirectDraw4\n", This, status);
1077 return IDirectDraw4_GetVerticalBlankStatus(dd4_from_impl(This), status);
1078 }
1079
1080 static HRESULT WINAPI
1081 IDirectDraw4Impl_Initialize(IDirectDraw4 *iface,
1082 GUID *Guid)
1083 {
1084 IDirectDrawImpl *This = impl_from_dd4(iface);
1085 TRACE("(%p)->(%s)\n", This, debugstr_guid(Guid));
1086 return IDirectDraw4_Initialize(This->parent, Guid);
1087 }
1088
1089 static HRESULT WINAPI
1090 IDirectDraw3Impl_Initialize(IDirectDraw3 *iface,
1091 GUID *Guid)
1092 {
1093 IDirectDrawImpl *This = impl_from_dd3(iface);
1094 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
1095 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
1096 }
1097
1098 static HRESULT WINAPI
1099 IDirectDraw2Impl_Initialize(IDirectDraw2 *iface,
1100 GUID *Guid)
1101 {
1102 IDirectDrawImpl *This = impl_from_dd2(iface);
1103 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
1104 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
1105 }
1106
1107 static HRESULT WINAPI
1108 IDirectDrawImpl_Initialize(IDirectDraw *iface,
1109 GUID *Guid)
1110 {
1111 IDirectDrawImpl *This = impl_from_dd1(iface);
1112 TRACE("(%p)->(%s): Thunking to IDirectDraw4\n", This, debugstr_guid(Guid));
1113 return IDirectDraw4_Initialize(dd4_from_impl(This), Guid);
1114 }
1115
1116 static HRESULT WINAPI
1117 IDirectDraw4Impl_RestoreDisplayMode(IDirectDraw4 *iface)
1118 {
1119 IDirectDrawImpl *This = impl_from_dd4(iface);
1120 TRACE("(%p)\n", This);
1121 return IDirectDraw4_RestoreDisplayMode(This->parent);
1122 }
1123
1124 static HRESULT WINAPI
1125 IDirectDraw3Impl_RestoreDisplayMode(IDirectDraw3 *iface)
1126 {
1127 IDirectDrawImpl *This = impl_from_dd3(iface);
1128 TRACE("(%p): Thunking to IDirectDraw4\n", This);
1129 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
1130 }
1131
1132 static HRESULT WINAPI
1133 IDirectDraw2Impl_RestoreDisplayMode(IDirectDraw2 *iface)
1134 {
1135 IDirectDrawImpl *This = impl_from_dd2(iface);
1136 TRACE("(%p): Thunking to IDirectDraw4\n", This);
1137 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
1138 }
1139
1140 static HRESULT WINAPI
1141 IDirectDrawImpl_RestoreDisplayMode(IDirectDraw *iface)
1142 {
1143 IDirectDrawImpl *This = impl_from_dd1(iface);
1144 TRACE("(%p): Thunking to IDirectDraw4\n", This);
1145 return IDirectDraw4_RestoreDisplayMode(dd4_from_impl(This));
1146 }
1147
1148 static HRESULT WINAPI
1149 IDirectDraw4Impl_SetCooperativeLevel(IDirectDraw4 *iface,
1150 HWND hwnd,
1151 DWORD cooplevel)
1152 {
1153 IDirectDrawImpl *This = impl_from_dd4(iface);
1154 TRACE("(%p)->(%p, 0x%08x)\n", This, hwnd, cooplevel);
1155 return IDirectDraw4_SetCooperativeLevel(This->parent, hwnd, cooplevel);
1156 }
1157
1158 static HRESULT WINAPI
1159 IDirectDraw3Impl_SetCooperativeLevel(IDirectDraw3 *iface,
1160 HWND hwnd,
1161 DWORD cooplevel)
1162 {
1163 IDirectDrawImpl *This = impl_from_dd3(iface);
1164 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
1165 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
1166 }
1167
1168 static HRESULT WINAPI
1169 IDirectDraw2Impl_SetCooperativeLevel(IDirectDraw2 *iface,
1170 HWND hwnd,
1171 DWORD cooplevel)
1172 {
1173 IDirectDrawImpl *This = impl_from_dd2(iface);
1174 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
1175 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
1176 }
1177
1178 static HRESULT WINAPI
1179 IDirectDrawImpl_SetCooperativeLevel(IDirectDraw *iface,
1180 HWND hwnd,
1181 DWORD cooplevel)
1182 {
1183 IDirectDrawImpl *This = impl_from_dd1(iface);
1184 TRACE("(%p)->(%p, 0x%08x): Thunking to IDirectDraw4\n", This, hwnd, cooplevel);
1185 return IDirectDraw4_SetCooperativeLevel(dd4_from_impl(This), hwnd, cooplevel);
1186 }
1187
1188 static HRESULT WINAPI
1189 IDirectDraw4Impl_SetDisplayMode(IDirectDraw4 *iface,
1190 DWORD Width,
1191 DWORD Height,
1192 DWORD BPP,
1193 DWORD RefreshRate,
1194 DWORD Flags)
1195 {
1196 IDirectDrawImpl *This = impl_from_dd4(iface);
1197 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x)\n", This, Width, Height, BPP, RefreshRate, Flags);
1198 return IDirectDraw4_SetDisplayMode(This->parent, Width, Height, BPP, RefreshRate, Flags);
1199 }
1200
1201 static HRESULT WINAPI
1202 IDirectDraw3Impl_SetDisplayMode(IDirectDraw3 *iface,
1203 DWORD Width,
1204 DWORD Height,
1205 DWORD BPP,
1206 DWORD RefreshRate,
1207 DWORD Flags)
1208 {
1209 IDirectDrawImpl *This = impl_from_dd3(iface);
1210 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1211 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
1212 }
1213
1214 static HRESULT WINAPI
1215 IDirectDraw2Impl_SetDisplayMode(IDirectDraw2 *iface,
1216 DWORD Width,
1217 DWORD Height,
1218 DWORD BPP,
1219 DWORD RefreshRate,
1220 DWORD Flags)
1221 {
1222 IDirectDrawImpl *This = impl_from_dd2(iface);
1223 TRACE("(%p)->(%u, %u, %u, %u, 0x%08x): Thunking to IDirectDraw4\n", This, Width, Height, BPP, RefreshRate, Flags);
1224 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, RefreshRate, Flags);
1225 }
1226
1227 static HRESULT WINAPI
1228 IDirectDrawImpl_SetDisplayMode(IDirectDraw *iface,
1229 DWORD Width,
1230 DWORD Height,
1231 DWORD BPP)
1232 {
1233 IDirectDrawImpl *This = impl_from_dd1(iface);
1234 TRACE("(%p)->(%u, %u, %u): Thunking to IDirectDraw4\n", This, Width, Height, BPP);
1235 return IDirectDraw3_SetDisplayMode(dd4_from_impl(This), Width, Height, BPP, 0, 0);
1236 }
1237
1238 static HRESULT WINAPI
1239 IDirectDraw4Impl_WaitForVerticalBlank(IDirectDraw4 *iface,
1240 DWORD Flags,
1241 HANDLE h)
1242 {
1243 IDirectDrawImpl *This = impl_from_dd4(iface);
1244 TRACE("(%p)->(0x%08x, %p)\n", This, Flags, h);
1245 return IDirectDraw4_WaitForVerticalBlank(This->parent, Flags, h);
1246 }
1247
1248 static HRESULT WINAPI
1249 IDirectDraw3Impl_WaitForVerticalBlank(IDirectDraw3 *iface,
1250 DWORD Flags,
1251 HANDLE h)
1252 {
1253 IDirectDrawImpl *This = impl_from_dd3(iface);
1254 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1255 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1256 }
1257
1258 static HRESULT WINAPI
1259 IDirectDraw2Impl_WaitForVerticalBlank(IDirectDraw2 *iface,
1260 DWORD Flags,
1261 HANDLE h)
1262 {
1263 IDirectDrawImpl *This = impl_from_dd2(iface);
1264 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1265 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1266 }
1267
1268 static HRESULT WINAPI
1269 IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw *iface,
1270 DWORD Flags,
1271 HANDLE h)
1272 {
1273 IDirectDrawImpl *This = impl_from_dd1(iface);
1274 TRACE("(%p)->(0x%08x, %p): Thunking to IDirectDraw4\n", This, Flags, h);
1275 return IDirectDraw4_WaitForVerticalBlank(dd4_from_impl(This), Flags, h);
1276 }
1277
1278 static HRESULT WINAPI
1279 IDirectDraw4Impl_GetAvailableVidMem(IDirectDraw4 *iface,
1280 DDSCAPS2 *Caps,
1281 DWORD *total,
1282 DWORD *free)
1283 {
1284 IDirectDrawImpl *This = impl_from_dd4(iface);
1285 TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
1286 return IDirectDraw4_GetAvailableVidMem(This->parent, Caps, total, free);
1287 }
1288
1289 static HRESULT WINAPI
1290 IDirectDraw3Impl_GetAvailableVidMem(IDirectDraw3 *iface,
1291 DDSCAPS *Caps,
1292 DWORD *total,
1293 DWORD *free)
1294 {
1295 IDirectDrawImpl *This = impl_from_dd3(iface);
1296 DDSCAPS2 caps2;
1297 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1298 memset(&caps2, 0, sizeof(caps2));
1299 caps2.dwCaps = Caps->dwCaps;
1300 return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
1301 }
1302
1303 static HRESULT WINAPI
1304 IDirectDraw2Impl_GetAvailableVidMem(IDirectDraw2 *iface,
1305 DDSCAPS *Caps,
1306 DWORD *total,
1307 DWORD *free)
1308 {
1309 IDirectDrawImpl *This = impl_from_dd2(iface);
1310 DDSCAPS2 caps2;
1311 TRACE("(%p)->(%p, %p, %p): Thunking to IDirectDraw4\n", This, Caps, total, free);
1312 memset(&caps2, 0, sizeof(caps2));
1313 caps2.dwCaps = Caps->dwCaps;
1314 return IDirectDraw4_GetAvailableVidMem(dd4_from_impl(This), &caps2, total, free);
1315 }
1316
1317 static HRESULT WINAPI
1318 IDirectDraw4Impl_GetSurfaceFromDC(IDirectDraw4 *iface,
1319 HDC hdc,
1320 IDirectDrawSurface4 **Surface)
1321 {
1322 IDirectDrawImpl *This = impl_from_dd4(iface);
1323 IDirectDrawSurface4 *inner;
1324 HRESULT hr;
1325 TRACE("(%p)->(%p, %p)\n", This, hdc, Surface);
1326 hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, &inner);
1327 if(SUCCEEDED(hr))
1328 {
1329 *Surface = dds_get_outer(inner);
1330 IDirectDrawSurface4_AddRef(*Surface);
1331 IDirectDrawSurface4_Release(inner);
1332 }
1333 else
1334 {
1335 *Surface = NULL;
1336 }
1337
1338 return hr;
1339 }
1340
1341 static HRESULT WINAPI
1342 IDirectDraw3Impl_GetSurfaceFromDC(IDirectDraw3 *iface,
1343 HDC hdc,
1344 IDirectDrawSurface **Surface)
1345 {
1346 IDirectDrawImpl *This = impl_from_dd3(iface);
1347 IDirectDrawSurface4 *surf4;
1348 HRESULT hr;
1349 TRACE("(%p)->(%p, %p): Thunking to IDirectDraw4\n", This, hdc, Surface);
1350
1351 hr = IDirectDraw4_GetSurfaceFromDC(dd4_from_impl(This), hdc, &surf4);
1352 if(FAILED(hr))
1353 {
1354 *Surface = NULL;
1355 return hr;
1356 }
1357 IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surface);
1358 IDirectDrawSurface4_Release(surf4);
1359 return hr;
1360 }
1361
1362 static HRESULT WINAPI
1363 IDirectDraw4Impl_RestoreAllSurfaces(IDirectDraw4 *iface)
1364 {
1365 IDirectDrawImpl *This = impl_from_dd4(iface);
1366 TRACE("(%p)\n", This);
1367 return IDirectDraw4_RestoreAllSurfaces(This->parent);
1368 }
1369
1370 static HRESULT WINAPI
1371 IDirectDraw4Impl_TestCooperativeLevel(IDirectDraw4 *iface)
1372 {
1373 IDirectDrawImpl *This = impl_from_dd4(iface);
1374 TRACE("(%p)\n", This);
1375 return IDirectDraw4_TestCooperativeLevel(This->parent);
1376 }
1377
1378 static HRESULT WINAPI
1379 IDirectDraw4Impl_GetDeviceIdentifier(IDirectDraw4 *iface,
1380 DDDEVICEIDENTIFIER *DDDI,
1381 DWORD Flags)
1382 {
1383 IDirectDrawImpl *This = impl_from_dd4(iface);
1384 TRACE("(%p)->(%p,0x%08x)\n", This, DDDI, Flags);
1385 return IDirectDraw4_GetDeviceIdentifier(This->parent, DDDI, Flags);
1386 }
1387
1388 static const IDirectDrawVtbl IDirectDraw1_Vtbl =
1389 {
1390 IDirectDrawImpl_QueryInterface,
1391 IDirectDrawImpl_AddRef,
1392 IDirectDrawImpl_Release,
1393 IDirectDrawImpl_Compact,
1394 IDirectDrawImpl_CreateClipper,
1395 IDirectDrawImpl_CreatePalette,
1396 IDirectDrawImpl_CreateSurface,
1397 IDirectDrawImpl_DuplicateSurface,
1398 IDirectDrawImpl_EnumDisplayModes,
1399 IDirectDrawImpl_EnumSurfaces,
1400 IDirectDrawImpl_FlipToGDISurface,
1401 IDirectDrawImpl_GetCaps,
1402 IDirectDrawImpl_GetDisplayMode,
1403 IDirectDrawImpl_GetFourCCCodes,
1404 IDirectDrawImpl_GetGDISurface,
1405 IDirectDrawImpl_GetMonitorFrequency,
1406 IDirectDrawImpl_GetScanLine,
1407 IDirectDrawImpl_GetVerticalBlankStatus,
1408 IDirectDrawImpl_Initialize,
1409 IDirectDrawImpl_RestoreDisplayMode,
1410 IDirectDrawImpl_SetCooperativeLevel,
1411 IDirectDrawImpl_SetDisplayMode,
1412 IDirectDrawImpl_WaitForVerticalBlank,
1413 };
1414
1415 static const IDirectDraw2Vtbl IDirectDraw2_Vtbl =
1416 {
1417 IDirectDraw2Impl_QueryInterface,
1418 IDirectDraw2Impl_AddRef,
1419 IDirectDraw2Impl_Release,
1420 IDirectDraw2Impl_Compact,
1421 IDirectDraw2Impl_CreateClipper,
1422 IDirectDraw2Impl_CreatePalette,
1423 IDirectDraw2Impl_CreateSurface,
1424 IDirectDraw2Impl_DuplicateSurface,
1425 IDirectDraw2Impl_EnumDisplayModes,
1426 IDirectDraw2Impl_EnumSurfaces,
1427 IDirectDraw2Impl_FlipToGDISurface,
1428 IDirectDraw2Impl_GetCaps,
1429 IDirectDraw2Impl_GetDisplayMode,
1430 IDirectDraw2Impl_GetFourCCCodes,
1431 IDirectDraw2Impl_GetGDISurface,
1432 IDirectDraw2Impl_GetMonitorFrequency,
1433 IDirectDraw2Impl_GetScanLine,
1434 IDirectDraw2Impl_GetVerticalBlankStatus,
1435 IDirectDraw2Impl_Initialize,
1436 IDirectDraw2Impl_RestoreDisplayMode,
1437 IDirectDraw2Impl_SetCooperativeLevel,
1438 IDirectDraw2Impl_SetDisplayMode,
1439 IDirectDraw2Impl_WaitForVerticalBlank,
1440 IDirectDraw2Impl_GetAvailableVidMem
1441 };
1442
1443 static const IDirectDraw3Vtbl IDirectDraw3_Vtbl =
1444 {
1445 IDirectDraw3Impl_QueryInterface,
1446 IDirectDraw3Impl_AddRef,
1447 IDirectDraw3Impl_Release,
1448 IDirectDraw3Impl_Compact,
1449 IDirectDraw3Impl_CreateClipper,
1450 IDirectDraw3Impl_CreatePalette,
1451 IDirectDraw3Impl_CreateSurface,
1452 IDirectDraw3Impl_DuplicateSurface,
1453 IDirectDraw3Impl_EnumDisplayModes,
1454 IDirectDraw3Impl_EnumSurfaces,
1455 IDirectDraw3Impl_FlipToGDISurface,
1456 IDirectDraw3Impl_GetCaps,
1457 IDirectDraw3Impl_GetDisplayMode,
1458 IDirectDraw3Impl_GetFourCCCodes,
1459 IDirectDraw3Impl_GetGDISurface,
1460 IDirectDraw3Impl_GetMonitorFrequency,
1461 IDirectDraw3Impl_GetScanLine,
1462 IDirectDraw3Impl_GetVerticalBlankStatus,
1463 IDirectDraw3Impl_Initialize,
1464 IDirectDraw3Impl_RestoreDisplayMode,
1465 IDirectDraw3Impl_SetCooperativeLevel,
1466 IDirectDraw3Impl_SetDisplayMode,
1467 IDirectDraw3Impl_WaitForVerticalBlank,
1468 IDirectDraw3Impl_GetAvailableVidMem,
1469 IDirectDraw3Impl_GetSurfaceFromDC,
1470 };
1471
1472 static const IDirectDraw4Vtbl IDirectDraw4_Vtbl =
1473 {
1474 IDirectDraw4Impl_QueryInterface,
1475 IDirectDraw4Impl_AddRef,
1476 IDirectDraw4Impl_Release,
1477 IDirectDraw4Impl_Compact,
1478 IDirectDraw4Impl_CreateClipper,
1479 IDirectDraw4Impl_CreatePalette,
1480 IDirectDraw4Impl_CreateSurface,
1481 IDirectDraw4Impl_DuplicateSurface,
1482 IDirectDraw4Impl_EnumDisplayModes,
1483 IDirectDraw4Impl_EnumSurfaces,
1484 IDirectDraw4Impl_FlipToGDISurface,
1485 IDirectDraw4Impl_GetCaps,
1486 IDirectDraw4Impl_GetDisplayMode,
1487 IDirectDraw4Impl_GetFourCCCodes,
1488 IDirectDraw4Impl_GetGDISurface,
1489 IDirectDraw4Impl_GetMonitorFrequency,
1490 IDirectDraw4Impl_GetScanLine,
1491 IDirectDraw4Impl_GetVerticalBlankStatus,
1492 IDirectDraw4Impl_Initialize,
1493 IDirectDraw4Impl_RestoreDisplayMode,
1494 IDirectDraw4Impl_SetCooperativeLevel,
1495 IDirectDraw4Impl_SetDisplayMode,
1496 IDirectDraw4Impl_WaitForVerticalBlank,
1497 IDirectDraw4Impl_GetAvailableVidMem,
1498 IDirectDraw4Impl_GetSurfaceFromDC,
1499 IDirectDraw4Impl_RestoreAllSurfaces,
1500 IDirectDraw4Impl_TestCooperativeLevel,
1501 IDirectDraw4Impl_GetDeviceIdentifier
1502 };
1503
1504 /*******************************************************************************
1505 * IDirectDrawFactoryImpl_CreateDirectDraw
1506 *******************************************************************************/
1507 HRESULT WINAPI
1508 IDirectDrawFactoryImpl_CreateDirectDraw(IDirectDrawFactory* iface,
1509 GUID * pGUID,
1510 HWND hWnd,
1511 DWORD dwCoopLevelFlags,
1512 DWORD dwReserved,
1513 IUnknown *pUnkOuter,
1514 IDirectDraw **ppDirectDraw)
1515 {
1516 HRESULT hr;
1517 IDirectDrawImpl *object = NULL;
1518 IDirectDraw *parent = NULL;
1519
1520 TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p,%p)\n", iface, debugstr_guid(pGUID), hWnd, dwCoopLevelFlags,
1521 dwReserved, pUnkOuter, ppDirectDraw);
1522
1523 if(pUnkOuter)
1524 {
1525 FIXME("Implement aggregation in ddrawex's IDirectDraw interface\n");
1526 }
1527
1528 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1529 if(!object)
1530 {
1531 ERR("Out of memory\n");
1532 hr = E_OUTOFMEMORY;
1533 goto err;
1534 }
1535 object->ref = 1;
1536 object->IDirectDraw_Vtbl = &IDirectDraw1_Vtbl;
1537 object->IDirectDraw2_Vtbl = &IDirectDraw2_Vtbl;
1538 object->IDirectDraw3_Vtbl = &IDirectDraw3_Vtbl;
1539 object->IDirectDraw4_Vtbl = &IDirectDraw4_Vtbl;
1540
1541 hr = DirectDrawCreate(pGUID, &parent, NULL);
1542 if (FAILED(hr)) goto err;
1543
1544 hr = IDirectDraw_QueryInterface(parent, &IID_IDirectDraw4, (void **) &object->parent);
1545 if(FAILED(hr)) goto err;
1546
1547 hr = IDirectDraw_SetCooperativeLevel(dd1_from_impl(object), hWnd, dwCoopLevelFlags);
1548 if (FAILED(hr)) goto err;
1549
1550 *ppDirectDraw = dd1_from_impl(object);
1551 IDirectDraw_Release(parent);
1552 return DD_OK;
1553
1554 err:
1555 if(object && object->parent) IDirectDraw4_Release(object->parent);
1556 if(parent) IDirectDraw_Release(parent);
1557 HeapFree(GetProcessHeap(), 0, object);
1558 *ppDirectDraw = NULL;
1559 return hr;
1560 }
1561
1562 IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
1563 {
1564 IDirectDrawImpl *This = impl_from_dd4(outer);
1565 return This->parent;
1566 }
1567
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.